diff --git a/Cargo.lock b/Cargo.lock index ce3388b072..d6155bb536 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,11 +12,11 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072" +checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423" dependencies = [ - "gimli 0.22.0", + "gimli 0.23.0", ] [[package]] @@ -25,12 +25,6 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" -[[package]] -name = "adler32" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" - [[package]] name = "aead" version = "0.3.2" @@ -42,9 +36,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7001367fde4c768a19d1029f0a8be5abd9308e1119846d5bd9ad26297b8faf5" +checksum = "dd2bc6d3f370b5666245ff421e231cba4353df936e26986d2918e61a8fd6aef6" dependencies = [ "aes-soft", "aesni", @@ -53,9 +47,9 @@ dependencies = [ [[package]] name = "aes-gcm" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f5007801316299f922a6198d1d09a0bae95786815d066d5880d13f7c45ead1" +checksum = "0301c9e9c443494d970a07885e8cf3e587bae8356a1d5abd0999068413f7205f" dependencies = [ "aead", "aes", @@ -66,30 +60,30 @@ dependencies = [ [[package]] name = "aes-soft" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4925647ee64e5056cf231608957ce7c81e12d6d6e316b9ce1404778cc1d35fa7" +checksum = "63dd91889c49327ad7ef3b500fd1109dbd3c509a03db0d4a9ce413b79f575cb6" dependencies = [ "block-cipher", "byteorder", - "opaque-debug 0.2.3", + "opaque-debug 0.3.0", ] [[package]] name = "aesni" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050d39b0b7688b3a3254394c3e30a9d66c41dcf9b05b0e2dbdc623f6505d264" +checksum = "0a6fe808308bb07d393e2ea47780043ec47683fcf19cf5efc8ca51c50cc8c68a" dependencies = [ "block-cipher", - "opaque-debug 0.2.3", + "opaque-debug 0.3.0", ] [[package]] name = "ahash" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f33b5018f120946c1dcf279194f238a9f146725593ead1c08fa47ff22b0b5d3" +checksum = "29661b60bec623f0586702976ff4d0c9942dcb6723161c2df0eea78455cfedfb" dependencies = [ "const-random", ] @@ -101,10 +95,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217" [[package]] -name = "aho-corasick" -version = "0.7.13" +name = "ahash" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" +checksum = "f6789e291be47ace86a60303502173d84af8327e3627ecf334356ee0f87a164c" + +[[package]] +name = "aho-corasick" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" dependencies = [ "memchr", ] @@ -117,7 +117,7 @@ checksum = "4f823d037a7ec6ea2197046bafd4ae150e6bc36f9ca347404f46a46823fa84f2" dependencies = [ "approx", "num-complex", - "num-traits 0.2.12", + "num-traits 0.2.14", ] [[package]] @@ -140,9 +140,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.32" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" +checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7" [[package]] name = "approx" @@ -150,7 +150,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" dependencies = [ - "num-traits 0.2.12", + "num-traits 0.2.14", ] [[package]] @@ -176,9 +176,9 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "asn1_der" @@ -196,7 +196,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502" dependencies = [ "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] @@ -213,17 +213,11 @@ dependencies = [ "wait-timeout", ] -[[package]] -name = "assert_matches" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5" - [[package]] name = "async-channel" -version = "1.4.2" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21279cfaa4f47df10b1816007e738ca3747ef2ee53ffc51cdbf57a8bb266fee3" +checksum = "59740d83946db6a5af71ae25ddf9562c2b176b2ca42cf99a455f09f4a220d6b9" dependencies = [ "concurrent-queue", "event-listener", @@ -240,39 +234,41 @@ dependencies = [ "concurrent-queue", "fastrand", "futures-lite", - "once_cell", + "once_cell 1.4.1", "vec-arena", ] [[package]] name = "async-global-executor" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fefeb39da249f4c33af940b779a56723ce45809ef5c54dad84bb538d4ffb6d9e" +checksum = "73079b49cd26b8fd5a15f68fc7707fc78698dc2a3d61430f2a7a9430230dfa04" dependencies = [ "async-executor", "async-io", "futures-lite", "num_cpus", - "once_cell", + "once_cell 1.4.1", ] [[package]] name = "async-io" -version = "1.1.5" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e727cebd055ab2861a854f79def078c4b99ea722d54c6800a0e274389882d4c" +checksum = "d54bc4c1c7292475efb2253227dbcfad8fe1ca4c02bc62c510cc2f3da5c4704e" dependencies = [ "concurrent-queue", "fastrand", "futures-lite", + "libc", "log 0.4.11", "nb-connect", - "once_cell", + "once_cell 1.4.1", "parking", "polling", "vec-arena", "waker-fn", + "winapi 0.3.9", ] [[package]] @@ -286,15 +282,15 @@ dependencies = [ [[package]] name = "async-std" -version = "1.6.5" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9fa76751505e8df1c7a77762f60486f60c71bbd9b8557f4da6ad47d083732ed" +checksum = "a7e82538bc65a25dbdff70e4c5439d52f068048ab97cdea0acd73f131594caa1" dependencies = [ "async-global-executor", "async-io", "async-mutex", "blocking", - "crossbeam-utils", + "crossbeam-utils 0.8.0", "futures-channel", "futures-core", "futures-io", @@ -304,7 +300,7 @@ dependencies = [ "log 0.4.11", "memchr", "num_cpus", - "once_cell", + "once_cell 1.4.1", "pin-project-lite", "pin-utils", "slab", @@ -313,20 +309,41 @@ dependencies = [ [[package]] name = "async-task" -version = "4.0.2" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ab27c1aa62945039e44edaeee1dc23c74cc0c303dd5fe0fb462a184f1c3a518" +checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" [[package]] name = "async-tls" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df097e3f506bec0e1a24f06bb3c962c228f36671de841ff579cb99f371772634" +checksum = "d85a97c4a0ecce878efd3f945f119c78a646d8975340bca0398f9bb05c30cc52" dependencies = [ - "futures 0.3.5", + "futures-core", + "futures-io", "rustls", "webpki", - "webpki-roots 0.19.0", + "webpki-roots", +] + +[[package]] +name = "async-trait" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b246867b8b3b6ae56035f1eb1ed557c1d8eae97f0d53696138a50fa0e3a3b8c0" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn 1.0.48", +] + +[[package]] +name = "atomic" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3410529e8288c463bedb5930f82833bc0c90e5d2fe639a56582a4d09220b281" +dependencies = [ + "autocfg 1.0.1", ] [[package]] @@ -360,15 +377,15 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "backtrace" -version = "0.3.51" +version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec1931848a574faa8f7c71a12ea00453ff5effbb5f51afe7f77d7a48cace6ac1" +checksum = "2baad346b2d4e94a24347adeee9c7a93f412ee94b9cc26e5b59dea23848e9f28" dependencies = [ "addr2line", - "cfg-if", + "cfg-if 1.0.0", "libc", "miniz_oxide", - "object 0.20.0", + "object 0.22.0", "rustc-demangle", ] @@ -384,6 +401,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + [[package]] name = "bincode" version = "1.3.1" @@ -402,7 +425,7 @@ checksum = "66c0bb6167449588ff70803f4127f0684f9063097eca5016f37eb52b92c2cf36" dependencies = [ "bitflags", "cexpr", - "cfg-if", + "cfg-if 0.1.10", "clang-sys", "clap", "env_logger", @@ -410,7 +433,7 @@ dependencies = [ "lazycell", "log 0.4.11", "peeking_take_while", - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", "regex", "rustc-hash", @@ -418,18 +441,27 @@ dependencies = [ "which", ] +[[package]] +name = "bip39" +version = "0.6.0-beta.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059804e226b3ac116519a252d7f5fb985a5ccc0e93255e036a5f7e7283323f4" +dependencies = [ + "failure", + "hashbrown 0.1.8", + "hmac", + "once_cell 0.1.8", + "pbkdf2", + "rand 0.6.5", + "sha2 0.8.2", +] + [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -[[package]] -name = "bitmask" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead" - [[package]] name = "bitvec" version = "0.17.4" @@ -442,15 +474,13 @@ dependencies = [ [[package]] name = "blake2" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84ce5b6108f8e154604bd4eb76a2f726066c3464d5a552a4229262a18c9bb471" +checksum = "10a5720225ef5daecf08657f23791354e1685a8c91a4c60c7f3d3b2892f978f4" dependencies = [ - "byte-tools", - "byteorder", "crypto-mac 0.8.0", "digest 0.9.0", - "opaque-debug 0.2.3", + "opaque-debug 0.3.0", ] [[package]] @@ -465,23 +495,23 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" dependencies = [ "arrayref", - "arrayvec 0.5.1", + "arrayvec 0.5.2", "constant_time_eq", ] [[package]] name = "blake2s_simd" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab9e07352b829279624ceb7c64adb4f585dacdb81d35cafae81139ccd617cf44" +checksum = "9e461a7034e85b211a4acb57ee2e6730b32912b06c08cc242243c39fc21ae6a2" dependencies = [ "arrayref", - "arrayvec 0.5.1", + "arrayvec 0.5.2", "constant_time_eq", ] @@ -509,9 +539,9 @@ dependencies = [ [[package]] name = "block-cipher" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa136449e765dc7faa244561ccae839c394048667929af599b5d931ebe7b7f10" +checksum = "f337a3e6da609650eb74e02bc9fac7b735049f7623ab12f2e4c719316fcc7e80" dependencies = [ "generic-array 0.14.4", ] @@ -533,16 +563,16 @@ checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" [[package]] name = "blocking" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2640778f8053e72c11f621b0a5175a0560a269282aa98ed85107773ab8e2a556" +checksum = "c5e170dbede1f740736619b776d7251cb1b9095c435c34d8ca9f57fcd2f335e9" dependencies = [ "async-channel", + "async-task", "atomic-waker", "fastrand", "futures-lite", - "once_cell", - "waker-fn", + "once_cell 1.4.1", ] [[package]] @@ -553,9 +583,9 @@ checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb" [[package]] name = "bstr" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31accafdb70df7871592c058eca3985b71104e15ac32f64706022c58867da931" +checksum = "473fc6b38233f9af7baa94fb5852dca389e3d95b8e21c8e3719301462c5d9faf" dependencies = [ "memchr", ] @@ -601,12 +631,6 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" -[[package]] -name = "c_linked_list" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" - [[package]] name = "cache-padded" version = "1.1.1" @@ -615,9 +639,9 @@ checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" [[package]] name = "cc" -version = "1.0.60" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef611cc68ff783f18535d77ddd080185275713d852c4f5cbb6122c462a7a825c" +checksum = "ed67cbde08356238e75fc4656be4749481eeffb09e19f320a25237d5221c985d" dependencies = [ "jobserver", ] @@ -638,10 +662,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] -name = "chacha20" -version = "0.4.3" +name = "cfg-if" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "086c0f07ac275808b7bf9a39f2fd013aae1498be83632814c8c4e0bd53f2dc58" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chacha20" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "244fbce0d47e97e8ef2f63b81d5e05882cb518c68531eb33194990d7b7e85845" dependencies = [ "stream-cipher", "zeroize", @@ -649,9 +679,9 @@ dependencies = [ [[package]] name = "chacha20poly1305" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18b0c90556d8e3fec7cf18d84a2f53d27b21288f2fe481b830fadcf809e48205" +checksum = "9bf18d374d66df0c05cdddd528a7db98f78c28e2519b120855c4f84c5027b1f5" dependencies = [ "aead", "chacha20", @@ -662,13 +692,13 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.18" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d021fddb7bd3e734370acfa4a83f34095571d8570c039f1420d77540f68d5772" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" dependencies = [ "libc", "num-integer", - "num-traits 0.2.12", + "num-traits 0.2.14", "time", "winapi 0.3.9", ] @@ -679,7 +709,7 @@ version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe6837df1d5cba2397b835c8530f51723267e16abbf83892e9e5af4f0e5dd10a" dependencies = [ - "glob 0.3.0", + "glob", "libc", "libloading", ] @@ -717,15 +747,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "cmake" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e56268c17a6248366d66d4a47a3381369d068cce8409bb1716ed77ea32163bb" -dependencies = [ - "cc", -] - [[package]] name = "concurrent-queue" version = "1.2.2" @@ -737,9 +758,9 @@ dependencies = [ [[package]] name = "const-random" -version = "0.1.8" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f1af9ac737b2dd2d577701e59fd09ba34822f6f2ebdb30a7647405d9e55e16a" +checksum = "02dc82c12dc2ee6e1ded861cf7d582b46f66f796d1b6c93fa28b911ead95da02" dependencies = [ "const-random-macro", "proc-macro-hack", @@ -747,14 +768,20 @@ dependencies = [ [[package]] name = "const-random-macro" -version = "0.1.8" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e4c606eb459dd29f7c57b2e0879f2b6f14ee130918c2b78ccb58a9624e6c7a" +checksum = "fc757bbb9544aa296c2ae00c679e81f886b37e28e59097defe0cf524306f6685" dependencies = [ - "getrandom", + "getrandom 0.2.0", "proc-macro-hack", ] +[[package]] +name = "const_fn" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c478836e029dcef17fb47c89023448c64f781a046e0300e257ad8225ae59afab" + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -877,21 +904,21 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" +checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] name = "crossbeam-channel" -version = "0.4.4" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" +checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" dependencies = [ - "crossbeam-utils", - "maybe-uninit", + "cfg-if 1.0.0", + "crossbeam-utils 0.8.0", ] [[package]] @@ -900,11 +927,22 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", + "crossbeam-epoch 0.8.2", + "crossbeam-utils 0.7.2", "maybe-uninit", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch 0.9.0", + "crossbeam-utils 0.8.0", +] + [[package]] name = "crossbeam-epoch" version = "0.8.2" @@ -912,22 +950,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" dependencies = [ "autocfg 1.0.1", - "cfg-if", - "crossbeam-utils", + "cfg-if 0.1.10", + "crossbeam-utils 0.7.2", "lazy_static", "maybe-uninit", "memoffset", "scopeguard 1.1.0", ] +[[package]] +name = "crossbeam-epoch" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0f606a85340376eef0d6d8fec399e6d4a544d648386c6645eb6d0653b27d9f" +dependencies = [ + "cfg-if 1.0.0", + "const_fn", + "crossbeam-utils 0.8.0", + "lazy_static", + "memoffset", + "scopeguard 1.1.0", +] + [[package]] name = "crossbeam-queue" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" dependencies = [ - "cfg-if", - "crossbeam-utils", + "cfg-if 0.1.10", + "crossbeam-utils 0.7.2", "maybe-uninit", ] @@ -938,7 +990,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" dependencies = [ "autocfg 1.0.1", - "cfg-if", + "cfg-if 0.1.10", + "lazy_static", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5" +dependencies = [ + "autocfg 1.0.1", + "cfg-if 1.0.0", + "const_fn", "lazy_static", ] @@ -977,6 +1041,17 @@ dependencies = [ "sct", ] +[[package]] +name = "cuckoofilter" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b810a8449931679f64cd7eef1bbd0fa315801b6d5d9cdc1ace2804d6529eee18" +dependencies = [ + "byteorder", + "fnv", + "rand 0.7.3", +] + [[package]] name = "cumulus-collator" version = "0.1.0" @@ -988,15 +1063,19 @@ dependencies = [ "cumulus-test-client", "cumulus-test-runtime", "env_logger", - "futures 0.3.5", + "futures 0.3.7", "log 0.4.11", "parity-scale-codec", "parking_lot 0.9.0", - "polkadot-collator", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-test-helpers", + "polkadot-overseer", "polkadot-parachain", "polkadot-primitives", "polkadot-service", "polkadot-validation", + "sc-block-builder", "sc-cli", "sc-client-api", "sp-api", @@ -1004,6 +1083,7 @@ dependencies = [ "sp-consensus", "sp-core", "sp-inherents", + "sp-io", "sp-keyring", "sp-runtime", "sp-state-machine", @@ -1014,7 +1094,7 @@ dependencies = [ name = "cumulus-consensus" version = "0.1.0" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", "log 0.4.11", "parity-scale-codec", "polkadot-primitives", @@ -1031,76 +1111,22 @@ dependencies = [ "tokio 0.1.22", ] -[[package]] -name = "cumulus-contracts-parachain-runtime" -version = "0.1.0" -dependencies = [ - "cumulus-message-broker", - "cumulus-pallet-contracts", - "cumulus-pallet-contracts-primitives", - "cumulus-pallet-contracts-rpc-runtime-api", - "cumulus-parachain-upgrade", - "cumulus-primitives", - "cumulus-runtime", - "cumulus-token-dealer", - "cumulus-upward-message", - "frame-executive", - "frame-support", - "frame-system", - "pallet-balances", - "pallet-randomness-collective-flip", - "pallet-sudo", - "pallet-timestamp", - "pallet-transaction-payment", - "parachain-info", - "parity-scale-codec", - "polkadot-parachain", - "rococo-parachain-primitives", - "serde", - "sp-api", - "sp-block-builder", - "sp-core", - "sp-inherents", - "sp-io", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-std", - "sp-transaction-pool", - "sp-version", - "substrate-wasm-builder-runner 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cumulus-message-broker" -version = "0.1.0" -dependencies = [ - "cumulus-primitives", - "cumulus-upward-message", - "frame-support", - "frame-system", - "parity-scale-codec", - "sp-inherents", - "sp-io", - "sp-runtime", - "sp-std", -] - [[package]] name = "cumulus-network" version = "0.1.0" dependencies = [ "cumulus-primitives", "cumulus-test-runtime", - "futures 0.3.5", + "futures 0.3.7", "log 0.4.11", "parity-scale-codec", "parking_lot 0.10.2", - "polkadot-collator", - "polkadot-network", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-overseer", "polkadot-primitives", + "polkadot-service", "polkadot-statement-table", - "polkadot-test-runtime-client", "polkadot-validation", "sc-client-api", "sp-api", @@ -1108,73 +1134,10 @@ dependencies = [ "sp-consensus", "sp-core", "sp-keyring", + "sp-keystore", "sp-runtime", ] -[[package]] -name = "cumulus-pallet-contracts" -version = "2.0.0-rc3" -dependencies = [ - "assert_matches", - "cumulus-pallet-contracts-primitives", - "frame-support", - "frame-system", - "hex-literal", - "pallet-balances", - "pallet-randomness-collective-flip", - "pallet-timestamp", - "parity-scale-codec", - "parity-wasm", - "pwasm-utils", - "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-sandbox", - "sp-std", - "wabt", - "wasmi-validation", -] - -[[package]] -name = "cumulus-pallet-contracts-primitives" -version = "2.0.0-rc3" -dependencies = [ - "parity-scale-codec", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "cumulus-pallet-contracts-rpc" -version = "0.8.0-rc3" -dependencies = [ - "cumulus-pallet-contracts-primitives", - "cumulus-pallet-contracts-rpc-runtime-api", - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", - "parity-scale-codec", - "serde", - "serde_json", - "sp-api", - "sp-blockchain", - "sp-core", - "sp-rpc", - "sp-runtime", -] - -[[package]] -name = "cumulus-pallet-contracts-rpc-runtime-api" -version = "0.8.0-rc3" -dependencies = [ - "cumulus-pallet-contracts-primitives", - "parity-scale-codec", - "sp-api", - "sp-runtime", - "sp-std", -] - [[package]] name = "cumulus-parachain-upgrade" version = "0.1.0" @@ -1206,7 +1169,7 @@ dependencies = [ "polkadot-core-primitives", "polkadot-parachain", "polkadot-primitives", - "sc-service", + "sc-chain-spec", "sp-inherents", "sp-runtime", "sp-std", @@ -1218,6 +1181,7 @@ version = "0.1.0" dependencies = [ "cumulus-primitives", "cumulus-test-client", + "env_logger", "frame-executive", "hash-db", "memory-db", @@ -1233,7 +1197,6 @@ dependencies = [ "sp-keyring", "sp-runtime", "sp-std", - "sp-timestamp", "sp-trie", "trie-db", ] @@ -1244,9 +1207,9 @@ version = "0.1.0" dependencies = [ "cumulus-collator", "cumulus-consensus", - "cumulus-network", "cumulus-primitives", - "polkadot-collator", + "futures 0.3.7", + "polkadot-overseer", "polkadot-primitives", "polkadot-service", "sc-client-api", @@ -1270,14 +1233,14 @@ dependencies = [ "pallet-balances", "pallet-transaction-payment", "parity-scale-codec", + "polkadot-primitives", "sc-block-builder", - "sc-client-api", "sc-consensus", "sc-service", "sp-api", "sp-blockchain", - "sp-consensus", "sp-core", + "sp-inherents", "sp-keyring", "sp-runtime", "sp-test-primitives", @@ -1289,12 +1252,9 @@ dependencies = [ name = "cumulus-test-parachain-runtime" version = "0.1.0" dependencies = [ - "cumulus-message-broker", "cumulus-parachain-upgrade", "cumulus-primitives", "cumulus-runtime", - "cumulus-token-dealer", - "cumulus-upward-message", "frame-executive", "frame-support", "frame-system", @@ -1319,7 +1279,7 @@ dependencies = [ "sp-std", "sp-transaction-pool", "sp-version", - "substrate-wasm-builder-runner 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-wasm-builder-runner 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1329,7 +1289,6 @@ dependencies = [ "cumulus-parachain-upgrade", "cumulus-primitives", "cumulus-runtime", - "cumulus-upward-message", "frame-executive", "frame-support", "frame-system", @@ -1352,35 +1311,34 @@ dependencies = [ "sp-std", "sp-transaction-pool", "sp-version", - "substrate-wasm-builder-runner 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-wasm-builder-runner 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cumulus-test-service" version = "0.1.0" dependencies = [ - "ansi_term 0.12.1", - "cumulus-collator", "cumulus-consensus", "cumulus-network", "cumulus-primitives", "cumulus-service", "cumulus-test-runtime", - "futures 0.3.5", + "futures 0.3.7", "jsonrpc-core", "pallet-sudo", "parity-scale-codec", - "polkadot-collator", + "polkadot-overseer", "polkadot-primitives", + "polkadot-service", "polkadot-test-runtime", "polkadot-test-service", "rand 0.7.3", "sc-basic-authorship", "sc-block-builder", "sc-chain-spec", + "sc-cli", "sc-client-api", "sc-executor", - "sc-informant", "sc-network", "sc-rpc", "sc-service", @@ -1405,31 +1363,6 @@ dependencies = [ "tokio 0.2.22", ] -[[package]] -name = "cumulus-token-dealer" -version = "0.1.0" -dependencies = [ - "cumulus-primitives", - "cumulus-upward-message", - "frame-support", - "frame-system", - "parity-scale-codec", - "polkadot-parachain", -] - -[[package]] -name = "cumulus-upward-message" -version = "0.1.0" -dependencies = [ - "kusama-runtime", - "polkadot-core-primitives", - "polkadot-parachain", - "polkadot-runtime", - "rococo-runtime", - "sp-std", - "westend-runtime", -] - [[package]] name = "curve25519-dalek" version = "2.1.0" @@ -1458,21 +1391,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d0e2d24e5ee3b23a01de38eefdcd978907890701f08ffffd4cb457ca4ee8d6" - -[[package]] -name = "derive_more" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d944ac6003ed268757ef1ee686753b57efc5fcf0ebe7b64c9fc81e7e32ff839" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "rustc_version", - "syn 0.15.44", -] +checksum = "993a608597367c6377b258c25d7120740f00ed23a2252b729b1932dd7866f908" [[package]] name = "derive_more" @@ -1490,13 +1411,13 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.10" +version = "0.99.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dcfabdab475c16a93d669dddfc393027803e347d09663f524447f642fbb84ba" +checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] @@ -1529,7 +1450,7 @@ version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "dirs-sys", ] @@ -1551,7 +1472,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" dependencies = [ "byteorder", - "quick-error", + "quick-error 1.2.3", ] [[package]] @@ -1576,22 +1497,22 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] name = "dyn-clone" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c53dc3a653e0f64081026e4bf048d48fec9fce90c66e8326ca7292df0ff2d82" +checksum = "d55796afa1b20c2945ca8eabfc421839f2b766619209f1ede813cf2484f31804" [[package]] name = "ed25519" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07dfc993ea376e864fe29a4099a61ca0bb994c6d7745a61bf60ddb3d64e05237" +checksum = "37c66a534cbb46ab4ea03477eae19d5c22c01da8258030280b7bd9d8433fb6ef" dependencies = [ "signature", ] @@ -1606,7 +1527,7 @@ dependencies = [ "ed25519", "rand 0.7.3", "serde", - "sha2 0.9.1", + "sha2 0.9.2", "zeroize", ] @@ -1616,17 +1537,6 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" -[[package]] -name = "enum-primitive-derive" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b90e520ec62c1864c8c78d637acbfe8baf5f63240f2fb8165b8325c07812dd" -dependencies = [ - "num-traits 0.1.43", - "quote 0.3.15", - "syn 0.11.11", -] - [[package]] name = "enum_primitive" version = "0.1.1" @@ -1651,9 +1561,9 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] @@ -1686,9 +1596,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eab5ee3df98a279d9b316b1af6ac95422127b1290317e6d18c1743c99418b01" +checksum = "fa68f2fb9cae9d37c9b2b3584aba698a2e97f72d7aef7b9f7aa71d8b54ce46fe" dependencies = [ "errno-dragonfly", "libc", @@ -1729,7 +1639,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8013f441e38e31c670e7f34ec8f1d5d3a2bd9d303c1ff83976ca886005e8f48" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", "parking_lot 0.7.1", ] @@ -1739,7 +1649,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", ] [[package]] @@ -1758,9 +1668,9 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", "synstructure", ] @@ -1778,15 +1688,18 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "1.3.5" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c85295147490b8fcf2ea3d104080a105a8b2c63f9c319e82c02d8e952388919" +checksum = "ca5faf057445ce5c9d4329e382b2ce7ca38550ef3b73a5348362d5f24e0c7fe3" +dependencies = [ + "instant", +] [[package]] name = "fdlimit" -version = "0.1.4" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0da54a593b34c71b889ee45f5b5bb900c74148c5f7f8c6a9479ee7899f69603c" +checksum = "2c4c9e43643f5a3be4ca5b67d26b98031ff9db6806c3440ae32e02e3ceac3f1b" dependencies = [ "libc", ] @@ -1808,10 +1721,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8feb87a63249689640ac9c011742c33139204e3c134293d3054022276869133b" dependencies = [ "either", - "futures 0.3.5", + "futures 0.3.7", "futures-timer 2.0.2", "log 0.4.11", - "num-traits 0.2.12", + "num-traits 0.2.14", "parity-scale-codec", "parking_lot 0.9.0", ] @@ -1836,11 +1749,11 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" [[package]] name = "flate2" -version = "1.0.17" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "766d0e77a2c1502169d4a93ff3b8c15a71fd946cd0126309752104e5f3c46d94" +checksum = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crc32fast", "libc", "libz-sys", @@ -1855,16 +1768,16 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fork-tree" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "parity-scale-codec", ] [[package]] name = "frame-benchmarking" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -1876,21 +1789,26 @@ dependencies = [ "sp-runtime", "sp-runtime-interface", "sp-std", + "sp-storage", ] [[package]] name = "frame-benchmarking-cli" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ + "chrono", "frame-benchmarking", + "handlebars", "parity-scale-codec", "sc-cli", "sc-client-db", "sc-executor", "sc-service", + "serde", "sp-core", "sp-externalities", + "sp-keystore", "sp-runtime", "sp-state-machine", "structopt", @@ -1898,13 +1816,14 @@ dependencies = [ [[package]] name = "frame-executive" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", "parity-scale-codec", "serde", + "sp-core", "sp-io", "sp-runtime", "sp-std", @@ -1913,8 +1832,8 @@ dependencies = [ [[package]] name = "frame-metadata" -version = "11.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "12.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "parity-scale-codec", "serde", @@ -1924,15 +1843,15 @@ dependencies = [ [[package]] name = "frame-support" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "bitmask", + "bitflags", "frame-metadata", "frame-support-procedural", "impl-trait-for-tuples", "log 0.4.11", - "once_cell", + "once_cell 1.4.1", "parity-scale-codec", "paste", "serde", @@ -1949,41 +1868,41 @@ dependencies = [ [[package]] name = "frame-support-procedural" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support-procedural-tools", - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] name = "frame-support-procedural-tools" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] name = "frame-support-procedural-tools-derive" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] name = "frame-system" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -1998,8 +1917,8 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "parity-scale-codec", "sp-api", @@ -2041,15 +1960,15 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] name = "futures" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" +checksum = "4c7e4c2612746b0df8fed4ce0c69156021b704c9aefa360311c04e6e9e002eed" [[package]] name = "futures" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613" +checksum = "95314d38584ffbfda215621d723e0a3906f032e03ae5551e650058dac83d4797" dependencies = [ "futures-channel", "futures-core", @@ -2062,9 +1981,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5" +checksum = "0448174b01148032eed37ac4aed28963aaaa8cfa93569a08e5b479bbc6c2c151" dependencies = [ "futures-core", "futures-sink", @@ -2081,9 +2000,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" +checksum = "18eaa56102984bed2c88ea39026cff3ce3b4c7f508ca970cedf2450ea10d4e46" [[package]] name = "futures-core-preview" @@ -2097,7 +2016,7 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", "num_cpus", ] @@ -2107,21 +2026,21 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdcef58a173af8148b182684c9f2d5250875adbcaff7b5794073894f9d8634a9" dependencies = [ - "futures 0.1.29", - "futures 0.3.5", + "futures 0.1.30", + "futures 0.3.7", "lazy_static", "log 0.4.11", "parking_lot 0.9.0", - "pin-project", + "pin-project 0.4.27", "serde", "serde_json", ] [[package]] name = "futures-executor" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314" +checksum = "f5f8e0c9258abaea85e78ebdda17ef9666d390e987f006be6080dfe354b708cb" dependencies = [ "futures-core", "futures-task", @@ -2131,15 +2050,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789" +checksum = "6e1798854a4727ff944a7b12aa999f58ce7aa81db80d2dfaaf2ba06f065ddd2b" [[package]] name = "futures-lite" -version = "1.8.0" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0db18c5f58083b54b0c416638ea73066722c2815c1e54dd8ba85ee3def593c3a" +checksum = "5e6c079abfac3ab269e2927ec048dabc89d009ebfdda6b8ee86624f30c689658" dependencies = [ "fastrand", "futures-core", @@ -2152,29 +2071,29 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" +checksum = "e36fccf3fc58563b4a14d265027c627c3b665d7fed489427e88e7cc929559efe" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] name = "futures-sink" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc" +checksum = "0e3ca3f17d6e8804ae5d3df7a7d35b2b3a6fe89dac84b31872720fc3060a0b11" [[package]] name = "futures-task" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626" +checksum = "96d502af37186c4fef99453df03e374683f8a1eec9dcc1e66b3b82dc8278ce3c" dependencies = [ - "once_cell", + "once_cell 1.4.1", ] [[package]] @@ -2191,11 +2110,11 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6" +checksum = "abcb44342f62e6f3e8ac427b8aa815f724fd705dfad060b18ac7866c15bb8e34" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", "futures-channel", "futures-core", "futures-io", @@ -2203,7 +2122,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project", + "pin-project 1.0.1", "pin-utils", "proc-macro-hack", "proc-macro-nested", @@ -2229,9 +2148,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce54d63f8b0c75023ed920d46fd71d0cbbb830b0ee012726b5b4f506fb6dea5b" dependencies = [ "bytes 0.5.6", - "futures 0.3.5", + "futures 0.3.7", "memchr", - "pin-project", + "pin-project 0.4.27", ] [[package]] @@ -2240,6 +2159,19 @@ version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" +[[package]] +name = "generator" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cdc09201b2e8ca1b19290cf7e65de2246b8e91fb6874279722189c4de7b94dc" +dependencies = [ + "cc", + "libc", + "log 0.4.11", + "rustc_version", + "winapi 0.3.9", +] + [[package]] name = "generic-array" version = "0.12.3" @@ -2259,35 +2191,24 @@ dependencies = [ "version_check", ] -[[package]] -name = "get_if_addrs" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7" -dependencies = [ - "c_linked_list", - "get_if_addrs-sys", - "libc", - "winapi 0.2.8", -] - -[[package]] -name = "get_if_addrs-sys" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48" -dependencies = [ - "gcc", - "libc", -] - [[package]] name = "getrandom" version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4" +dependencies = [ + "cfg-if 0.1.10", "libc", "wasi 0.9.0+wasi-snapshot-preview1", ] @@ -2314,15 +2235,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.22.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724" - -[[package]] -name = "glob" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" +checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" [[package]] name = "glob" @@ -2332,9 +2247,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "globset" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ad1da430bd7281dde2576f44c84cc3f0f7b475e7202cd503042dff01a8c8120" +checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a" dependencies = [ "aho-corasick", "bstr", @@ -2365,7 +2280,7 @@ dependencies = [ "byteorder", "bytes 0.4.12", "fnv", - "futures 0.1.29", + "futures 0.1.30", "http 0.1.21", "indexmap", "log 0.4.11", @@ -2376,9 +2291,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993f9e0baeed60001cf565546b0d3dbe6a6ad23f2bd31644a133c641eccf6d53" +checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" dependencies = [ "bytes 0.5.6", "fnv", @@ -2391,6 +2306,21 @@ dependencies = [ "tokio 0.2.22", "tokio-util", "tracing", + "tracing-futures", +] + +[[package]] +name = "handlebars" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2764f9796c0ddca4b82c07f25dd2cb3db30b9a8f47940e78e1c883d9e95c3db9" +dependencies = [ + "log 0.4.11", + "pest", + "pest_derive", + "quick-error 2.0.0", + "serde", + "serde_json", ] [[package]] @@ -2408,13 +2338,23 @@ dependencies = [ "crunchy", ] +[[package]] +name = "hashbrown" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" +dependencies = [ + "byteorder", + "scopeguard 0.3.3", +] + [[package]] name = "hashbrown" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead" dependencies = [ - "ahash 0.2.18", + "ahash 0.2.19", "autocfg 0.1.7", ] @@ -2433,6 +2373,9 @@ name = "hashbrown" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +dependencies = [ + "ahash 0.4.6", +] [[package]] name = "heck" @@ -2445,9 +2388,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c30f6d0bc6b00693347368a67d41b58f2fb851215ff1da49e90fe2c5c667151" +checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" dependencies = [ "libc", ] @@ -2468,6 +2411,12 @@ dependencies = [ "proc-macro-hack", ] +[[package]] +name = "hex-literal" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8" + [[package]] name = "hex-literal-impl" version = "0.2.2" @@ -2477,6 +2426,12 @@ dependencies = [ "proc-macro-hack", ] +[[package]] +name = "hex_fmt" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" + [[package]] name = "hmac" version = "0.7.1" @@ -2527,7 +2482,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "http 0.1.21", "tokio-buf", ] @@ -2560,7 +2515,7 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" dependencies = [ - "quick-error", + "quick-error 1.2.3", ] [[package]] @@ -2570,7 +2525,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "futures-cpupool", "h2 0.1.26", "http 0.1.21", @@ -2595,21 +2550,21 @@ dependencies = [ [[package]] name = "hyper" -version = "0.13.8" +version = "0.13.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f3afcfae8af5ad0576a31e768415edb627824129e8e5a29b8bfccb2f234e835" +checksum = "f6ad767baac13b44d4529fcf58ba2cd0995e36e7b435bc5b039de6f47e880dbf" dependencies = [ "bytes 0.5.6", "futures-channel", "futures-core", "futures-util", - "h2 0.2.6", + "h2 0.2.7", "http 0.2.1", "http-body 0.3.1", "httparse", "httpdate", "itoa", - "pin-project", + "pin-project 1.0.1", "socket2", "tokio 0.2.22", "tower-service", @@ -2626,7 +2581,7 @@ dependencies = [ "bytes 0.5.6", "ct-logs", "futures-util", - "hyper 0.13.8", + "hyper 0.13.9", "log 0.4.11", "rustls", "rustls-native-certs", @@ -2657,6 +2612,27 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "if-addrs" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28538916eb3f3976311f5dfbe67b5362d0add1293d0a9cad17debf86f8e3aa48" +dependencies = [ + "if-addrs-sys", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "if-addrs-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de74b9dd780476e837e5eb5ab7c88b49ed304126e412030a0adba99c8efe79ea" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "impl-codec" version = "0.4.2" @@ -2666,15 +2642,6 @@ dependencies = [ "parity-scale-codec", ] -[[package]] -name = "impl-serde" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58e3cae7e99c7ff5a995da2cf78dd0a5383740eda71d98cf7b1910c301ac69b8" -dependencies = [ - "serde", -] - [[package]] name = "impl-serde" version = "0.3.1" @@ -2690,9 +2657,9 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] @@ -2708,11 +2675,11 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63312a18f7ea8760cdd0a7c5aac1a619752a246b833545e3e36d1f81f7cd9e66" +checksum = "cb1fc4429a33e1f80d41dc9fea4d108a88bec1de8053878898ae448a0b52f613" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -2721,7 +2688,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" dependencies = [ - "num-traits 0.2.12", + "num-traits 0.2.14", ] [[package]] @@ -2730,7 +2697,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64fa110ec7b8f493f416eed552740d10e7030ad5f63b2308f82c9608ec2df275" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", "futures-timer 2.0.2", ] @@ -2799,12 +2766,12 @@ dependencies = [ [[package]] name = "jsonrpc-client-transports" -version = "14.2.1" +version = "15.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2773fa94a2a1fd51efb89a8f45b8861023dbb415d18d3c9235ae9388d780f9ec" +checksum = "489b9c612e60c766f751ab40fcb43cbb55a1e10bb44a9b4307ed510ca598cbd7" dependencies = [ "failure", - "futures 0.1.29", + "futures 0.1.30", "jsonrpc-core", "jsonrpc-pubsub", "log 0.4.11", @@ -2815,11 +2782,11 @@ dependencies = [ [[package]] name = "jsonrpc-core" -version = "14.2.0" +version = "15.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0747307121ffb9703afd93afbd0fb4f854c38fb873f2c8b90e0e902f27c7b62" +checksum = "0745a6379e3edc893c84ec203589790774e4247420033e71a76d3ab4687991fa" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", "log 0.4.11", "serde", "serde_derive", @@ -2828,30 +2795,30 @@ dependencies = [ [[package]] name = "jsonrpc-core-client" -version = "14.2.0" +version = "15.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34221123bc79b66279a3fde2d3363553835b43092d629b34f2e760c44dc94713" +checksum = "6f764902d7b891344a0acb65625f32f6f7c6db006952143bd650209fbe7d94db" dependencies = [ "jsonrpc-client-transports", ] [[package]] name = "jsonrpc-derive" -version = "14.2.2" +version = "15.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0e77e8812f02155b85a677a96e1d16b60181950c0636199bc4528524fba98dc" +checksum = "99a847f9ec7bb52149b2786a17c9cb260d6effc6b8eeb8c16b343a487a7563a3" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] name = "jsonrpc-http-server" -version = "14.2.0" +version = "15.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0da906d682799df05754480dac1b9e70ec92e12c19ebafd2662a5ea1c9fd6522" +checksum = "4fb5c4513b7b542f42da107942b7b759f27120b5cc894729f88254b28dff44b7" dependencies = [ "hyper 0.12.35", "jsonrpc-core", @@ -2864,9 +2831,9 @@ dependencies = [ [[package]] name = "jsonrpc-ipc-server" -version = "14.2.0" +version = "15.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dedccd693325d833963b549e959137f30a7a0ea650cde92feda81dc0c1393cb5" +checksum = "cf50e53e4eea8f421a7316c5f63e395f7bc7c4e786a6dc54d76fab6ff7aa7ce7" dependencies = [ "jsonrpc-core", "jsonrpc-server-utils", @@ -2878,9 +2845,9 @@ dependencies = [ [[package]] name = "jsonrpc-pubsub" -version = "14.2.0" +version = "15.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d44f5602a11d657946aac09357956d2841299ed422035edf140c552cb057986" +checksum = "639558e0604013be9787ae52f798506ae42bf4220fe587bdc5625871cc8b9c77" dependencies = [ "jsonrpc-core", "log 0.4.11", @@ -2891,9 +2858,9 @@ dependencies = [ [[package]] name = "jsonrpc-server-utils" -version = "14.2.0" +version = "15.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56cbfb462e7f902e21121d9f0d1c2b77b2c5b642e1a4e8f4ebfa2e15b94402bb" +checksum = "72f1f3990650c033bd8f6bd46deac76d990f9bbfb5f8dc8c4767bf0a00392176" dependencies = [ "bytes 0.4.12", "globset", @@ -2907,16 +2874,16 @@ dependencies = [ [[package]] name = "jsonrpc-ws-server" -version = "14.2.0" +version = "15.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "903d3109fe7c4acb932b567e1e607e0f524ed04741b09fb0e61841bc40a022fc" +checksum = "6596fe75209b73a2a75ebe1dce4e60e03b88a2b25e8807b667597f6315150d22" dependencies = [ "jsonrpc-core", "jsonrpc-server-utils", "log 0.4.11", + "parity-ws", "parking_lot 0.10.2", "slab", - "ws", ] [[package]] @@ -2937,8 +2904,8 @@ dependencies = [ [[package]] name = "kusama-runtime" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +version = "0.8.26" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ "bitvec", "frame-executive", @@ -2953,7 +2920,6 @@ dependencies = [ "pallet-collective", "pallet-democracy", "pallet-elections-phragmen", - "pallet-finality-tracker", "pallet-grandpa", "pallet-identity", "pallet-im-online", @@ -2998,7 +2964,7 @@ dependencies = [ "sp-transaction-pool", "sp-version", "static_assertions", - "substrate-wasm-builder-runner 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-wasm-builder-runner 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3069,27 +3035,9 @@ checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a" [[package]] name = "libc" -version = "0.2.77" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" - -[[package]] -name = "libflate" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9bac9023e1db29c084f9f8cd9d3852e5e8fddf98fb47c4964a0ea4663d95949" -dependencies = [ - "adler32", - "crc32fast", - "libflate_lz77", - "rle-decode-fast", -] - -[[package]] -name = "libflate_lz77" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3286f09f7d4926fc486334f28d8d2e6ebe4f7f9994494b6dab27ddfad2c9b11b" +checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" [[package]] name = "libloading" @@ -3109,47 +3057,55 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" -version = "0.22.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0306a49ee6a89468f96089906f36b0eef82c988dcfc8acf3e2dcd6ad1c859f85" +checksum = "021f703bfef6e3da78ef9828c8a244d639b8d57eedf58360922aca5ff69dfdcd" dependencies = [ + "atomic", "bytes 0.5.6", - "futures 0.3.5", + "futures 0.3.7", "lazy_static", "libp2p-core", "libp2p-core-derive", + "libp2p-deflate", "libp2p-dns", + "libp2p-floodsub", + "libp2p-gossipsub", "libp2p-identify", "libp2p-kad", "libp2p-mdns", "libp2p-mplex", "libp2p-noise", "libp2p-ping", + "libp2p-plaintext", + "libp2p-pnet", + "libp2p-request-response", "libp2p-swarm", "libp2p-tcp", + "libp2p-uds", "libp2p-wasm-ext", "libp2p-websocket", "libp2p-yamux", "multihash", "parity-multiaddr", - "parking_lot 0.10.2", - "pin-project", + "parking_lot 0.11.0", + "pin-project 1.0.1", "smallvec 1.4.2", "wasm-timer", ] [[package]] name = "libp2p-core" -version = "0.20.1" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a694fd76d7c33a45a0e6e1525e9b9b5d11127c9c94e560ac0f8abba54ed80af" +checksum = "3960524389409633550567e8a9e0684d25a33f4f8408887ff897dd9fdfbdb771" dependencies = [ "asn1_der", "bs58", "ed25519-dalek", "either", "fnv", - "futures 0.3.5", + "futures 0.3.7", "futures-timer 3.0.2", "lazy_static", "libsecp256k1", @@ -3157,17 +3113,17 @@ dependencies = [ "multihash", "multistream-select", "parity-multiaddr", - "parking_lot 0.10.2", - "pin-project", + "parking_lot 0.11.0", + "pin-project 1.0.1", "prost", "prost-build", "rand 0.7.3", "ring", "rw-stream-sink", - "sha2 0.8.2", + "sha2 0.9.2", "smallvec 1.4.2", "thiserror", - "unsigned-varint 0.4.0", + "unsigned-varint 0.5.1", "void", "zeroize", ] @@ -3179,27 +3135,82 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f753d9324cd3ec14bf04b8a8cd0d269c87f294153d6bf2a84497a63a5ad22213" dependencies = [ "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", +] + +[[package]] +name = "libp2p-deflate" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567962c5c5f8a1282979441300e1739ba939024010757c3dbfab4d462189df77" +dependencies = [ + "flate2", + "futures 0.3.7", + "libp2p-core", ] [[package]] name = "libp2p-dns" -version = "0.20.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f751924b6b98e350005e0b87a822beb246792a3fb878c684e088f866158120ac" +checksum = "436280f5fe21a58fcaff82c2606945579241f32bc0eaf2d39321aa4624a66e7f" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", "libp2p-core", "log 0.4.11", ] [[package]] -name = "libp2p-identify" -version = "0.20.0" +name = "libp2p-floodsub" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "912c00a7bf67e0e765daf0cc37e08f675ea26aba3d6d1fbfaee81f19a4c23049" +checksum = "ecc175613c5915332fd6458895407ec242ea055ae3b107a586626d5e3349350a" dependencies = [ - "futures 0.3.5", + "cuckoofilter", + "fnv", + "futures 0.3.7", + "libp2p-core", + "libp2p-swarm", + "log 0.4.11", + "prost", + "prost-build", + "rand 0.7.3", + "smallvec 1.4.2", +] + +[[package]] +name = "libp2p-gossipsub" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d500ad89ba14de4d18bebdff61a0ce3e769f1c5c5a95026c5da90187e5fff5c9" +dependencies = [ + "base64 0.13.0", + "byteorder", + "bytes 0.5.6", + "fnv", + "futures 0.3.7", + "futures_codec", + "hex_fmt", + "libp2p-core", + "libp2p-swarm", + "log 0.4.11", + "lru_time_cache", + "prost", + "prost-build", + "rand 0.7.3", + "sha2 0.9.2", + "smallvec 1.4.2", + "unsigned-varint 0.5.1", + "wasm-timer", +] + +[[package]] +name = "libp2p-identify" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b90b350e37f398b73d778bd94422f4e6a3afa2c1582742ce2446b8a0dba787" +dependencies = [ + "futures 0.3.7", "libp2p-core", "libp2p-swarm", "log 0.4.11", @@ -3211,15 +3222,15 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.21.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44ed3a4c8111c570ab2bffb30c6353178d7603ce3787e3c5f2493c8d3d16d1f0" +checksum = "fb78341f114bf686d5fe50b33ff1a804d88fb326c0d39ee1c22db4346b21fc27" dependencies = [ - "arrayvec 0.5.1", + "arrayvec 0.5.2", "bytes 0.5.6", "either", "fnv", - "futures 0.3.5", + "futures 0.3.7", "futures_codec", "libp2p-core", "libp2p-swarm", @@ -3228,25 +3239,25 @@ dependencies = [ "prost", "prost-build", "rand 0.7.3", - "sha2 0.8.2", + "sha2 0.9.2", "smallvec 1.4.2", "uint", - "unsigned-varint 0.4.0", + "unsigned-varint 0.5.1", "void", "wasm-timer", ] [[package]] name = "libp2p-mdns" -version = "0.20.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd004c668160fd922f7268b2cd1e4550ff69165d9c744e9eb5770086eb753d02" +checksum = "b575514fce0a3ccbd065d6aa377bd4d5102001b05c1a22a5eee49c450254ef0f" dependencies = [ "async-std", "data-encoding", "dns-parser", "either", - "futures 0.3.5", + "futures 0.3.7", "lazy_static", "libp2p-core", "libp2p-swarm", @@ -3260,36 +3271,38 @@ dependencies = [ [[package]] name = "libp2p-mplex" -version = "0.20.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14ae0ffacd30f073f96cd518b2c9cd2cb18ac27c3d136a4b23cf1af99f33e541" +checksum = "a92b538238c80067c6417a58a07e41002b69d129355b60ec147d6337fdff0eb0" dependencies = [ "bytes 0.5.6", - "fnv", - "futures 0.3.5", + "futures 0.3.7", "futures_codec", "libp2p-core", "log 0.4.11", - "parking_lot 0.10.2", - "unsigned-varint 0.4.0", + "nohash-hasher", + "parking_lot 0.11.0", + "rand 0.7.3", + "smallvec 1.4.2", + "unsigned-varint 0.5.1", ] [[package]] name = "libp2p-noise" -version = "0.21.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f353f8966bbaaf7456535fffd3f366f153148773a0cf04b2ec3860955cb720e" +checksum = "93c77142e3e5b18fefa7d267305c777c9cbe9b2232ec489979390100bebcc1e6" dependencies = [ "bytes 0.5.6", - "curve25519-dalek 2.1.0", - "futures 0.3.5", + "curve25519-dalek 3.0.0", + "futures 0.3.7", "lazy_static", "libp2p-core", "log 0.4.11", "prost", "prost-build", "rand 0.7.3", - "sha2 0.8.2", + "sha2 0.9.2", "snow", "static_assertions", "x25519-dalek", @@ -3298,11 +3311,11 @@ dependencies = [ [[package]] name = "libp2p-ping" -version = "0.20.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70130cf130e4ba6dc177366e72dd9f86f9e3588fa1a0c4145247e676f16affad" +checksum = "7257135609e8877f4d286935cbe1e572b2018946881c3e7f63054577074a7ee7" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", "libp2p-core", "libp2p-swarm", "log 0.4.11", @@ -3312,12 +3325,64 @@ dependencies = [ ] [[package]] -name = "libp2p-swarm" -version = "0.20.1" +name = "libp2p-plaintext" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f88d5e2a090a2aadf042cd33484e2f015c6dab212567406a59deece5dedbd133" +checksum = "c88d59ba3e710a8c8e0535cb4a52e9e46534924cbbea4691f8c3aaad17b58c61" dependencies = [ - "futures 0.3.5", + "bytes 0.5.6", + "futures 0.3.7", + "futures_codec", + "libp2p-core", + "log 0.4.11", + "prost", + "prost-build", + "unsigned-varint 0.5.1", + "void", +] + +[[package]] +name = "libp2p-pnet" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b3c2d5d26a9500e959a0e19743897239a6c4be78dadf99b70414301a70c006" +dependencies = [ + "futures 0.3.7", + "log 0.4.11", + "pin-project 0.4.27", + "rand 0.7.3", + "salsa20", + "sha3", +] + +[[package]] +name = "libp2p-request-response" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02ba1aa5727ccc118c09ba5111480873f2fe5608cb304e258fd12c173ecf27c9" +dependencies = [ + "async-trait", + "bytes 0.5.6", + "futures 0.3.7", + "libp2p-core", + "libp2p-swarm", + "log 0.4.11", + "lru 0.6.1", + "minicbor", + "rand 0.7.3", + "smallvec 1.4.2", + "unsigned-varint 0.5.1", + "wasm-timer", +] + +[[package]] +name = "libp2p-swarm" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffa6fa33b16956b8a58afbfebe1406866011a1ab8960765bd36868952d7be6a1" +dependencies = [ + "either", + "futures 0.3.7", "libp2p-core", "log 0.4.11", "rand 0.7.3", @@ -3328,14 +3393,14 @@ dependencies = [ [[package]] name = "libp2p-tcp" -version = "0.20.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b1fa2bbad054020cb875546a577a66a65a5bf42eff55ed5265f92ffee3cc052" +checksum = "9d0b6f4ef48d9493607fae069deecce0579320a1f3de6cb056770b151018a9a5" dependencies = [ "async-std", - "futures 0.3.5", + "futures 0.3.7", "futures-timer 3.0.2", - "get_if_addrs", + "if-addrs", "ipnet", "libp2p-core", "log 0.4.11", @@ -3343,12 +3408,24 @@ dependencies = [ ] [[package]] -name = "libp2p-wasm-ext" -version = "0.20.1" +name = "libp2p-uds" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0feb99e32fea20ffb1bbf56a6fb2614bff7325ff44a515728385170b3420d2c3" +checksum = "945bed3c989a1b290b5a0d4e8fa6e44e01840efb9a5ab3f0d3d174f0e451ac0e" dependencies = [ - "futures 0.3.5", + "async-std", + "futures 0.3.7", + "libp2p-core", + "log 0.4.11", +] + +[[package]] +name = "libp2p-wasm-ext" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66518a4455e15c283637b4d7b579aef928b75a3fc6c50a41e7e6b9fa86672ca0" +dependencies = [ + "futures 0.3.7", "js-sys", "libp2p-core", "parity-send-wrapper", @@ -3358,13 +3435,13 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.21.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046a5201f6e471f22b22b394e4d084269ed1e28cf7300f7b49874385db84c7bd" +checksum = "edc561870477523245efaaea1b6b743c70115f10c670e62bcbbe4d3153be5f0c" dependencies = [ "async-tls", "either", - "futures 0.3.5", + "futures 0.3.7", "libp2p-core", "log 0.4.11", "quicksink", @@ -3373,18 +3450,18 @@ dependencies = [ "soketto", "url 2.1.1", "webpki", - "webpki-roots 0.18.0", + "webpki-roots", ] [[package]] name = "libp2p-yamux" -version = "0.20.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46ae9bf2f7d8a4be9c7e9b61df9de9dc1bd66419d669098f22f81f8d9571029a" +checksum = "07c0c9b6ef7a168c2ae854170b0b6b77550599afe06cc3ac390eb45c5d9c7110" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", "libp2p-core", - "parking_lot 0.10.2", + "parking_lot 0.11.0", "thiserror", "yamux", ] @@ -3397,7 +3474,7 @@ checksum = "eb5b56f651c204634b936be2f92dbb42c36867e00ff7fe2405591f3b9fa66f09" dependencies = [ "bindgen", "cc", - "glob 0.3.0", + "glob", "libc", ] @@ -3497,7 +3574,20 @@ version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", +] + +[[package]] +name = "loom" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0e8460f2f2121162705187214720353c517b97bdfb3494c0b1e33d83ebe4bed" +dependencies = [ + "cfg-if 0.1.10", + "generator", + "scoped-tls", + "serde", + "serde_json", ] [[package]] @@ -3509,6 +3599,21 @@ dependencies = [ "hashbrown 0.6.3", ] +[[package]] +name = "lru" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be716eb6878ca2263eb5d00a781aa13264a794f519fe6af4fbb2668b2d5441c0" +dependencies = [ + "hashbrown 0.9.1", +] + +[[package]] +name = "lru_time_cache" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebac060fafad3adedd0c66a80741a92ff4bc8e94a273df2ba3770ab206f2e29a" + [[package]] name = "mach" version = "0.3.2" @@ -3518,6 +3623,21 @@ dependencies = [ "libc", ] +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata", +] + [[package]] name = "matches" version = "0.1.8" @@ -3541,9 +3661,9 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[package]] name = "memchr" -version = "2.3.3" +version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" [[package]] name = "memmap" @@ -3603,10 +3723,30 @@ dependencies = [ ] [[package]] -name = "miniz_oxide" -version = "0.4.2" +name = "minicbor" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c60c0dfe32c10b43a144bad8fc83538c52f58302c92300ea7ec7bf7b38d5a7b9" +checksum = "9a2ef6aa869726518c5d8206fa5d1337bda8a0442807611be617891c018fa781" +dependencies = [ + "minicbor-derive", +] + +[[package]] +name = "minicbor-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b3569c0dbfff1b8d5f1434c642b67f5bf81c0f354a3f5f8f180b549dba3c07c" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn 1.0.48", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" dependencies = [ "adler", "autocfg 1.0.1", @@ -3618,7 +3758,7 @@ version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "fuchsia-zircon", "fuchsia-zircon-sys", "iovec", @@ -3703,8 +3843,8 @@ dependencies = [ "blake2b_simd", "blake2s_simd", "digest 0.9.0", - "sha-1 0.9.1", - "sha2 0.9.1", + "sha-1 0.9.2", + "sha2 0.9.2", "sha3", "unsigned-varint 0.5.1", ] @@ -3717,16 +3857,16 @@ checksum = "1255076139a83bb467426e7f8d0134968a8118844faa755985e077cf31850333" [[package]] name = "multistream-select" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9157e87afbc2ef0d84cc0345423d715f445edde00141c93721c162de35a05e5" +checksum = "36a6aa6e32fbaf16795142335967214b8564a7a4661eb6dc846ef343a6e00ac1" dependencies = [ "bytes 0.5.6", - "futures 0.3.5", + "futures 0.3.7", "log 0.4.11", - "pin-project", + "pin-project 1.0.1", "smallvec 1.4.2", - "unsigned-varint 0.4.0", + "unsigned-varint 0.5.1", ] [[package]] @@ -3741,7 +3881,7 @@ dependencies = [ "matrixmultiply", "num-complex", "num-rational", - "num-traits 0.2.12", + "num-traits 0.2.14", "rand 0.6.5", "typenum", ] @@ -3757,9 +3897,9 @@ dependencies = [ [[package]] name = "nb-connect" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "701f47aeb98466d0a7fea67e2c2f667c33efa1f2e4fd7f76743aac1153196f72" +checksum = "8123a81538e457d44b933a02faf885d3fe8408806b23fa700e8f01c6c3a98998" dependencies = [ "libc", "winapi 0.3.9", @@ -3771,25 +3911,11 @@ version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ebc3ec692ed7c9a255596c67808dee269f64655d8baf7b4f0638e51ba1d6853" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "winapi 0.3.9", ] -[[package]] -name = "netstat2" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29449d242064c48d3057a194b049a2bdcccadda16faa18a91468677b44e8d422" -dependencies = [ - "bitflags", - "byteorder", - "enum-primitive-derive", - "libc", - "num-traits 0.2.12", - "thiserror", -] - [[package]] name = "nix" version = "0.10.0" @@ -3798,7 +3924,7 @@ checksum = "b7fd5681d13fda646462cfbd4e5f2051279a89a544d50eb98c365b507246839f" dependencies = [ "bitflags", "bytes 0.4.12", - "cfg-if", + "cfg-if 0.1.10", "gcc", "libc", "void", @@ -3812,7 +3938,7 @@ checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363" dependencies = [ "bitflags", "cc", - "cfg-if", + "cfg-if 0.1.10", "libc", "void", ] @@ -3839,15 +3965,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "ntapi" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a31937dea023539c72ddae0e3571deadc1414b300483fa7aaec176168cfa9d2" -dependencies = [ - "winapi 0.3.9", -] - [[package]] name = "num-bigint" version = "0.2.6" @@ -3856,7 +3973,7 @@ checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ "autocfg 1.0.1", "num-integer", - "num-traits 0.2.12", + "num-traits 0.2.14", ] [[package]] @@ -3866,17 +3983,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" dependencies = [ "autocfg 1.0.1", - "num-traits 0.2.12", + "num-traits 0.2.14", ] [[package]] name = "num-integer" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ "autocfg 1.0.1", - "num-traits 0.2.12", + "num-traits 0.2.14", ] [[package]] @@ -3888,7 +4005,7 @@ dependencies = [ "autocfg 1.0.1", "num-bigint", "num-integer", - "num-traits 0.2.12", + "num-traits 0.2.14", ] [[package]] @@ -3897,14 +4014,14 @@ version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" dependencies = [ - "num-traits 0.2.12", + "num-traits 0.2.14", ] [[package]] name = "num-traits" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ "autocfg 1.0.1", "libm", @@ -3937,6 +4054,21 @@ dependencies = [ "wasmparser 0.57.0", ] +[[package]] +name = "object" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" + +[[package]] +name = "once_cell" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" +dependencies = [ + "parking_lot 0.7.1", +] + [[package]] name = "once_cell" version = "1.4.1" @@ -3975,8 +4107,8 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -3991,8 +4123,8 @@ dependencies = [ [[package]] name = "pallet-authorship" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4006,8 +4138,8 @@ dependencies = [ [[package]] name = "pallet-babe" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-benchmarking", "frame-support", @@ -4031,8 +4163,8 @@ dependencies = [ [[package]] name = "pallet-balances" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-benchmarking", "frame-support", @@ -4045,8 +4177,8 @@ dependencies = [ [[package]] name = "pallet-collective" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4060,8 +4192,8 @@ dependencies = [ [[package]] name = "pallet-democracy" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-benchmarking", "frame-support", @@ -4075,8 +4207,8 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4087,32 +4219,15 @@ dependencies = [ "sp-std", ] -[[package]] -name = "pallet-finality-tracker" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" -dependencies = [ - "frame-support", - "frame-system", - "impl-trait-for-tuples", - "parity-scale-codec", - "serde", - "sp-finality-tracker", - "sp-inherents", - "sp-runtime", - "sp-std", -] - [[package]] name = "pallet-grandpa" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "pallet-authorship", - "pallet-finality-tracker", "pallet-session", "parity-scale-codec", "serde", @@ -4127,8 +4242,8 @@ dependencies = [ [[package]] name = "pallet-identity" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "enumflags2", "frame-benchmarking", @@ -4143,8 +4258,8 @@ dependencies = [ [[package]] name = "pallet-im-online" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4162,8 +4277,8 @@ dependencies = [ [[package]] name = "pallet-indices" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4178,8 +4293,8 @@ dependencies = [ [[package]] name = "pallet-membership" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4192,8 +4307,8 @@ dependencies = [ [[package]] name = "pallet-multisig" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4207,8 +4322,8 @@ dependencies = [ [[package]] name = "pallet-nicks" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4221,8 +4336,8 @@ dependencies = [ [[package]] name = "pallet-offences" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4236,8 +4351,8 @@ dependencies = [ [[package]] name = "pallet-proxy" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.1" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4251,8 +4366,8 @@ dependencies = [ [[package]] name = "pallet-randomness-collective-flip" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4264,8 +4379,8 @@ dependencies = [ [[package]] name = "pallet-recovery" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "enumflags2", "frame-support", @@ -4279,8 +4394,8 @@ dependencies = [ [[package]] name = "pallet-scheduler" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-benchmarking", "frame-support", @@ -4294,8 +4409,8 @@ dependencies = [ [[package]] name = "pallet-session" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4314,8 +4429,8 @@ dependencies = [ [[package]] name = "pallet-society" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4328,8 +4443,8 @@ dependencies = [ [[package]] name = "pallet-staking" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4348,19 +4463,19 @@ dependencies = [ [[package]] name = "pallet-staking-reward-curve" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] name = "pallet-sudo" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4373,8 +4488,8 @@ dependencies = [ [[package]] name = "pallet-timestamp" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-benchmarking", "frame-support", @@ -4390,8 +4505,8 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4407,8 +4522,8 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -4425,8 +4540,8 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "parity-scale-codec", @@ -4438,8 +4553,8 @@ dependencies = [ [[package]] name = "pallet-treasury" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4452,8 +4567,8 @@ dependencies = [ [[package]] name = "pallet-utility" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-support", "frame-system", @@ -4467,8 +4582,8 @@ dependencies = [ [[package]] name = "pallet-vesting" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "enumflags2", "frame-support", @@ -4506,9 +4621,9 @@ dependencies = [ [[package]] name = "parity-multiaddr" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2165a93382a93de55868dcbfa11e4a8f99676a9164eee6a2b4a9479ad319c257" +checksum = "4c7ad66970bbab360c97179b60906e2dc4aef1f7fca8ab4e5c5db8c97b16814a" dependencies = [ "arrayref", "bs58", @@ -4518,7 +4633,7 @@ dependencies = [ "percent-encoding 2.1.0", "serde", "static_assertions", - "unsigned-varint 0.4.0", + "unsigned-varint 0.5.1", "url 2.1.1", ] @@ -4528,7 +4643,7 @@ version = "1.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c740e5fbcb6847058b40ac7e5574766c6388f585e184d769910fe0d3a2ca861" dependencies = [ - "arrayvec 0.5.1", + "arrayvec 0.5.2", "bitvec", "byte-slice-cast", "parity-scale-codec-derive", @@ -4542,9 +4657,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "198db82bb1c18fc00176004462dd809b2a6d851669550aa17af6dacd21ae0c14" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] @@ -4560,7 +4675,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e57fea504fea33f9fbb5f49f378359030e7e026a6ab849bb9e8f0787376f1bf" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "libc", "log 0.4.11", "mio-named-pipes", @@ -4578,7 +4693,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "297ff91fa36aec49ce183484b102f6b75b46776822bd81525bfc4cc9b0dd0f5c" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "hashbrown 0.8.2", "impl-trait-for-tuples", "parity-util-mem-derive", @@ -4594,8 +4709,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" dependencies = [ - "proc-macro2 1.0.23", - "syn 1.0.42", + "proc-macro2 1.0.24", + "syn 1.0.48", "synstructure", ] @@ -4605,6 +4720,24 @@ version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" +[[package]] +name = "parity-ws" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e02a625dd75084c2a7024f07c575b61b782f729d18702dabb3cdbf31911dc61" +dependencies = [ + "byteorder", + "bytes 0.4.12", + "httparse", + "log 0.4.11", + "mio", + "mio-extras", + "rand 0.7.3", + "sha-1 0.8.2", + "slab", + "url 2.1.1", +] + [[package]] name = "parking" version = "2.0.0" @@ -4672,7 +4805,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "cloudabi 0.0.3", "libc", "redox_syscall", @@ -4687,7 +4820,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "cloudabi 0.0.3", "libc", "redox_syscall", @@ -4701,7 +4834,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "cloudabi 0.1.0", "instant", "libc", @@ -4737,6 +4870,7 @@ checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" dependencies = [ "byteorder", "crypto-mac 0.7.0", + "rayon", ] [[package]] @@ -4763,6 +4897,49 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn 1.0.48", +] + +[[package]] +name = "pest_meta" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" +dependencies = [ + "maplit", + "pest", + "sha-1 0.8.2", +] + [[package]] name = "petgraph" version = "0.5.1" @@ -4775,29 +4952,49 @@ dependencies = [ [[package]] name = "pin-project" -version = "0.4.24" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f48fad7cfbff853437be7cf54d7b993af21f53be7f0988cbfe4a51535aa77205" +checksum = "2ffbc8e94b38ea3d2d8ba92aea2983b503cd75d0888d75b86bb37970b5698e15" dependencies = [ - "pin-project-internal", + "pin-project-internal 0.4.27", +] + +[[package]] +name = "pin-project" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee41d838744f60d959d7074e3afb6b35c7456d0f61cad38a24e35e6553f73841" +dependencies = [ + "pin-project-internal 1.0.1", ] [[package]] name = "pin-project-internal" -version = "0.4.24" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24c6d293bdd3ca5a1697997854c6cf7855e43fb6a0ba1c47af57a5bcafd158ae" +checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81a4ffa594b66bff340084d4081df649a7dc049ac8d7fc458d8e628bfbbb2f86" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn 1.0.48", ] [[package]] name = "pin-project-lite" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fe74897791e156a0cd8cce0db31b9b2198e67877316bf3086c3acd187f719f0" +checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b" [[package]] name = "pin-utils" @@ -4807,9 +5004,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" [[package]] name = "platforms" @@ -4818,86 +5015,74 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "feb3b2b1033b8a60b4da6ee470325f887758c95d5320f52f9ce0df055a55940e" [[package]] -name = "polkadot-availability-store" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +name = "polkadot-availability-bitfield-distribution" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ - "derive_more 0.99.10", - "exit-future 0.2.0", - "futures 0.3.5", - "kvdb", - "kvdb-memorydb", - "kvdb-rocksdb", + "futures 0.3.7", "log 0.4.11", "parity-scale-codec", - "parking_lot 0.9.0", - "polkadot-erasure-coding", + "polkadot-node-network-protocol", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-primitives", +] + +[[package]] +name = "polkadot-availability-distribution" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "futures 0.3.7", + "log 0.4.11", + "parity-scale-codec", + "polkadot-erasure-coding", + "polkadot-node-network-protocol", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", "polkadot-primitives", - "sc-client-api", - "sc-keystore", - "sc-network", - "sp-api", - "sp-blockchain", - "sp-consensus", "sp-core", - "sp-runtime", - "tokio 0.2.22", + "sp-keystore", + "thiserror", ] [[package]] name = "polkadot-cli" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +version = "0.8.26" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ "frame-benchmarking-cli", - "futures 0.3.5", "log 0.4.11", + "polkadot-parachain", "polkadot-service", "sc-cli", - "sc-client-api", - "sc-client-db", - "sc-executor", "sc-service", - "sp-api", + "sc-tracing", "sp-core", - "sp-runtime", "sp-trie", "structopt", "substrate-build-script-utils", - "tokio 0.2.22", + "thiserror", ] [[package]] -name = "polkadot-collator" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +name = "polkadot-collator-protocol" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ - "futures 0.3.5", - "futures-timer 2.0.2", + "futures 0.3.7", "log 0.4.11", - "parity-scale-codec", - "polkadot-cli", - "polkadot-network", + "polkadot-node-network-protocol", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", "polkadot-primitives", - "polkadot-service", - "polkadot-validation", - "sc-cli", - "sc-client-api", - "sc-executor", - "sc-network", - "sc-service", - "sp-api", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-runtime", - "tokio 0.2.22", + "thiserror", ] [[package]] name = "polkadot-core-primitives" version = "0.7.30" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ "parity-scale-codec", "sp-core", @@ -4907,53 +5092,311 @@ dependencies = [ [[package]] name = "polkadot-erasure-coding" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +version = "0.8.26" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ - "derive_more 0.15.0", "parity-scale-codec", "polkadot-primitives", "reed-solomon-erasure", "sp-core", "sp-trie", + "thiserror", ] [[package]] -name = "polkadot-network" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +name = "polkadot-network-bridge" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ - "arrayvec 0.4.12", - "bytes 0.5.6", - "derive_more 0.14.1", - "exit-future 0.2.0", - "futures 0.3.5", - "futures-timer 2.0.2", + "async-trait", + "futures 0.3.7", "log 0.4.11", "parity-scale-codec", - "parking_lot 0.9.0", - "polkadot-availability-store", - "polkadot-erasure-coding", + "polkadot-node-network-protocol", + "polkadot-node-subsystem", "polkadot-primitives", - "polkadot-validation", - "rand 0.7.3", + "sc-authority-discovery", "sc-network", - "sc-network-gossip", - "sp-api", - "sp-blockchain", - "sp-consensus", - "sp-core", "sp-runtime", +] + +[[package]] +name = "polkadot-node-collation-generation" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "futures 0.3.7", + "log 0.4.11", + "polkadot-erasure-coding", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "sp-core", + "thiserror", +] + +[[package]] +name = "polkadot-node-core-av-store" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "futures 0.3.7", + "futures-timer 3.0.2", + "kvdb", + "kvdb-rocksdb", + "log 0.4.11", + "parity-scale-codec", + "polkadot-erasure-coding", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-overseer", + "polkadot-primitives", + "sc-service", + "thiserror", +] + +[[package]] +name = "polkadot-node-core-backing" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "bitvec", + "futures 0.3.7", + "log 0.4.11", + "polkadot-erasure-coding", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "polkadot-statement-table", + "sp-keystore", + "thiserror", +] + +[[package]] +name = "polkadot-node-core-bitfield-signing" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "derive_more 0.99.11", + "futures 0.3.7", + "log 0.4.11", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "sp-keystore", + "thiserror", "wasm-timer", ] [[package]] -name = "polkadot-parachain" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +name = "polkadot-node-core-candidate-selection" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ - "derive_more 0.99.10", - "futures 0.3.5", + "futures 0.3.7", + "log 0.4.11", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "thiserror", +] + +[[package]] +name = "polkadot-node-core-candidate-validation" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "futures 0.3.7", + "log 0.4.11", + "parity-scale-codec", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-parachain", + "polkadot-primitives", + "sp-core", +] + +[[package]] +name = "polkadot-node-core-chain-api" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "futures 0.3.7", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "sp-blockchain", +] + +[[package]] +name = "polkadot-node-core-proposer" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "futures 0.3.7", + "futures-timer 3.0.2", + "log 0.4.11", + "polkadot-node-subsystem", + "polkadot-overseer", + "polkadot-primitives", + "sc-basic-authorship", + "sc-block-builder", + "sc-client-api", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-transaction-pool", + "substrate-prometheus-endpoint", +] + +[[package]] +name = "polkadot-node-core-provisioner" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "bitvec", + "futures 0.3.7", + "log 0.4.11", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "thiserror", +] + +[[package]] +name = "polkadot-node-core-runtime-api" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "futures 0.3.7", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "sp-api", +] + +[[package]] +name = "polkadot-node-network-protocol" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "parity-scale-codec", + "polkadot-node-primitives", + "polkadot-primitives", + "sc-network", +] + +[[package]] +name = "polkadot-node-primitives" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "futures 0.3.7", + "parity-scale-codec", + "polkadot-primitives", + "polkadot-statement-table", + "sp-core", + "sp-runtime", +] + +[[package]] +name = "polkadot-node-subsystem" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "async-trait", + "derive_more 0.99.11", + "futures 0.3.7", + "futures-timer 3.0.2", + "log 0.4.11", + "parity-scale-codec", + "pin-project 0.4.27", + "polkadot-node-network-protocol", + "polkadot-node-primitives", + "polkadot-primitives", + "polkadot-statement-table", + "sc-network", + "smallvec 1.4.2", + "sp-core", + "substrate-prometheus-endpoint", + "thiserror", +] + +[[package]] +name = "polkadot-node-subsystem-test-helpers" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "async-trait", + "futures 0.3.7", + "futures-timer 3.0.2", + "log 0.4.11", + "parity-scale-codec", + "parking_lot 0.10.2", + "pin-project 0.4.27", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "polkadot-statement-table", + "sc-network", + "smallvec 1.4.2", + "sp-core", +] + +[[package]] +name = "polkadot-node-subsystem-util" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "async-trait", + "futures 0.3.7", + "futures-timer 3.0.2", + "log 0.4.11", + "parity-scale-codec", + "pin-project 0.4.27", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-primitives", + "sc-network", + "sp-application-crypto", + "sp-core", + "sp-keystore", + "streamunordered", + "substrate-prometheus-endpoint", + "thiserror", +] + +[[package]] +name = "polkadot-overseer" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "async-trait", + "futures 0.3.7", + "futures-timer 3.0.2", + "log 0.4.11", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "sc-client-api", + "streamunordered", +] + +[[package]] +name = "polkadot-parachain" +version = "0.8.26" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "derive_more 0.99.11", + "futures 0.3.7", "log 0.4.11", "parity-scale-codec", "parking_lot 0.10.2", @@ -4964,14 +5407,29 @@ dependencies = [ "sp-core", "sp-externalities", "sp-io", + "sp-runtime", "sp-std", "sp-wasm-interface", + "thiserror", +] + +[[package]] +name = "polkadot-pov-distribution" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "futures 0.3.7", + "log 0.4.11", + "polkadot-node-network-protocol", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-primitives", ] [[package]] name = "polkadot-primitives" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +version = "0.8.26" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ "bitvec", "frame-system", @@ -4982,8 +5440,10 @@ dependencies = [ "sp-api", "sp-application-crypto", "sp-arithmetic", + "sp-authority-discovery", "sp-core", "sp-inherents", + "sp-keystore", "sp-runtime", "sp-staking", "sp-std", @@ -4993,13 +5453,14 @@ dependencies = [ [[package]] name = "polkadot-rpc" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +version = "0.8.26" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ "jsonrpc-core", "pallet-transaction-payment-rpc", "parity-scale-codec", "polkadot-primitives", + "sc-chain-spec", "sc-client-api", "sc-consensus-babe", "sc-consensus-babe-rpc", @@ -5008,11 +5469,13 @@ dependencies = [ "sc-finality-grandpa-rpc", "sc-keystore", "sc-rpc", + "sc-sync-state-rpc", "sp-api", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-babe", + "sp-keystore", "sp-runtime", "sp-transaction-pool", "substrate-frame-rpc-system", @@ -5020,15 +5483,14 @@ dependencies = [ [[package]] name = "polkadot-runtime" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +version = "0.8.26" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ "bitvec", "frame-executive", "frame-support", "frame-system", "frame-system-rpc-runtime-api", - "hex-literal", "log 0.3.9", "pallet-authority-discovery", "pallet-authorship", @@ -5037,7 +5499,6 @@ dependencies = [ "pallet-collective", "pallet-democracy", "pallet-elections-phragmen", - "pallet-finality-tracker", "pallet-grandpa", "pallet-identity", "pallet-im-online", @@ -5080,13 +5541,13 @@ dependencies = [ "sp-transaction-pool", "sp-version", "static_assertions", - "substrate-wasm-builder-runner 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-wasm-builder-runner 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "polkadot-runtime-common" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +version = "0.8.26" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ "bitvec", "frame-support", @@ -5099,6 +5560,7 @@ dependencies = [ "pallet-staking", "pallet-timestamp", "pallet-transaction-payment", + "pallet-treasury", "pallet-vesting", "parity-scale-codec", "polkadot-primitives", @@ -5120,11 +5582,13 @@ dependencies = [ [[package]] name = "polkadot-runtime-parachains" version = "0.8.0" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ "bitvec", "frame-support", "frame-system", + "log 0.4.11", + "pallet-authority-discovery", "pallet-authorship", "pallet-balances", "pallet-offences", @@ -5142,6 +5606,7 @@ dependencies = [ "sp-core", "sp-inherents", "sp-io", + "sp-keystore", "sp-runtime", "sp-session", "sp-staking", @@ -5150,13 +5615,13 @@ dependencies = [ [[package]] name = "polkadot-service" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +version = "0.8.3" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ "frame-benchmarking", "frame-system-rpc-runtime-api", - "futures 0.3.5", - "hex-literal", + "futures 0.3.7", + "hex-literal 0.2.1", "kusama-runtime", "lazy_static", "log 0.4.11", @@ -5166,12 +5631,30 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", "parking_lot 0.9.0", - "polkadot-availability-store", - "polkadot-network", + "polkadot-availability-bitfield-distribution", + "polkadot-availability-distribution", + "polkadot-collator-protocol", + "polkadot-network-bridge", + "polkadot-node-collation-generation", + "polkadot-node-core-av-store", + "polkadot-node-core-backing", + "polkadot-node-core-bitfield-signing", + "polkadot-node-core-candidate-selection", + "polkadot-node-core-candidate-validation", + "polkadot-node-core-chain-api", + "polkadot-node-core-proposer", + "polkadot-node-core-provisioner", + "polkadot-node-core-runtime-api", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-overseer", + "polkadot-parachain", + "polkadot-pov-distribution", "polkadot-primitives", "polkadot-rpc", "polkadot-runtime", - "polkadot-validation", + "polkadot-runtime-parachains", + "polkadot-statement-distribution", "rococo-runtime", "sc-authority-discovery", "sc-block-builder", @@ -5182,7 +5665,6 @@ dependencies = [ "sc-consensus-babe", "sc-executor", "sc-finality-grandpa", - "sc-keystore", "sc-network", "sc-service", "sc-telemetry", @@ -5199,29 +5681,72 @@ dependencies = [ "sp-finality-grandpa", "sp-inherents", "sp-io", + "sp-keystore", "sp-offchain", "sp-runtime", "sp-session", + "sp-storage", "sp-transaction-pool", "sp-trie", "substrate-prometheus-endpoint", "westend-runtime", ] +[[package]] +name = "polkadot-statement-distribution" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "arrayvec 0.5.2", + "futures 0.3.7", + "indexmap", + "log 0.4.11", + "polkadot-node-network-protocol", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-primitives", + "sp-staking", +] + [[package]] name = "polkadot-statement-table" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +version = "0.8.26" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ "parity-scale-codec", "polkadot-primitives", "sp-core", ] +[[package]] +name = "polkadot-test-client" +version = "0.8.26" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" +dependencies = [ + "parity-scale-codec", + "polkadot-node-subsystem", + "polkadot-primitives", + "polkadot-test-runtime", + "polkadot-test-service", + "sc-block-builder", + "sc-consensus", + "sc-service", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-state-machine", + "sp-timestamp", + "substrate-test-client", +] + [[package]] name = "polkadot-test-runtime" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +version = "0.8.26" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ "bitvec", "frame-executive", @@ -5233,7 +5758,6 @@ dependencies = [ "pallet-authorship", "pallet-babe", "pallet-balances", - "pallet-finality-tracker", "pallet-grandpa", "pallet-indices", "pallet-nicks", @@ -5251,6 +5775,7 @@ dependencies = [ "polkadot-parachain", "polkadot-primitives", "polkadot-runtime-common", + "polkadot-runtime-parachains", "rustc-hex", "serde", "serde_derive", @@ -5269,68 +5794,47 @@ dependencies = [ "sp-std", "sp-transaction-pool", "sp-version", - "substrate-wasm-builder-runner 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "polkadot-test-runtime-client" -version = "2.0.0" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" -dependencies = [ - "futures 0.3.5", - "pallet-timestamp", - "parity-scale-codec", - "polkadot-primitives", - "polkadot-runtime-common", - "polkadot-test-runtime", - "polkadot-test-service", - "sc-block-builder", - "sc-client-api", - "sc-consensus", - "sc-light", - "sc-service", - "sp-api", - "sp-blockchain", - "sp-core", - "sp-runtime", - "substrate-test-client", + "substrate-wasm-builder-runner 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "polkadot-test-service" -version = "0.8.2" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +version = "0.8.26" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ "frame-benchmarking", "frame-system", - "futures 0.1.29", - "futures 0.3.5", + "futures 0.1.30", + "futures 0.3.7", "hex", "log 0.4.11", + "pallet-balances", "pallet-staking", - "pallet-sudo", "pallet-transaction-payment", - "polkadot-availability-store", - "polkadot-network", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-overseer", + "polkadot-parachain", "polkadot-primitives", "polkadot-rpc", "polkadot-runtime-common", + "polkadot-runtime-parachains", "polkadot-service", "polkadot-test-runtime", - "polkadot-validation", "rand 0.7.3", "sc-authority-discovery", "sc-chain-spec", + "sc-cli", "sc-client-api", "sc-consensus", "sc-consensus-babe", "sc-executor", "sc-finality-grandpa", - "sc-informant", "sc-network", "sc-service", "sc-transaction-pool", "sp-arithmetic", + "sp-authority-discovery", "sp-blockchain", "sp-consensus", "sp-consensus-babe", @@ -5346,29 +5850,18 @@ dependencies = [ [[package]] name = "polkadot-validation" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +version = "0.8.26" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ - "ansi_term 0.12.1", - "bitvec", - "derive_more 0.14.1", - "exit-future 0.2.0", - "futures 0.3.5", - "futures-timer 2.0.2", + "futures 0.3.7", "log 0.4.11", - "pallet-babe", "parity-scale-codec", - "parking_lot 0.9.0", - "polkadot-availability-store", - "polkadot-erasure-coding", "polkadot-parachain", "polkadot-primitives", - "polkadot-statement-table", "sc-basic-authorship", "sc-block-builder", "sc-client-api", "sc-finality-grandpa", - "sc-keystore", "sp-api", "sp-blockchain", "sp-consensus", @@ -5380,19 +5873,19 @@ dependencies = [ "sp-transaction-pool", "sp-trie", "substrate-prometheus-endpoint", - "tokio 0.2.22", + "thiserror", ] [[package]] name = "polling" -version = "1.1.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0720e0b9ea9d52451cf29d3413ba8a9303f8815d9d9653ef70e03ff73e65566" +checksum = "a2a7bc6b2a29e632e45451c941832803a18cce6781db04de8a04696cdca8bde4" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "log 0.4.11", - "wepoll-sys-stjepang", + "wepoll-sys", "winapi 0.3.9", ] @@ -5411,15 +5904,15 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5884790f1ce3553ad55fec37b5aaac5882e0e845a2612df744d6c85c9bf046c" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "universal-hash", ] [[package]] name = "ppv-lite86" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" [[package]] name = "predicates" @@ -5455,7 +5948,7 @@ checksum = "c55c21c64d0eaa4d7ed885d959ef2d62d9e488c27c0e02d9aa5ce6c877b7d5f8" dependencies = [ "fixed-hash", "impl-codec", - "impl-serde 0.3.1", + "impl-serde", "uint", ] @@ -5475,9 +5968,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", "version_check", ] @@ -5487,16 +5980,16 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", "version_check", ] [[package]] name = "proc-macro-hack" -version = "0.5.18" +version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro-nested" @@ -5515,38 +6008,24 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51ef7cd2518ead700af67bf9d1a658d90b6037d77110fd9c0445429d0ba1c6c9" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ "unicode-xid 0.2.1", ] -[[package]] -name = "procfs" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c434e93ef69c216e68e4f417c927b4f31502c3560b72cfdb6827e2321c5c6b3e" -dependencies = [ - "bitflags", - "byteorder", - "chrono", - "hex", - "lazy_static", - "libc", - "libflate", -] - [[package]] name = "prometheus" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0ced56dee39a6e960c15c74dc48849d614586db2eaada6497477af7c7811cd" +checksum = "30d70cf4412832bcac9cffe27906f4a66e450d323525e977168c70d1b36120ae" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "fnv", "lazy_static", - "spin", + "parking_lot 0.11.0", + "regex", "thiserror", ] @@ -5586,9 +6065,9 @@ checksum = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72" dependencies = [ "anyhow", "itertools 0.8.2", - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] @@ -5603,9 +6082,9 @@ dependencies = [ [[package]] name = "pwasm-utils" -version = "0.12.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f7a12f176deee919f4ba55326ee17491c8b707d0987aed822682c821b660192" +checksum = "0f53bc2558e8376358ebdc28301546471d67336584f6438ed4b7c7457a055fd7" dependencies = [ "byteorder", "log 0.4.11", @@ -5618,6 +6097,12 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quick-error" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ac73b1112776fc109b2e61909bc46c7e1bf0d7f690ffb1676553acce16d5cda" + [[package]] name = "quicksink" version = "0.1.2" @@ -5629,12 +6114,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "quote" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" - [[package]] name = "quote" version = "0.6.13" @@ -5650,7 +6129,7 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", ] [[package]] @@ -5720,7 +6199,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom", + "getrandom 0.1.15", "libc", "rand_chacha 0.2.2", "rand_core 0.5.1", @@ -5769,7 +6248,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom", + "getrandom 0.1.15", ] [[package]] @@ -5871,25 +6350,25 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf6960dc9a5b4ee8d3e4c5787b4a112a8818e0290a42ff664ad60692fdf2032" +checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" dependencies = [ "autocfg 1.0.1", - "crossbeam-deque", + "crossbeam-deque 0.8.0", "either", "rayon-core", ] [[package]] name = "rayon-core" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c4fec834fb6e6d2dd5eece3c7b432a52f0ba887cf40e595190c4107edc08bf" +checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" dependencies = [ "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", + "crossbeam-deque 0.8.0", + "crossbeam-utils 0.8.0", "lazy_static", "num_cpus", ] @@ -5915,7 +6394,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" dependencies = [ - "getrandom", + "getrandom 0.1.15", "redox_syscall", "rust-argon2", ] @@ -5931,22 +6410,22 @@ dependencies = [ [[package]] name = "ref-cast" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "745c1787167ddae5569661d5ffb8b25ae5fedbf46717eaa92d652221cec72623" +checksum = "e17626b2f4bcf35b84bf379072a66e28cfe5c3c6ae58b38e4914bb8891dabece" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d21b475ab879ef0e315ad99067fa25778c3b0377f57f1b00207448dac1a3144" +checksum = "0c523ccaed8ac4b0288948849a350b37d3035827413c458b6a40ddb614bb4f72" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] @@ -5962,9 +6441,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.3.9" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" +checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" dependencies = [ "aho-corasick", "memchr", @@ -5973,10 +6452,20 @@ dependencies = [ ] [[package]] -name = "regex-syntax" -version = "0.6.18" +name = "regex-automata" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" +checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" +dependencies = [ + "byteorder", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" [[package]] name = "region" @@ -5999,27 +6488,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "rental" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8545debe98b2b139fb04cad8618b530e9b07c152d99a5de83c860b877d67847f" -dependencies = [ - "rental-impl", - "stable_deref_trait", -] - -[[package]] -name = "rental-impl" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "475e68978dc5b743f2f40d8e0a8fdc83f1c5e78cbf4b8fa5e74e73beebc340de" -dependencies = [ - "proc-macro2 1.0.23", - "quote 1.0.7", - "syn 1.0.42", -] - [[package]] name = "retain_mut" version = "0.1.1" @@ -6034,19 +6502,13 @@ checksum = "952cd6b98c85bbc30efa1ba5783b8abf12fec8b3287ffa52605b9432313e34e4" dependencies = [ "cc", "libc", - "once_cell", + "once_cell 1.4.1", "spin", "untrusted", "web-sys", "winapi 0.3.9", ] -[[package]] -name = "rle-decode-fast" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" - [[package]] name = "rocksdb" version = "0.15.0" @@ -6061,30 +6523,32 @@ dependencies = [ name = "rococo-collator" version = "0.1.0" dependencies = [ - "ansi_term 0.12.1", "assert_cmd", "cumulus-collator", "cumulus-consensus", - "cumulus-contracts-parachain-runtime", "cumulus-network", - "cumulus-pallet-contracts-rpc", "cumulus-primitives", "cumulus-service", "cumulus-test-parachain-runtime", "derive_more 0.15.0", "exit-future 0.1.4", - "futures 0.3.5", - "hex-literal", + "futures 0.3.7", + "hex-literal 0.2.1", "jsonrpc-core", "log 0.4.11", "nix 0.17.0", + "pallet-sudo", "parity-scale-codec", "parking_lot 0.9.0", "polkadot-cli", - "polkadot-collator", "polkadot-parachain", "polkadot-primitives", + "polkadot-runtime-common", "polkadot-service", + "polkadot-test-client", + "polkadot-test-runtime", + "polkadot-test-service", + "rand 0.7.3", "rococo-parachain-primitives", "sc-basic-authorship", "sc-chain-spec", @@ -6093,12 +6557,12 @@ dependencies = [ "sc-consensus", "sc-executor", "sc-finality-grandpa", - "sc-informant", + "sc-network", "sc-rpc", "sc-service", + "sc-tracing", "sc-transaction-pool", "serde", - "sp-api", "sp-block-builder", "sp-blockchain", "sp-consensus", @@ -6113,6 +6577,9 @@ dependencies = [ "sp-trie", "structopt", "substrate-build-script-utils", + "substrate-test-client", + "substrate-test-runtime-client", + "tokio 0.2.22", "trie-root 0.15.2", ] @@ -6126,52 +6593,33 @@ dependencies = [ [[package]] name = "rococo-runtime" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +version = "0.8.26" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ - "bitvec", "frame-executive", "frame-support", "frame-system", "frame-system-rpc-runtime-api", - "hex-literal", - "log 0.3.9", "pallet-authority-discovery", "pallet-authorship", "pallet-babe", "pallet-balances", - "pallet-collective", - "pallet-democracy", - "pallet-elections-phragmen", - "pallet-finality-tracker", "pallet-grandpa", - "pallet-identity", "pallet-im-online", "pallet-indices", - "pallet-membership", - "pallet-multisig", - "pallet-nicks", "pallet-offences", - "pallet-proxy", - "pallet-randomness-collective-flip", - "pallet-recovery", - "pallet-scheduler", "pallet-session", - "pallet-society", "pallet-staking", "pallet-staking-reward-curve", "pallet-sudo", "pallet-timestamp", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", - "pallet-treasury", - "pallet-utility", - "pallet-vesting", "parity-scale-codec", "polkadot-parachain", "polkadot-primitives", "polkadot-runtime-common", - "rustc-hex", + "polkadot-runtime-parachains", "serde", "serde_derive", "smallvec 1.4.2", @@ -6189,8 +6637,7 @@ dependencies = [ "sp-std", "sp-transaction-pool", "sp-version", - "static_assertions", - "substrate-wasm-builder-runner 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-wasm-builder-runner 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6209,17 +6656,17 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19" dependencies = [ - "base64", + "base64 0.12.3", "blake2b_simd", "constant_time_eq", - "crossbeam-utils", + "crossbeam-utils 0.7.2", ] [[package]] name = "rustc-demangle" -version = "0.1.16" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" +checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" [[package]] name = "rustc-hash" @@ -6254,7 +6701,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81" dependencies = [ - "base64", + "base64 0.12.3", "log 0.4.11", "ring", "sct", @@ -6279,8 +6726,8 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020" dependencies = [ - "futures 0.3.5", - "pin-project", + "futures 0.3.7", + "pin-project 0.4.27", "static_assertions", ] @@ -6300,13 +6747,24 @@ dependencies = [ ] [[package]] -name = "sc-authority-discovery" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +name = "salsa20" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f47b10fa80f6969bbbd9c8e7cc998f082979d402a9e10579e2303a87955395" dependencies = [ + "stream-cipher", +] + +[[package]] +name = "sc-authority-discovery" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" +dependencies = [ + "async-trait", "bytes 0.5.6", - "derive_more 0.99.10", - "futures 0.3.5", + "derive_more 0.99.11", + "either", + "futures 0.3.7", "futures-timer 3.0.2", "libp2p", "log 0.4.11", @@ -6322,16 +6780,17 @@ dependencies = [ "sp-authority-discovery", "sp-blockchain", "sp-core", + "sp-keystore", "sp-runtime", "substrate-prometheus-endpoint", ] [[package]] name = "sc-basic-authorship" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", "futures-timer 3.0.2", "log 0.4.11", "parity-scale-codec", @@ -6352,8 +6811,8 @@ dependencies = [ [[package]] name = "sc-block-builder" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -6369,52 +6828,58 @@ dependencies = [ [[package]] name = "sc-chain-spec" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "impl-trait-for-tuples", + "parity-scale-codec", "sc-chain-spec-derive", + "sc-consensus-babe", + "sc-consensus-epochs", + "sc-finality-grandpa", "sc-network", "sc-telemetry", "serde", "serde_json", "sp-chain-spec", + "sp-consensus-babe", "sp-core", "sp-runtime", ] [[package]] name = "sc-chain-spec-derive" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] name = "sc-cli" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "ansi_term 0.12.1", "atty", + "bip39", "chrono", - "derive_more 0.99.10", - "env_logger", "fdlimit", - "futures 0.3.5", - "lazy_static", + "futures 0.3.7", + "hex", + "libp2p", "log 0.4.11", "names", - "nix 0.17.0", - "parity-util-mem", + "parity-scale-codec", + "rand 0.7.3", "regex", "rpassword", + "sc-cli-proc-macro", "sc-client-api", - "sc-informant", + "sc-keystore", "sc-network", "sc-service", "sc-telemetry", @@ -6424,27 +6889,40 @@ dependencies = [ "sp-blockchain", "sp-core", "sp-keyring", + "sp-keystore", "sp-panic-handler", "sp-runtime", - "sp-state-machine", "sp-utils", "sp-version", "structopt", - "substrate-prometheus-endpoint", - "time", + "thiserror", "tokio 0.2.22", + "tracing", + "tracing-log", + "tracing-subscriber", +] + +[[package]] +name = "sc-cli-proc-macro" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" +dependencies = [ + "proc-macro-crate", + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn 1.0.48", ] [[package]] name = "sc-client-api" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "derive_more 0.99.10", + "derive_more 0.99.11", "fnv", - "futures 0.3.5", + "futures 0.3.7", "hash-db", - "hex-literal", + "hex-literal 0.3.1", "kvdb", "lazy_static", "log 0.4.11", @@ -6460,6 +6938,7 @@ dependencies = [ "sp-externalities", "sp-inherents", "sp-keyring", + "sp-keystore", "sp-runtime", "sp-state-machine", "sp-std", @@ -6473,8 +6952,8 @@ dependencies = [ [[package]] name = "sc-client-db" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "blake2-rfc", "hash-db", @@ -6503,8 +6982,8 @@ dependencies = [ [[package]] name = "sc-consensus" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "sc-client-api", "sp-blockchain", @@ -6514,18 +6993,18 @@ dependencies = [ [[package]] name = "sc-consensus-babe" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "derive_more 0.99.10", + "derive_more 0.99.11", "fork-tree", - "futures 0.3.5", + "futures 0.3.7", "futures-timer 3.0.2", "log 0.4.11", "merlin", "num-bigint", "num-rational", - "num-traits 0.2.12", + "num-traits 0.2.14", "parity-scale-codec", "parking_lot 0.10.2", "pdqselect", @@ -6549,6 +7028,7 @@ dependencies = [ "sp-core", "sp-inherents", "sp-io", + "sp-keystore", "sp-runtime", "sp-timestamp", "sp-utils", @@ -6558,17 +7038,16 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "derive_more 0.99.10", - "futures 0.3.5", + "derive_more 0.99.11", + "futures 0.3.7", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", "sc-consensus-babe", "sc-consensus-epochs", - "sc-keystore", "sc-rpc-api", "serde", "sp-api", @@ -6577,13 +7056,14 @@ dependencies = [ "sp-consensus", "sp-consensus-babe", "sp-core", + "sp-keystore", "sp-runtime", ] [[package]] name = "sc-consensus-epochs" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "fork-tree", "parity-scale-codec", @@ -6595,10 +7075,10 @@ dependencies = [ [[package]] name = "sc-consensus-slots" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", "futures-timer 3.0.2", "log 0.4.11", "parity-scale-codec", @@ -6614,12 +7094,13 @@ dependencies = [ "sp-inherents", "sp-runtime", "sp-state-machine", + "sp-trie", ] [[package]] name = "sc-consensus-uncles" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "log 0.4.11", "sc-client-api", @@ -6632,10 +7113,10 @@ dependencies = [ [[package]] name = "sc-executor" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "derive_more 0.99.10", + "derive_more 0.99.11", "lazy_static", "libsecp256k1", "log 0.4.11", @@ -6652,6 +7133,7 @@ dependencies = [ "sp-panic-handler", "sp-runtime-interface", "sp-serializer", + "sp-tasks", "sp-trie", "sp-version", "sp-wasm-interface", @@ -6660,10 +7142,10 @@ dependencies = [ [[package]] name = "sc-executor-common" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "derive_more 0.99.10", + "derive_more 0.99.11", "log 0.4.11", "parity-scale-codec", "parity-wasm", @@ -6677,8 +7159,8 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "log 0.4.11", "parity-scale-codec", @@ -6692,40 +7174,36 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "cranelift-codegen", - "cranelift-wasm", "log 0.4.11", "parity-scale-codec", "parity-wasm", + "pwasm-utils", "sc-executor-common", "scoped-tls", "sp-allocator", "sp-core", "sp-runtime-interface", "sp-wasm-interface", - "substrate-wasmtime", - "wasmtime-environ", - "wasmtime-runtime", + "wasmtime", ] [[package]] name = "sc-finality-grandpa" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "assert_matches", - "derive_more 0.99.10", + "derive_more 0.99.11", "finality-grandpa", "fork-tree", - "futures 0.3.5", + "futures 0.3.7", "futures-timer 3.0.2", "log 0.4.11", "parity-scale-codec", "parking_lot 0.10.2", - "pin-project", + "pin-project 0.4.27", "rand 0.7.3", "sc-block-builder", "sc-client-api", @@ -6742,8 +7220,8 @@ dependencies = [ "sp-consensus", "sp-core", "sp-finality-grandpa", - "sp-finality-tracker", "sp-inherents", + "sp-keystore", "sp-runtime", "sp-utils", "substrate-prometheus-endpoint", @@ -6751,28 +7229,35 @@ dependencies = [ [[package]] name = "sc-finality-grandpa-rpc" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "derive_more 0.99.10", + "derive_more 0.99.11", "finality-grandpa", - "futures 0.3.5", + "futures 0.3.7", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", + "jsonrpc-pubsub", "log 0.4.11", + "parity-scale-codec", + "sc-client-api", "sc-finality-grandpa", + "sc-rpc", "serde", "serde_json", + "sp-blockchain", + "sp-core", + "sp-runtime", ] [[package]] name = "sc-informant" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "ansi_term 0.12.1", - "futures 0.3.5", + "futures 0.3.7", "log 0.4.11", "parity-util-mem", "sc-client-api", @@ -6786,10 +7271,13 @@ dependencies = [ [[package]] name = "sc-keystore" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "derive_more 0.99.10", + "async-trait", + "derive_more 0.99.11", + "futures 0.3.7", + "futures-util", "hex", "merlin", "parking_lot 0.10.2", @@ -6797,13 +7285,14 @@ dependencies = [ "serde_json", "sp-application-crypto", "sp-core", + "sp-keystore", "subtle 2.3.0", ] [[package]] name = "sc-light" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "hash-db", "lazy_static", @@ -6821,18 +7310,20 @@ dependencies = [ [[package]] name = "sc-network" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ + "async-std", + "async-trait", "bitflags", "bs58", "bytes 0.5.6", - "derive_more 0.99.10", + "derive_more 0.99.11", "either", "erased-serde", "fnv", "fork-tree", - "futures 0.3.5", + "futures 0.3.7", "futures-timer 3.0.2", "futures_codec", "hex", @@ -6841,11 +7332,11 @@ dependencies = [ "linked-hash-map", "linked_hash_set", "log 0.4.11", - "lru", + "lru 0.4.3", "nohash-hasher", "parity-scale-codec", "parking_lot 0.10.2", - "pin-project", + "pin-project 0.4.27", "prost", "prost-build", "rand 0.7.3", @@ -6873,14 +7364,14 @@ dependencies = [ [[package]] name = "sc-network-gossip" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", "futures-timer 3.0.2", "libp2p", "log 0.4.11", - "lru", + "lru 0.4.3", "sc-network", "sp-runtime", "wasm-timer", @@ -6888,14 +7379,14 @@ dependencies = [ [[package]] name = "sc-offchain" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "bytes 0.5.6", "fnv", - "futures 0.3.5", + "futures 0.3.7", "futures-timer 3.0.2", - "hyper 0.13.8", + "hyper 0.13.9", "hyper-rustls", "log 0.4.11", "num_cpus", @@ -6915,10 +7406,10 @@ dependencies = [ [[package]] name = "sc-peerset" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", "libp2p", "log 0.4.11", "serde_json", @@ -6928,8 +7419,8 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "log 0.4.11", "substrate-prometheus-endpoint", @@ -6937,10 +7428,10 @@ dependencies = [ [[package]] name = "sc-rpc" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", "hash-db", "jsonrpc-core", "jsonrpc-pubsub", @@ -6957,6 +7448,7 @@ dependencies = [ "sp-blockchain", "sp-chain-spec", "sp-core", + "sp-keystore", "sp-offchain", "sp-rpc", "sp-runtime", @@ -6969,11 +7461,11 @@ dependencies = [ [[package]] name = "sc-rpc-api" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "derive_more 0.99.10", - "futures 0.3.5", + "derive_more 0.99.11", + "futures 0.3.7", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -6993,9 +7485,10 @@ dependencies = [ [[package]] name = "sc-rpc-server" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ + "futures 0.1.30", "jsonrpc-core", "jsonrpc-http-server", "jsonrpc-ipc-server", @@ -7005,29 +7498,29 @@ dependencies = [ "serde", "serde_json", "sp-runtime", + "substrate-prometheus-endpoint", ] [[package]] name = "sc-service" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "derive_more 0.99.10", + "derive_more 0.99.11", "directories", "exit-future 0.2.0", - "futures 0.1.29", - "futures 0.3.5", + "futures 0.1.30", + "futures 0.3.7", "futures-timer 3.0.2", "hash-db", + "jsonrpc-core", "jsonrpc-pubsub", "lazy_static", "log 0.4.11", - "netstat2", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.2", - "pin-project", - "procfs", + "pin-project 0.4.27", "rand 0.7.3", "sc-block-builder", "sc-chain-spec", @@ -7056,24 +7549,26 @@ dependencies = [ "sp-externalities", "sp-inherents", "sp-io", + "sp-keystore", "sp-runtime", "sp-session", "sp-state-machine", + "sp-tracing", "sp-transaction-pool", "sp-trie", "sp-utils", "sp-version", "substrate-prometheus-endpoint", - "sysinfo", "tempfile", "tracing", + "tracing-futures", "wasm-timer", ] [[package]] name = "sc-state-db" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "log 0.4.11", "parity-scale-codec", @@ -7085,16 +7580,35 @@ dependencies = [ ] [[package]] -name = "sc-telemetry" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +name = "sc-sync-state-rpc" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "futures 0.3.5", + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "sc-chain-spec", + "sc-client-api", + "sc-consensus-babe", + "sc-consensus-epochs", + "sc-finality-grandpa", + "sc-rpc-api", + "serde_json", + "sp-blockchain", + "sp-runtime", +] + +[[package]] +name = "sc-telemetry" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" +dependencies = [ + "futures 0.3.7", "futures-timer 3.0.2", "libp2p", "log 0.4.11", "parking_lot 0.10.2", - "pin-project", + "pin-project 0.4.27", "rand 0.7.3", "serde", "slog", @@ -7107,8 +7621,8 @@ dependencies = [ [[package]] name = "sc-tracing" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "erased-serde", "log 0.4.11", @@ -7119,16 +7633,18 @@ dependencies = [ "serde_json", "slog", "sp-tracing", + "tracing", "tracing-core", + "tracing-subscriber", ] [[package]] name = "sc-transaction-graph" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "derive_more 0.99.10", - "futures 0.3.5", + "derive_more 0.99.11", + "futures 0.3.7", "linked-hash-map", "log 0.4.11", "parity-util-mem", @@ -7145,11 +7661,11 @@ dependencies = [ [[package]] name = "sc-transaction-pool" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "derive_more 0.99.10", - "futures 0.3.5", + "derive_more 0.99.11", + "futures 0.3.7", "futures-diagnose", "intervalier", "log 0.4.11", @@ -7186,9 +7702,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" dependencies = [ "arrayref", - "arrayvec 0.5.1", + "arrayvec 0.5.2", "curve25519-dalek 2.1.0", - "getrandom", + "getrandom 0.1.15", "merlin", "rand 0.7.3", "rand_core 0.5.1", @@ -7217,22 +7733,22 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "scroll" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb2332cb595d33f7edd5700f4cbf94892e680c7f0ae56adab58a35190b66cb1" +checksum = "fda28d4b4830b807a8b43f7b0e6b5df875311b3e7621d84577188c175b6ec1ec" dependencies = [ "scroll_derive", ] [[package]] name = "scroll_derive" -version = "0.10.2" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e367622f934864ffa1c704ba2b82280aab856e3d8213c84c5720257eb34b15b9" +checksum = "b12bd20b94c7cdfda8c7ba9b92ad0d9a56e3fa018c25fca83b51aa664c9b4c0d" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] @@ -7294,29 +7810,29 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" +checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" +checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] name = "serde_json" -version = "1.0.57" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" +checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" dependencies = [ "itoa", "ryu", @@ -7337,12 +7853,12 @@ dependencies = [ [[package]] name = "sha-1" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "170a36ea86c864a3f16dd2687712dd6646f7019f301e57537c7f4dc9f5916770" +checksum = "ce3cdf1b5e620a498ee6f2a171885ac7e22f0e12089ec4b3d22b84921792507c" dependencies = [ "block-buffer 0.9.0", - "cfg-if", + "cfg-if 1.0.0", "cpuid-bool", "digest 0.9.0", "opaque-debug 0.3.0", @@ -7362,12 +7878,12 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" +checksum = "6e7aab86fe2149bad8c507606bdb3f4ef5e7b2380eb92350f56122cca72a42a8" dependencies = [ "block-buffer 0.9.0", - "cfg-if", + "cfg-if 1.0.0", "cpuid-bool", "digest 0.9.0", "opaque-debug 0.3.0", @@ -7385,19 +7901,29 @@ dependencies = [ "opaque-debug 0.3.0", ] +[[package]] +name = "sharded-slab" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4921be914e16899a80adefb821f8ddb7974e3f1250223575a44ed994882127" +dependencies = [ + "lazy_static", + "loom", +] + [[package]] name = "shared_memory" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf3ab0cdff84d6c66fc9e268010ea6508e58ee942575afb66f2cf194bb218bb4" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "enum_primitive", "libc", "log 0.4.11", "memrange", "nix 0.10.0", - "quick-error", + "quick-error 1.2.3", "rand 0.4.6", "shared_memory_derive", "theban_interval_tree", @@ -7423,11 +7949,10 @@ checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" [[package]] name = "signal-hook-registry" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e12110bc539e657a646068aaf5eb5b63af9d0c1f7b29c97113fad80e15f035" +checksum = "ce32ea0c6c56d5eacaeb814fbed9960547021d3edd010ded1425f180536b20ab" dependencies = [ - "arc-swap", "libc", ] @@ -7482,9 +8007,9 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a945ec7f7ce853e89ffa36be1e27dce9a43e82ff9093bf3461c30d5da74ed11b" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] @@ -7504,9 +8029,9 @@ checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" [[package]] name = "snow" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32bf8474159a95551661246cda4976e89356999e3cbfef36f493dacc3fae1e8e" +checksum = "795dd7aeeee24468e5a32661f6d27f7b5cbed802031b2d7640c7b10f8fb2dd50" dependencies = [ "aes-gcm", "blake2", @@ -7515,7 +8040,7 @@ dependencies = [ "rand_core 0.5.1", "ring", "rustc_version", - "sha2 0.9.1", + "sha2 0.9.2", "subtle 2.3.0", "x25519-dalek", ] @@ -7526,7 +8051,7 @@ version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1fa70dc5c8104ec096f4fe7ede7a221d35ae13dcd19ba1ad9a81d2cab9a1c44" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "redox_syscall", "winapi 0.3.9", @@ -7538,22 +8063,22 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5c71ed3d54db0a699f4948e1bb3e45b450fa31fe602621dee6680361d569c88" dependencies = [ - "base64", + "base64 0.12.3", "bytes 0.5.6", "flate2", - "futures 0.3.5", + "futures 0.3.7", "httparse", "log 0.4.11", "rand 0.7.3", - "sha-1 0.9.1", + "sha-1 0.9.2", ] [[package]] name = "sp-allocator" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "derive_more 0.99.10", + "derive_more 0.99.11", "log 0.4.11", "sp-core", "sp-std", @@ -7562,8 +8087,8 @@ dependencies = [ [[package]] name = "sp-api" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "hash-db", "parity-scale-codec", @@ -7577,20 +8102,20 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "blake2-rfc", "proc-macro-crate", - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] name = "sp-application-crypto" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "parity-scale-codec", "serde", @@ -7601,11 +8126,11 @@ dependencies = [ [[package]] name = "sp-arithmetic" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "integer-sqrt", - "num-traits 0.2.12", + "num-traits 0.2.14", "parity-scale-codec", "serde", "sp-debug-derive", @@ -7614,8 +8139,8 @@ dependencies = [ [[package]] name = "sp-authority-discovery" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "parity-scale-codec", "sp-api", @@ -7626,8 +8151,8 @@ dependencies = [ [[package]] name = "sp-authorship" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -7637,8 +8162,8 @@ dependencies = [ [[package]] name = "sp-block-builder" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "parity-scale-codec", "sp-api", @@ -7649,12 +8174,11 @@ dependencies = [ [[package]] name = "sp-blockchain" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "derive_more 0.99.10", "log 0.4.11", - "lru", + "lru 0.4.3", "parity-scale-codec", "parking_lot 0.10.2", "sp-block-builder", @@ -7662,12 +8186,13 @@ dependencies = [ "sp-database", "sp-runtime", "sp-state-machine", + "thiserror", ] [[package]] name = "sp-chain-spec" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "serde", "serde_json", @@ -7675,11 +8200,10 @@ dependencies = [ [[package]] name = "sp-consensus" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "derive_more 0.99.10", - "futures 0.3.5", + "futures 0.3.7", "futures-timer 3.0.2", "libp2p", "log 0.4.11", @@ -7696,13 +8220,14 @@ dependencies = [ "sp-utils", "sp-version", "substrate-prometheus-endpoint", + "thiserror", "wasm-timer", ] [[package]] name = "sp-consensus-aura" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#2e7292cd84121db8bcd2317c1ad70e348ee52f7a" dependencies = [ "parity-scale-codec", "sp-api", @@ -7715,8 +8240,8 @@ dependencies = [ [[package]] name = "sp-consensus-babe" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "merlin", "parity-scale-codec", @@ -7727,6 +8252,7 @@ dependencies = [ "sp-consensus-vrf", "sp-core", "sp-inherents", + "sp-keystore", "sp-runtime", "sp-std", "sp-timestamp", @@ -7734,8 +8260,8 @@ dependencies = [ [[package]] name = "sp-consensus-slots" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -7743,8 +8269,8 @@ dependencies = [ [[package]] name = "sp-consensus-vrf" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "parity-scale-codec", "schnorrkel", @@ -7755,25 +8281,24 @@ dependencies = [ [[package]] name = "sp-core" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "base58", "blake2-rfc", "byteorder", - "derive_more 0.99.10", "dyn-clonable", "ed25519-dalek", - "futures 0.3.5", + "futures 0.3.7", "hash-db", "hash256-std-hasher", "hex", - "impl-serde 0.3.1", + "impl-serde", "lazy_static", "libsecp256k1", "log 0.4.11", "merlin", - "num-traits 0.2.12", + "num-traits 0.2.14", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.2", @@ -7790,6 +8315,7 @@ dependencies = [ "sp-std", "sp-storage", "substrate-bip39", + "thiserror", "tiny-bip39", "tiny-keccak", "twox-hash", @@ -7799,8 +8325,8 @@ dependencies = [ [[package]] name = "sp-database" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "kvdb", "parking_lot 0.10.2", @@ -7808,18 +8334,18 @@ dependencies = [ [[package]] name = "sp-debug-derive" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] name = "sp-externalities" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "environmental", "parity-scale-codec", @@ -7829,8 +8355,8 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "finality-grandpa", "log 0.4.11", @@ -7839,38 +8365,29 @@ dependencies = [ "sp-api", "sp-application-crypto", "sp-core", + "sp-keystore", "sp-runtime", "sp-std", ] -[[package]] -name = "sp-finality-tracker" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" -dependencies = [ - "parity-scale-codec", - "sp-inherents", - "sp-std", -] - [[package]] name = "sp-inherents" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "derive_more 0.99.10", "parity-scale-codec", "parking_lot 0.10.2", "sp-core", "sp-std", + "thiserror", ] [[package]] name = "sp-io" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", "hash-db", "libsecp256k1", "log 0.4.11", @@ -7878,18 +8395,21 @@ dependencies = [ "parking_lot 0.10.2", "sp-core", "sp-externalities", + "sp-keystore", "sp-runtime-interface", "sp-state-machine", "sp-std", "sp-tracing", "sp-trie", "sp-wasm-interface", + "tracing", + "tracing-core", ] [[package]] name = "sp-keyring" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "lazy_static", "sp-core", @@ -7897,10 +8417,26 @@ dependencies = [ "strum", ] +[[package]] +name = "sp-keystore" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" +dependencies = [ + "async-trait", + "derive_more 0.99.11", + "futures 0.3.7", + "merlin", + "parity-scale-codec", + "parking_lot 0.10.2", + "schnorrkel", + "sp-core", + "sp-externalities", +] + [[package]] name = "sp-npos-elections" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "parity-scale-codec", "serde", @@ -7911,19 +8447,19 @@ dependencies = [ [[package]] name = "sp-npos-elections-compact" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] name = "sp-offchain" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "sp-api", "sp-core", @@ -7932,8 +8468,8 @@ dependencies = [ [[package]] name = "sp-panic-handler" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "backtrace", "log 0.4.11", @@ -7941,8 +8477,8 @@ dependencies = [ [[package]] name = "sp-rpc" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "serde", "sp-core", @@ -7950,8 +8486,8 @@ dependencies = [ [[package]] name = "sp-runtime" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "either", "hash256-std-hasher", @@ -7972,14 +8508,15 @@ dependencies = [ [[package]] name = "sp-runtime-interface" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "parity-scale-codec", "primitive-types", "sp-externalities", "sp-runtime-interface-proc-macro", "sp-std", + "sp-storage", "sp-tracing", "sp-wasm-interface", "static_assertions", @@ -7987,33 +8524,20 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "Inflector", "proc-macro-crate", - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", -] - -[[package]] -name = "sp-sandbox" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" -dependencies = [ - "parity-scale-codec", - "sp-core", - "sp-io", - "sp-std", - "sp-wasm-interface", - "wasmi", + "syn 1.0.48", ] [[package]] name = "sp-serializer" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "serde", "serde_json", @@ -8021,8 +8545,8 @@ dependencies = [ [[package]] name = "sp-session" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "parity-scale-codec", "sp-api", @@ -8034,8 +8558,8 @@ dependencies = [ [[package]] name = "sp-staking" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -8044,13 +8568,12 @@ dependencies = [ [[package]] name = "sp-state-machine" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "hash-db", - "itertools 0.9.0", "log 0.4.11", - "num-traits 0.2.12", + "num-traits 0.2.14", "parity-scale-codec", "parking_lot 0.10.2", "rand 0.7.3", @@ -8058,32 +8581,48 @@ dependencies = [ "sp-core", "sp-externalities", "sp-panic-handler", + "sp-std", "sp-trie", + "thiserror", "trie-db", "trie-root 0.16.0", ] [[package]] name = "sp-std" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" [[package]] name = "sp-storage" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "impl-serde 0.2.3", + "impl-serde", + "parity-scale-codec", "ref-cast", "serde", "sp-debug-derive", "sp-std", ] +[[package]] +name = "sp-tasks" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" +dependencies = [ + "log 0.4.11", + "sp-core", + "sp-externalities", + "sp-io", + "sp-runtime-interface", + "sp-std", +] + [[package]] name = "sp-test-primitives" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#2e7292cd84121db8bcd2317c1ad70e348ee52f7a" dependencies = [ "parity-scale-codec", "parity-util-mem", @@ -8095,8 +8634,8 @@ dependencies = [ [[package]] name = "sp-timestamp" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -8109,21 +8648,24 @@ dependencies = [ [[package]] name = "sp-tracing" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "log 0.4.11", - "rental", + "parity-scale-codec", + "sp-std", "tracing", + "tracing-core", + "tracing-subscriber", ] [[package]] name = "sp-transaction-pool" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "derive_more 0.99.10", - "futures 0.3.5", + "derive_more 0.99.11", + "futures 0.3.7", "log 0.4.11", "parity-scale-codec", "serde", @@ -8134,8 +8676,8 @@ dependencies = [ [[package]] name = "sp-trie" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "hash-db", "memory-db", @@ -8148,10 +8690,10 @@ dependencies = [ [[package]] name = "sp-utils" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", "futures-core", "futures-timer 3.0.2", "lazy_static", @@ -8160,10 +8702,10 @@ dependencies = [ [[package]] name = "sp-version" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "impl-serde 0.2.3", + "impl-serde", "parity-scale-codec", "serde", "sp-runtime", @@ -8172,8 +8714,8 @@ dependencies = [ [[package]] name = "sp-wasm-interface" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -8210,13 +8752,26 @@ dependencies = [ [[package]] name = "stream-cipher" -version = "0.4.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f8ed9974042b8c3672ff3030a69fcc03b74c47c3d1ecb7755e8a3626011e88" +checksum = "c80e15f898d8d8f25db24c253ea615cc14acf418ff307822995814e7d42cfa89" dependencies = [ + "block-cipher", "generic-array 0.14.4", ] +[[package]] +name = "streamunordered" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9394ee1338fee8370bee649f8a7170b3a56917903a0956467ad192dcf8699ca" +dependencies = [ + "futures-core", + "futures-sink", + "futures-util", + "slab", +] + [[package]] name = "string" version = "0.2.1" @@ -8234,9 +8789,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.18" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33f6461027d7f08a13715659b2948e1602c31a3756aeae9378bfe7518c72e82" +checksum = "126d630294ec449fae0b16f964e35bf3c74f940da9dca17ee9b905f7b3112eb8" dependencies = [ "clap", "lazy_static", @@ -8245,15 +8800,15 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92e775028122a4b3dd55d58f14fc5120289c69bee99df1d117ae30f84b225c9" +checksum = "65e51c492f9e23a220534971ff5afc14037289de430e3c83f9daf6a1b6ae91e8" dependencies = [ "heck", "proc-macro-error", - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] @@ -8272,9 +8827,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0054a7df764039a6cd8592b9de84be4bec368ff081d203a7d5371cbfa8e65c81" dependencies = [ "heck", - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] @@ -8292,19 +8847,19 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "platforms", ] [[package]] name = "substrate-frame-rpc-system" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "frame-system-rpc-runtime-api", - "futures 0.3.5", + "futures 0.3.7", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -8323,13 +8878,13 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ "async-std", - "derive_more 0.99.10", + "derive_more 0.99.11", "futures-util", - "hyper 0.13.8", + "hyper 0.13.9", "log 0.4.11", "prometheus", "tokio 0.2.22", @@ -8337,11 +8892,11 @@ dependencies = [ [[package]] name = "substrate-test-client" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#9ec43d880823e9ad082de7e3038ac9777613fa15" dependencies = [ - "futures 0.1.29", - "futures 0.3.5", + "futures 0.1.30", + "futures 0.3.7", "hash-db", "hex", "parity-scale-codec", @@ -8357,16 +8912,17 @@ dependencies = [ "sp-consensus", "sp-core", "sp-keyring", + "sp-keystore", "sp-runtime", "sp-state-machine", ] [[package]] name = "substrate-test-runtime" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#2e7292cd84121db8bcd2317c1ad70e348ee52f7a" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "frame-executive", "frame-support", "frame-system", @@ -8385,6 +8941,7 @@ dependencies = [ "sp-consensus-aura", "sp-consensus-babe", "sp-core", + "sp-externalities", "sp-finality-grandpa", "sp-inherents", "sp-io", @@ -8393,20 +8950,21 @@ dependencies = [ "sp-runtime", "sp-runtime-interface", "sp-session", + "sp-state-machine", "sp-std", "sp-transaction-pool", "sp-trie", "sp-version", - "substrate-wasm-builder-runner 1.0.6 (git+https://github.com/paritytech/substrate?branch=rococo-branch)", + "substrate-wasm-builder-runner 2.0.0 (git+https://github.com/paritytech/substrate)", "trie-db", ] [[package]] name = "substrate-test-runtime-client" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#2e7292cd84121db8bcd2317c1ad70e348ee52f7a" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", "parity-scale-codec", "sc-block-builder", "sc-client-api", @@ -8424,59 +8982,34 @@ dependencies = [ [[package]] name = "substrate-test-utils" -version = "2.0.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#2e7292cd84121db8bcd2317c1ad70e348ee52f7a" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", "substrate-test-utils-derive", "tokio 0.2.22", ] [[package]] name = "substrate-test-utils-derive" -version = "0.8.0-rc5" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "0.8.0" +source = "git+https://github.com/paritytech/substrate?branch=master#2e7292cd84121db8bcd2317c1ad70e348ee52f7a" dependencies = [ "proc-macro-crate", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] name = "substrate-wasm-builder-runner" -version = "1.0.6" -source = "git+https://github.com/paritytech/substrate?branch=rococo-branch#83544d41abcc0e3d3cbbd6aa510e04dc50863e5c" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54cab12167e32b38a62c5ea5825aa0874cde315f907a46aad2b05aa8ef3d862f" [[package]] name = "substrate-wasm-builder-runner" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2a965994514ab35d3893e9260245f2947fd1981cdd4fffd2c6e6d1a9ce02e6a" - -[[package]] -name = "substrate-wasmtime" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a69f5b3afef86e3e372529bf3fb1f7219b20287c4490e4cb4b4e91970f4f5" -dependencies = [ - "anyhow", - "backtrace", - "cfg-if", - "lazy_static", - "libc", - "log 0.4.11", - "region", - "rustc-demangle", - "smallvec 1.4.2", - "target-lexicon", - "wasmparser 0.59.0", - "wasmtime-environ", - "wasmtime-jit", - "wasmtime-profiling", - "wasmtime-runtime", - "wat", - "winapi 0.3.9", -] +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate?branch=master#2e7292cd84121db8bcd2317c1ad70e348ee52f7a" [[package]] name = "subtle" @@ -8490,17 +9023,6 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd" -[[package]] -name = "syn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -dependencies = [ - "quote 0.3.15", - "synom", - "unicode-xid 0.0.4", -] - [[package]] name = "syn" version = "0.15.44" @@ -8514,51 +9036,27 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.42" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c51d92969d209b54a98397e1b91c8ae82d8c87a7bb87df0b29aa2ad81454228" +checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", "unicode-xid 0.2.1", ] -[[package]] -name = "synom" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -dependencies = [ - "unicode-xid 0.0.4", -] - [[package]] name = "synstructure" version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", "unicode-xid 0.2.1", ] -[[package]] -name = "sysinfo" -version = "0.14.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2983daff11a197c7c406b130579bc362177aa54cf2cc1f34d6ac88fccaa6a5e1" -dependencies = [ - "cfg-if", - "doc-comment", - "libc", - "ntapi", - "once_cell", - "rayon", - "winapi 0.3.9", -] - [[package]] name = "take_mut" version = "0.2.2" @@ -8577,7 +9075,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "rand 0.7.3", "redox_syscall", @@ -8616,22 +9114,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" +checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" +checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] @@ -8671,7 +9169,7 @@ checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2" dependencies = [ "failure", "hmac", - "once_cell", + "once_cell 1.4.1", "pbkdf2", "rand 0.7.3", "rustc-hash", @@ -8701,7 +9199,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "mio", "num_cpus", "tokio-codec", @@ -8749,7 +9247,7 @@ checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" dependencies = [ "bytes 0.4.12", "either", - "futures 0.1.29", + "futures 0.1.30", ] [[package]] @@ -8759,7 +9257,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "tokio-io", ] @@ -8769,7 +9267,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", "tokio-executor 0.1.10", ] @@ -8779,8 +9277,8 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" dependencies = [ - "crossbeam-utils", - "futures 0.1.29", + "crossbeam-utils 0.7.2", + "futures 0.1.30", ] [[package]] @@ -8800,7 +9298,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "297a1206e0ca6302a0eed35b700d292b275256f596e2f3fea7729d5e629b6ff4" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", "tokio-io", "tokio-threadpool", ] @@ -8812,7 +9310,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "log 0.4.11", ] @@ -8822,9 +9320,9 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] @@ -8834,7 +9332,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d282d483052288b2308ba5ee795f5673b159c9bdf63c385a05609da782a5eae" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "mio", "mio-named-pipes", "tokio 0.1.22", @@ -8846,8 +9344,8 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" dependencies = [ - "crossbeam-utils", - "futures 0.1.29", + "crossbeam-utils 0.7.2", + "futures 0.1.30", "lazy_static", "log 0.4.11", "mio", @@ -8877,7 +9375,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", ] [[package]] @@ -8887,7 +9385,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" dependencies = [ "fnv", - "futures 0.1.29", + "futures 0.1.30", ] [[package]] @@ -8908,7 +9406,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "iovec", "mio", "tokio-io", @@ -8921,10 +9419,10 @@ version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df720b6581784c118f0eb4310796b12b1d242a7eb95f716a8367855325c25f89" dependencies = [ - "crossbeam-deque", + "crossbeam-deque 0.7.3", "crossbeam-queue", - "crossbeam-utils", - "futures 0.1.29", + "crossbeam-utils 0.7.2", + "futures 0.1.30", "lazy_static", "log 0.4.11", "num_cpus", @@ -8938,8 +9436,8 @@ version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" dependencies = [ - "crossbeam-utils", - "futures 0.1.29", + "crossbeam-utils 0.7.2", + "futures 0.1.30", "slab", "tokio-executor 0.1.10", ] @@ -8951,7 +9449,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "log 0.4.11", "mio", "tokio-codec", @@ -8966,7 +9464,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab57a4ac4111c8c9dbcf70779f6fc8bc35ae4b2454809febac840ad19bd7e4e0" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "iovec", "libc", "log 0.4.11", @@ -8993,9 +9491,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645" dependencies = [ "serde", ] @@ -9012,7 +9510,7 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0987850db3733619253fe60e17cb59b82d37c7e6c0236bb81e4d6b87c879f27" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "log 0.4.11", "pin-project-lite", "tracing-attributes", @@ -9025,9 +9523,9 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80e0ccfc3378da0cce270c946b676a376943f5cd16aeba64568e7939806f4ada" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", ] [[package]] @@ -9039,6 +9537,59 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "tracing-futures" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c" +dependencies = [ + "pin-project 0.4.27", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e0f8c7178e13481ff6765bd169b33e8d554c5d2bbede5e32c356194be02b9b9" +dependencies = [ + "lazy_static", + "log 0.4.11", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1fa8f0c8f4c594e4fc9debc1990deab13238077271ba84dd853d54902ee3401" +dependencies = [ + "ansi_term 0.12.1", + "chrono", + "lazy_static", + "matchers", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec 1.4.2", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + [[package]] name = "treeline" version = "0.1.0" @@ -9084,11 +9635,13 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "twox-hash" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" +checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59" dependencies = [ + "cfg-if 0.1.10", "rand 0.7.3", + "static_assertions", ] [[package]] @@ -9097,6 +9650,12 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + [[package]] name = "uint" version = "0.8.5" @@ -9148,12 +9707,6 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" -[[package]] -name = "unicode-xid" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" - [[package]] name = "unicode-xid" version = "0.1.0" @@ -9193,6 +9746,12 @@ name = "unsigned-varint" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fdeedbf205afadfe39ae559b75c3240f24e257d0ca27e85f85cb82aa19ac35" +dependencies = [ + "bytes 0.5.6", + "futures-io", + "futures-util", + "futures_codec", +] [[package]] name = "untrusted" @@ -9252,29 +9811,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -[[package]] -name = "wabt" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00bef93d5e6c81a293bccf107cf43aa47239382f455ba14869d36695d8963b9c" -dependencies = [ - "serde", - "serde_derive", - "serde_json", - "wabt-sys", -] - -[[package]] -name = "wabt-sys" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a4e043159f63e16986e713e9b5e1c06043df4848565bf672e27c523864c7791" -dependencies = [ - "cc", - "cmake", - "glob 0.2.11", -] - [[package]] name = "wait-timeout" version = "0.2.0" @@ -9296,7 +9832,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", "log 0.4.11", "try-lock", ] @@ -9329,7 +9865,7 @@ version = "0.2.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "wasm-bindgen-macro", ] @@ -9342,9 +9878,9 @@ dependencies = [ "bumpalo", "lazy_static", "log 0.4.11", - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", "wasm-bindgen-shared", ] @@ -9354,7 +9890,7 @@ version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7866cab0aa01de1edf8b5d7936938a7e397ee50ce24119aef3e1eaa3b6171da" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "js-sys", "wasm-bindgen", "web-sys", @@ -9376,9 +9912,9 @@ version = "0.2.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -9395,7 +9931,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", "js-sys", "parking_lot 0.11.0", "pin-utils", @@ -9413,7 +9949,7 @@ dependencies = [ "libc", "memory_units", "num-rational", - "num-traits 0.2.12", + "num-traits 0.2.14", "parity-wasm", "wasmi-validation", ] @@ -9439,6 +9975,31 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a950e6a618f62147fd514ff445b2a0b53120d382751960797f85f058c7eda9b9" +[[package]] +name = "wasmtime" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd3c4f449382779ef6e0a7c3ec6752ae614e20a42e4100000c3efdc973100e2" +dependencies = [ + "anyhow", + "backtrace", + "cfg-if 0.1.10", + "lazy_static", + "libc", + "log 0.4.11", + "region", + "rustc-demangle", + "smallvec 1.4.2", + "target-lexicon", + "wasmparser 0.59.0", + "wasmtime-environ", + "wasmtime-jit", + "wasmtime-profiling", + "wasmtime-runtime", + "wat", + "winapi 0.3.9", +] + [[package]] name = "wasmtime-debug" version = "0.19.0" @@ -9462,9 +10023,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08f85619a94ee4034bd5bb87fc3dcf71fd2237b81c840809da1201061eec9ab3" dependencies = [ "anyhow", - "base64", + "base64 0.12.3", "bincode", - "cfg-if", + "cfg-if 0.1.10", "cranelift-codegen", "cranelift-entity", "cranelift-frontend", @@ -9493,7 +10054,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e914c013c7a9f15f4e429d5431f2830fb8adb56e40567661b69c5ec1d645be23" dependencies = [ "anyhow", - "cfg-if", + "cfg-if 0.1.10", "cranelift-codegen", "cranelift-entity", "cranelift-frontend", @@ -9536,7 +10097,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e8d4d1af8dd5f7096cfcc89dd668d358e52980c38cce199643372ffd6590e27" dependencies = [ "anyhow", - "cfg-if", + "cfg-if 0.1.10", "gimli 0.21.0", "lazy_static", "libc", @@ -9556,7 +10117,7 @@ checksum = "3a25f140bbbaadb07c531cba99ce1a966dba216138dc1b2a0ddecec851a01a93" dependencies = [ "backtrace", "cc", - "cfg-if", + "cfg-if 0.1.10", "indexmap", "lazy_static", "libc", @@ -9571,18 +10132,18 @@ dependencies = [ [[package]] name = "wast" -version = "24.0.0" +version = "26.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff1e3bd3ad0b2ee7784add89c30dc96b89a54b43e5d6d95d774eda1863b3500" +checksum = "b3f174eed73e885ede6c8fcc3fbea8c3757afa521840676496cde56bb742ddab" dependencies = [ "leb128", ] [[package]] name = "wat" -version = "1.0.25" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c0bb2872ae453f98cec6ff1bf1a71cde1da6041fce8b0ac39d51eb033e9ec0" +checksum = "26b2dccbce4d0e14875091846e110a2369267b18ddd0d6423479b88dad914d71" dependencies = [ "wast", ] @@ -9609,42 +10170,32 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.18.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cd5736df7f12a964a5067a12c62fa38e1bd8080aff1f80bc29be7c80d19ab4" +checksum = "0f20dea7535251981a9670857150d571846545088359b28e4951d350bdaf179f" dependencies = [ "webpki", ] [[package]] -name = "webpki-roots" -version = "0.19.0" +name = "wepoll-sys" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8eff4b7516a57307f9349c64bf34caa34b940b66fed4b2fb3136cb7386e5739" -dependencies = [ - "webpki", -] - -[[package]] -name = "wepoll-sys-stjepang" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fdfbb03f290ca0b27922e8d48a0997b4ceea12df33269b9f75e713311eb178d" +checksum = "0fcb14dea929042224824779fbc82d9fab8d2e6d3cbc0ac404de8edf489e77ff" dependencies = [ "cc", ] [[package]] name = "westend-runtime" -version = "0.8.22" -source = "git+https://github.com/paritytech/polkadot?branch=rococo-branch#9d2324b24a8e616b67a96b862e048e75b0ec211b" +version = "0.8.26" +source = "git+https://github.com/paritytech/polkadot?branch=bkchr-adder-collator-integration-test#11347d4d050f9c405dea096d8de1ed388399bc1f" dependencies = [ "bitvec", "frame-executive", "frame-support", "frame-system", "frame-system-rpc-runtime-api", - "hex-literal", "log 0.3.9", "pallet-authority-discovery", "pallet-authorship", @@ -9653,7 +10204,6 @@ dependencies = [ "pallet-collective", "pallet-democracy", "pallet-elections-phragmen", - "pallet-finality-tracker", "pallet-grandpa", "pallet-identity", "pallet-im-online", @@ -9700,7 +10250,7 @@ dependencies = [ "sp-transaction-pool", "sp-version", "static_assertions", - "substrate-wasm-builder-runner 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-wasm-builder-runner 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -9755,24 +10305,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "ws" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51a2c47b5798ccc774ffb93ff536aec7c4275d722fd9c740c83cdd1af1f2d94" -dependencies = [ - "byteorder", - "bytes 0.4.12", - "httparse", - "log 0.4.11", - "mio", - "mio-extras", - "rand 0.7.3", - "sha-1 0.8.2", - "slab", - "url 2.1.1", -] - [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -9785,25 +10317,25 @@ dependencies = [ [[package]] name = "x25519-dalek" -version = "0.6.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637ff90c9540fa3073bb577e65033069e4bae7c79d49d74aa3ffdf5342a53217" +checksum = "bc614d95359fd7afc321b66d2107ede58b246b844cf5d8a0adcca413e439f088" dependencies = [ - "curve25519-dalek 2.1.0", + "curve25519-dalek 3.0.0", "rand_core 0.5.1", "zeroize", ] [[package]] name = "yamux" -version = "0.4.9" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053585b18bca1a3d00e4b5ef93e72d4f49a10005374c455db7177e27149c899d" +checksum = "9aeb8c4043cac71c3c299dff107171c220d179492350ea198e109a414981b83c" dependencies = [ - "futures 0.3.5", + "futures 0.3.7", "log 0.4.11", "nohash-hasher", - "parking_lot 0.10.2", + "parking_lot 0.11.0", "rand 0.7.3", "static_assertions", ] @@ -9823,9 +10355,9 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f369ddb18862aba61aa49bf31e74d29f0f162dec753063200e1dc084345d16" dependencies = [ - "proc-macro2 1.0.23", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.42", + "syn 1.0.48", "synstructure", ] @@ -9855,7 +10387,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b89249644df056b522696b1bb9e7c18c87e8ffa3e2f0dc3b0155875d6498f01b" dependencies = [ "cc", - "glob 0.3.0", + "glob", "itertools 0.9.0", "libc", ] diff --git a/Cargo.toml b/Cargo.toml index 031e9d6ab0..f82a96c47f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,14 +1,11 @@ [workspace] members = [ "consensus", - "message-broker", "network", "parachain-upgrade", "primitives", "rococo-parachains/", - "rococo-parachains/contracts-runtime", "rococo-parachains/pallets/parachain-info", - "rococo-parachains/pallets/token-dealer", "rococo-parachains/primitives", "rococo-parachains/runtime", "runtime", @@ -16,7 +13,6 @@ members = [ "test/runtime", "test/client", "test/service", - "upward-message", ] [profile.release] diff --git a/collator/Cargo.toml b/collator/Cargo.toml index 57de1261d2..958b60d9f0 100644 --- a/collator/Cargo.toml +++ b/collator/Cargo.toml @@ -6,21 +6,26 @@ edition = "2018" [dependencies] # Substrate dependencies -sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-api = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-cli = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } # Polkadot dependencies -polkadot-collator = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-validation = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } +polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test", features = [ "real-overseer" ] } +polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-validation = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-node-primitives = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-overseer = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-node-subsystem = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } # Cumulus dependencies cumulus-consensus = { path = "../consensus" } @@ -36,17 +41,17 @@ parking_lot = "0.9" [dev-dependencies] # Cumulus dependencies -test-runtime = { package = "cumulus-test-runtime", path = "../test/runtime" } -test-client = { package = "cumulus-test-client", path = "../test/client" } +cumulus-test-runtime = { path = "../test/runtime" } +cumulus-test-client = { path = "../test/client" } # Substrate dependencies -substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "master" } +substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "master" } # Polkadot dependencies -polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } +polkadot-node-subsystem-test-helpers = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } # Other dependencies env_logger = "0.7.1" diff --git a/collator/src/lib.rs b/collator/src/lib.rs index cbc7bf6776..b55f2ad434 100644 --- a/collator/src/lib.rs +++ b/collator/src/lib.rs @@ -16,24 +16,18 @@ //! Cumulus Collator implementation for Substrate. -use cumulus_network::{ - DelayedBlockAnnounceValidator, JustifiedBlockAnnounceValidator, WaitToAnnounce, -}; +use cumulus_network::WaitToAnnounce; use cumulus_primitives::{ - inherents::{ - DownwardMessagesType, DOWNWARD_MESSAGES_IDENTIFIER, - VALIDATION_FUNCTION_PARAMS_IDENTIFIER as VFP_IDENT, - }, - validation_function_params::ValidationFunctionParams, - HeadData, + inherents::{DownwardMessagesType, DOWNWARD_MESSAGES_IDENTIFIER, VALIDATION_DATA_IDENTIFIER}, + well_known_keys, ValidationData, }; use cumulus_runtime::ParachainBlockData; -use sc_client_api::{Backend as BackendT, BlockBackend, Finalizer, StateBackend, UsageProvider}; +use sc_client_api::{BlockBackend, Finalizer, StateBackend, UsageProvider}; use sp_blockchain::HeaderBackend; use sp_consensus::{ BlockImport, BlockImportParams, BlockOrigin, BlockStatus, Environment, Error as ConsensusError, - ForkChoiceStrategy, Proposal, Proposer, RecordProof, SyncOracle, + ForkChoiceStrategy, Proposal, Proposer, RecordProof, }; use sp_core::traits::SpawnNamed; use sp_inherents::{InherentData, InherentDataProviders}; @@ -41,73 +35,106 @@ use sp_runtime::{ generic::BlockId, traits::{BlakeTwo256, Block as BlockT, Header as HeaderT}, }; +use sp_state_machine::InspectState; -use polkadot_collator::{ - BuildParachainContext, Network as CollatorNetwork, ParachainContext, RuntimeApiCollection, -}; -use polkadot_primitives::v0::{ - self as parachain, Block as PBlock, BlockData, DownwardMessage, GlobalValidationData, - Hash as PHash, Id as ParaId, LocalValidationData, +use polkadot_node_primitives::{Collation, CollationGenerationConfig}; +use polkadot_node_subsystem::messages::{CollationGenerationMessage, CollatorProtocolMessage}; +use polkadot_overseer::OverseerHandler; +use polkadot_primitives::v1::{ + Block as PBlock, BlockData, CollatorPair, Hash as PHash, HeadData, Id as ParaId, PoV, + UpwardMessage, }; +use polkadot_service::RuntimeApiCollection; use codec::{Decode, Encode}; -use log::{debug, error, trace}; +use log::{debug, error, info, trace}; use futures::prelude::*; -use std::{marker::PhantomData, pin::Pin, sync::Arc, time::Duration}; +use std::{marker::PhantomData, sync::Arc, time::Duration}; use parking_lot::Mutex; +type TransactionFor = + <>::Proposer as Proposer>::Transaction; + /// The implementation of the Cumulus `Collator`. -pub struct Collator { +pub struct Collator { proposer_factory: Arc>, _phantom: PhantomData, inherent_data_providers: InherentDataProviders, - collator_network: Arc, block_import: Arc>, block_status: Arc, wait_to_announce: Arc>>, + backend: Arc, } -impl Collator { +impl Clone for Collator { + fn clone(&self) -> Self { + Self { + proposer_factory: self.proposer_factory.clone(), + inherent_data_providers: self.inherent_data_providers.clone(), + _phantom: PhantomData, + block_import: self.block_import.clone(), + block_status: self.block_status.clone(), + wait_to_announce: self.wait_to_announce.clone(), + backend: self.backend.clone(), + } + } +} + +impl Collator +where + Block: BlockT, + PF: Environment + 'static + Send, + PF::Proposer: Send, + BI: BlockImport< + Block, + Error = ConsensusError, + Transaction = >::Transaction, + > + Send + + Sync + + 'static, + BS: BlockBackend, + Backend: sc_client_api::Backend + 'static, +{ /// Create a new instance. fn new( proposer_factory: PF, inherent_data_providers: InherentDataProviders, - collator_network: impl CollatorNetwork + Clone + 'static, + overseer_handler: OverseerHandler, block_import: BI, block_status: Arc, spawner: Arc, announce_block: Arc) + Send + Sync>, + backend: Arc, ) -> Self { - let collator_network = Arc::new(collator_network); let wait_to_announce = Arc::new(Mutex::new(WaitToAnnounce::new( spawner, announce_block, - collator_network.clone(), + overseer_handler, ))); Self { proposer_factory: Arc::new(Mutex::new(proposer_factory)), inherent_data_providers, _phantom: PhantomData, - collator_network, block_import: Arc::new(Mutex::new(block_import)), block_status, wait_to_announce, + backend, } } /// Get the inherent data with validation function parameters injected fn inherent_data( - inherent_providers: InherentDataProviders, - global_validation: GlobalValidationData, - local_validation: LocalValidationData, + &mut self, + validation_data: &ValidationData, downward_messages: DownwardMessagesType, ) -> Option { - let mut inherent_data = inherent_providers + let mut inherent_data = self + .inherent_data_providers .create_inherent_data() .map_err(|e| { error!( @@ -119,10 +146,7 @@ impl Collator { .ok()?; inherent_data - .put_data( - VFP_IDENT, - &ValidationFunctionParams::from((global_validation, local_validation)), - ) + .put_data(VALIDATION_DATA_IDENTIFIER, validation_data) .map_err(|e| { error!( target: "cumulus-collator", @@ -145,36 +169,7 @@ impl Collator { Some(inherent_data) } -} -impl Clone for Collator { - fn clone(&self) -> Self { - Self { - proposer_factory: self.proposer_factory.clone(), - inherent_data_providers: self.inherent_data_providers.clone(), - _phantom: PhantomData, - collator_network: self.collator_network.clone(), - block_import: self.block_import.clone(), - block_status: self.block_status.clone(), - wait_to_announce: self.wait_to_announce.clone(), - } - } -} - -impl Collator -where - Block: BlockT, - PF: Environment + 'static + Send, - PF::Proposer: Send, - BI: BlockImport< - Block, - Error = ConsensusError, - Transaction = >::Transaction, - > + Send - + Sync - + 'static, - BS: BlockBackend, -{ /// Checks the status of the given block hash in the Parachain. /// /// Returns `true` if the block could be found and is good to be build on. @@ -215,197 +210,212 @@ where } } } -} -impl ParachainContext for Collator -where - Block: BlockT, - PF: Environment + 'static + Send, - PF::Proposer: Send, - BI: BlockImport< - Block, - Error = ConsensusError, - Transaction = >::Transaction, - > + Send - + Sync - + 'static, - BS: BlockBackend, -{ - type ProduceCandidate = - Pin> + Send>>; - - fn produce_candidate( + fn build_collation( &mut self, - relay_chain_parent: PHash, - global_validation: GlobalValidationData, - local_validation: LocalValidationData, - downward_messages: Vec, - ) -> Self::ProduceCandidate { - let factory = self.proposer_factory.clone(); - let inherent_providers = self.inherent_data_providers.clone(); - let block_import = self.block_import.clone(); + block: ParachainBlockData, + block_hash: Block::Hash, + ) -> Option { + let block_data = BlockData(block.encode()); + let header = block.into_header(); + let head_data = HeadData(header.encode()); - trace!(target: "cumulus-collator", "Producing candidate"); - - let last_head = match HeadData::::decode(&mut &local_validation.parent_head.0[..]) { - Ok(x) => x, + let state = match self.backend.state_at(BlockId::Hash(block_hash)) { + Ok(state) => state, Err(e) => { - error!(target: "cumulus-collator", "Could not decode the head data: {:?}", e); - return Box::pin(future::ready(None)); + error!(target: "cumulus-collator", "Failed to get state of the freshly built block: {:?}", e); + return None; } }; - if !self.check_block_status(last_head.header.hash()) { - return future::ready(None).boxed(); - } + state.inspect_state(|| { + let upward_messages = sp_io::storage::get(well_known_keys::UPWARD_MESSAGES); + let upward_messages = match upward_messages.map(|v| Vec::::decode(&mut &v[..])) { + Some(Ok(msgs)) => msgs, + Some(Err(e)) => { + error!(target: "cumulus-collator", "Failed to decode upward messages from the build block: {:?}", e); + return None + }, + None => Vec::new(), + }; - let proposer_future = factory.lock().init(&last_head.header); + let new_validation_code = sp_io::storage::get(well_known_keys::NEW_VALIDATION_CODE); - let wait_to_announce = self.wait_to_announce.clone(); + Some(Collation { + upward_messages, + new_validation_code: new_validation_code.map(Into::into), + head_data, + proof_of_validity: PoV { block_data }, + // TODO! + processed_downward_messages: 0, + }) + }) + } - Box::pin(async move { - let proposer = proposer_future - .await - .map_err(|e| { - error!( - target: "cumulus-collator", - "Could not create proposer: {:?}", - e, - ) - }) - .ok()?; - - let inherent_data = Self::inherent_data( - inherent_providers, - global_validation, - local_validation, - downward_messages, - )?; - - let Proposal { - block, - storage_changes, - proof, - } = proposer - .propose( - inherent_data, - Default::default(), - //TODO: Fix this. - Duration::from_millis(500), - RecordProof::Yes, - ) - .await - .map_err(|e| { - error!( - target: "cumulus-collator", - "Proposing failed: {:?}", - e, - ) - }) - .ok()?; - - let proof = match proof { - Some(proof) => proof, - None => { - error!( - target: "cumulus-collator", - "Proposer did not return the requested proof.", - ); + async fn produce_candidate( + mut self, + relay_parent: PHash, + validation_data: ValidationData, + ) -> Option { + trace!(target: "cumulus-collator", "Producing candidate"); + let last_head = + match Block::Header::decode(&mut &validation_data.persisted.parent_head.0[..]) { + Ok(x) => x, + Err(e) => { + error!(target: "cumulus-collator", "Could not decode the head data: {:?}", e); return None; } }; - let (header, extrinsics) = block.deconstruct(); + let last_head_hash = last_head.hash(); + if !self.check_block_status(last_head_hash) { + return None; + } - // Create the parachain block data for the validators. - let b = ParachainBlockData::::new(header.clone(), extrinsics, proof); + info!( + target: "cumulus-collator", + "Starting collation for relay parent `{}` on parent `{}`.", + relay_parent, + last_head_hash, + ); - let mut block_import_params = BlockImportParams::new(BlockOrigin::Own, header); - block_import_params.body = Some(b.extrinsics().to_vec()); - // Best block is determined by the relay chain. - block_import_params.fork_choice = Some(ForkChoiceStrategy::Custom(false)); - block_import_params.storage_changes = Some(storage_changes); + let proposer_future = self.proposer_factory.lock().init(&last_head); - if let Err(err) = block_import - .lock() - .import_block(block_import_params, Default::default()) - { + let proposer = proposer_future + .await + .map_err(|e| { error!( target: "cumulus-collator", - "Error importing build block (at {:?}): {:?}", - b.header().parent_hash(), - err, + "Could not create proposer: {:?}", + e, + ) + }) + .ok()?; + + let inherent_data = self.inherent_data( + &validation_data, + // TODO get the downward messages + Vec::new(), + )?; + + let Proposal { + block, + storage_changes, + proof, + } = proposer + .propose( + inherent_data, + Default::default(), + //TODO: Fix this. + Duration::from_millis(500), + RecordProof::Yes, + ) + .await + .map_err(|e| { + error!( + target: "cumulus-collator", + "Proposing failed: {:?}", + e, + ) + }) + .ok()?; + + let proof = match proof { + Some(proof) => proof, + None => { + error!( + target: "cumulus-collator", + "Proposer did not return the requested proof.", ); return None; } + }; - let block_data = BlockData(b.encode()); - let header = b.into_header(); - let encoded_header = header.encode(); - let hash = header.hash(); - let head_data = HeadData:: { header }; + let (header, extrinsics) = block.deconstruct(); + let block_hash = header.hash(); - let candidate = (block_data, parachain::HeadData(head_data.encode())); + // Create the parachain block data for the validators. + let b = ParachainBlockData::::new(header.clone(), extrinsics, proof); - wait_to_announce - .lock() - .wait_to_announce(hash, relay_chain_parent, encoded_header); + let mut block_import_params = BlockImportParams::new(BlockOrigin::Own, header); + block_import_params.body = Some(b.extrinsics().to_vec()); + // Best block is determined by the relay chain. + block_import_params.fork_choice = Some(ForkChoiceStrategy::Custom(false)); + block_import_params.storage_changes = Some(storage_changes); - trace!(target: "cumulus-collator", "Produced candidate: {:?}", candidate); + if let Err(err) = self + .block_import + .lock() + .import_block(block_import_params, Default::default()) + { + error!( + target: "cumulus-collator", + "Error importing build block (at {:?}): {:?}", + b.header().parent_hash(), + err, + ); - Some(candidate) - }) - } -} - -/// Implements `BuildParachainContext` to build a collator instance. -pub struct CollatorBuilder { - proposer_factory: PF, - inherent_data_providers: InherentDataProviders, - block_import: BI, - block_status: Arc, - para_id: ParaId, - client: Arc, - announce_block: Arc) + Send + Sync>, - delayed_block_announce_validator: DelayedBlockAnnounceValidator, - _marker: PhantomData<(Block, Backend)>, -} - -impl - CollatorBuilder -{ - /// Create a new instance of self. - pub fn new( - proposer_factory: PF, - inherent_data_providers: InherentDataProviders, - block_import: BI, - block_status: Arc, - para_id: ParaId, - client: Arc, - announce_block: Arc) + Send + Sync>, - delayed_block_announce_validator: DelayedBlockAnnounceValidator, - ) -> Self { - Self { - proposer_factory, - inherent_data_providers, - block_import, - block_status, - para_id, - client, - announce_block, - delayed_block_announce_validator, - _marker: PhantomData, + return None; } + + let collation = self.build_collation(b, block_hash)?; + let pov_hash = collation.proof_of_validity.hash(); + + self.wait_to_announce + .lock() + .wait_to_announce(block_hash, pov_hash); + + info!(target: "cumulus-collator", "Produced proof-of-validity candidate `{:?}` from block `{:?}`.", pov_hash, block_hash); + + Some(collation) } } -type TransactionFor = - <>::Proposer as Proposer>::Transaction; +/// Parameters for [`start_collator`]. +pub struct StartCollatorParams { + pub proposer_factory: PF, + pub inherent_data_providers: InherentDataProviders, + pub backend: Arc, + pub block_import: BI, + pub block_status: Arc, + pub client: Arc, + pub announce_block: Arc) + Send + Sync>, + pub overseer_handler: OverseerHandler, + pub spawner: Spawner, + pub para_id: ParaId, + pub key: CollatorPair, + pub polkadot_client: Arc, +} -impl BuildParachainContext - for CollatorBuilder +pub async fn start_collator< + Block: BlockT, + PF, + BI, + Backend, + Client, + BS, + Spawner, + PClient, + PBackend, + PApi, +>( + StartCollatorParams { + proposer_factory, + inherent_data_providers, + backend, + block_import, + block_status, + client, + announce_block, + mut overseer_handler, + spawner, + para_id, + key, + polkadot_client, + }: StartCollatorParams, +) -> Result<(), String> where PF: Environment + Send + 'static, BI: BlockImport> @@ -421,87 +431,79 @@ where + BlockBackend + 'static, for<'a> &'a Client: BlockImport, - BS: BlockBackend, + BS: BlockBackend + Send + Sync + 'static, + Spawner: SpawnNamed + Clone + Send + Sync + 'static, + PBackend: sc_client_api::Backend, + PBackend::State: StateBackend, + PApi: RuntimeApiCollection, + PClient: polkadot_service::AbstractClient + 'static, { - type ParachainContext = Collator; + let follow = match cumulus_consensus::follow_polkadot( + para_id, + client, + polkadot_client, + announce_block.clone(), + ) { + Ok(follow) => follow, + Err(e) => return Err(format!("Could not start following polkadot: {:?}", e)), + }; - fn build( - self, - polkadot_client: Arc, - spawner: Spawner, - polkadot_network: PNetwork, - ) -> Result - where - Spawner: SpawnNamed + Clone + Send + Sync + 'static, - PBackend: BackendT, - PBackend::State: StateBackend, - PClient: polkadot_service::AbstractClient + 'static, - PClient::Api: RuntimeApiCollection, - PNetwork: CollatorNetwork + SyncOracle + Clone + 'static, - { - let CollatorBuilder { - proposer_factory, - inherent_data_providers, - block_import, - block_status, - para_id, - client, - announce_block, - delayed_block_announce_validator, - _marker, - } = self; - delayed_block_announce_validator.set(Box::new(JustifiedBlockAnnounceValidator::new( - polkadot_client.clone(), - para_id, - Box::new(polkadot_network.clone()), - ))); + spawner.spawn("cumulus-follow-polkadot", follow.map(|_| ()).boxed()); - let follow = match cumulus_consensus::follow_polkadot( - para_id, - client, - polkadot_client, - announce_block.clone(), - ) { - Ok(follow) => follow, - Err(e) => { - return Err(error!("Could not start following polkadot: {:?}", e)); - } - }; + let collator = Collator::new( + proposer_factory, + inherent_data_providers, + overseer_handler.clone(), + block_import, + block_status, + Arc::new(spawner), + announce_block, + backend, + ); - spawner.spawn("cumulus-follow-polkadot", follow.map(|_| ()).boxed()); + let config = CollationGenerationConfig { + key, + para_id, + collator: Box::new(move |relay_parent, validation_data| { + let collator = collator.clone(); + collator + .produce_candidate(relay_parent, validation_data.clone()) + .boxed() + }), + }; - Ok(Collator::new( - proposer_factory, - inherent_data_providers, - polkadot_network, - block_import, - block_status, - Arc::new(spawner), - announce_block, - )) - } + overseer_handler + .send_msg(CollationGenerationMessage::Initialize(config)) + .await + .map_err(|e| format!("Failed to send `Initialize` message: {:?}", e))?; + + overseer_handler + .send_msg(CollatorProtocolMessage::CollateOn(para_id)) + .await + .map_err(|e| format!("Failed to send `CollateOn` message: {:?}", e)) } #[cfg(test)] mod tests { use super::*; - use std::time::Duration; + use std::{pin::Pin, time::Duration}; - use polkadot_collator::{collate, SignedStatement}; - use polkadot_primitives::v0::Id as ParaId; - - use sp_blockchain::Result as ClientResult; - use sp_core::testing::TaskExecutor; + use sc_block_builder::BlockBuilderProvider; + use sp_core::{testing::TaskExecutor, Pair}; use sp_inherents::InherentData; - use sp_keyring::Sr25519Keyring; - use sp_runtime::traits::{DigestFor, Header as HeaderT}; - use sp_state_machine::StorageProof; - use substrate_test_client::{NativeExecutor, WasmExecutionMethod::Interpreted}; + use sp_runtime::traits::DigestFor; - use test_client::{DefaultTestClientBuilderExt, TestClientBuilder, TestClientBuilderExt}; - use test_runtime::{Block, Header}; + use cumulus_test_client::{ + generate_block_inherents, Client, DefaultTestClientBuilderExt, NativeExecutor, + TestClientBuilder, TestClientBuilderExt, WasmExecutionMethod::Interpreted, + }; + use cumulus_test_runtime::{Block, Header}; - use futures::{future, Stream}; + use polkadot_node_subsystem::messages::CollationGenerationMessage; + use polkadot_node_subsystem_test_helpers::ForwardSubsystem; + use polkadot_overseer::{AllSubsystems, Overseer}; + + use futures::{channel::mpsc, executor::block_on, future}; #[derive(Debug)] struct Error; @@ -512,7 +514,7 @@ mod tests { } } - struct DummyFactory; + struct DummyFactory(Arc); impl Environment for DummyFactory { type Proposer = DummyProposer; @@ -521,150 +523,120 @@ mod tests { Box> + Send + Unpin + 'static>, >; - fn init(&mut self, _: &Header) -> Self::CreateProposer { - Box::pin(future::ready(Ok(DummyProposer))) + fn init(&mut self, header: &Header) -> Self::CreateProposer { + Box::pin(future::ready(Ok(DummyProposer { + client: self.0.clone(), + header: header.clone(), + }))) } } - struct DummyProposer; + struct DummyProposer { + client: Arc, + header: Header, + } impl Proposer for DummyProposer { type Error = Error; type Proposal = future::Ready, Error>>; - type Transaction = sc_client_api::TransactionFor; + type Transaction = sc_client_api::TransactionFor; fn propose( self, _: InherentData, digest: DigestFor, _: Duration, - _: RecordProof, + record_proof: RecordProof, ) -> Self::Proposal { - let header = Header::new( - 1337, - Default::default(), - Default::default(), - Default::default(), - digest, - ); + let block_id = BlockId::Hash(self.header.hash()); + let mut builder = self + .client + .new_block_at(&block_id, digest, record_proof.yes()) + .expect("Initializes new block"); + + generate_block_inherents(&*self.client, None) + .into_iter() + .for_each(|e| builder.push(e).expect("Pushes an inherent")); + + let (block, storage_changes, proof) = + builder.build().expect("Creates block").into_inner(); future::ready(Ok(Proposal { - block: Block::new(header, Vec::new()), - storage_changes: Default::default(), - proof: Some(StorageProof::empty()), + block, + storage_changes, + proof, })) } } - #[derive(Clone)] - struct DummyCollatorNetwork; - - impl CollatorNetwork for DummyCollatorNetwork { - fn checked_statements( - &self, - _: PHash, - ) -> Pin + Send>> { - unimplemented!("Not required in tests") - } - } - - impl SyncOracle for DummyCollatorNetwork { - fn is_major_syncing(&mut self) -> bool { - unimplemented!("Not required in tests") - } - - fn is_offline(&mut self) -> bool { - unimplemented!("Not required in tests") - } - } - - #[derive(Clone)] - struct DummyPolkadotClient; - - impl cumulus_consensus::PolkadotClient for DummyPolkadotClient { - type Error = Error; - type HeadStream = Box> + Send + Unpin>; - - fn new_best_heads(&self, _: ParaId) -> ClientResult { - unimplemented!("Not required in tests") - } - - fn finalized_heads(&self, _: ParaId) -> ClientResult { - unimplemented!("Not required in tests") - } - - fn parachain_head_at( - &self, - _: &BlockId, - _: ParaId, - ) -> ClientResult>> { - unimplemented!("Not required in tests") - } - } - #[test] fn collates_produces_a_block() { - let id = ParaId::from(100); let _ = env_logger::try_init(); + let spawner = TaskExecutor::new(); + let para_id = ParaId::from(100); let announce_block = |_, _| (); - let block_announce_validator = DelayedBlockAnnounceValidator::new(); - let client = Arc::new(TestClientBuilder::new().build()); - - let builder = CollatorBuilder::new( - DummyFactory, - InherentDataProviders::default(), - client.clone(), - client.clone(), - id, - client.clone(), - Arc::new(announce_block), - block_announce_validator, - ); - let context = builder - .build::<_, _, polkadot_service::FullBackend, _>( - Arc::new( - substrate_test_client::TestClientBuilder::<_, _, _, ()>::default() - .build_with_native_executor::( - Some(NativeExecutor::::new( - Interpreted, - None, - 1, - )), - ) - .0, - ), - spawner, - DummyCollatorNetwork, - ) - .expect("Creates parachain context"); - + let client_builder = TestClientBuilder::new(); + let backend = client_builder.backend(); + let client = Arc::new(client_builder.build()); let header = client.header(&BlockId::Number(0)).unwrap().unwrap(); - let collation = collate( - Default::default(), - id, - GlobalValidationData { - block_number: 0, - max_code_size: 0, - max_head_data_size: 0, - }, - LocalValidationData { - parent_head: parachain::HeadData(HeadData:: { header }.encode()), - balance: 10, - code_upgrade_allowed: None, - }, - Vec::new(), - context, - Arc::new(Sr25519Keyring::Alice.pair().into()), - ); + let (sub_tx, sub_rx) = mpsc::channel(64); - let collation = futures::executor::block_on(collation).unwrap(); + let all_subsystems = + AllSubsystems::<()>::dummy().replace_collation_generation(ForwardSubsystem(sub_tx)); + let (overseer, handler) = Overseer::new(Vec::new(), all_subsystems, None, spawner.clone()) + .expect("Creates overseer"); - let block_data = collation.pov.block_data; + spawner.spawn("overseer", overseer.run().then(|_| async { () }).boxed()); + + let collator_start = + start_collator::<_, _, _, _, _, _, _, _, polkadot_service::FullBackend, _>( + StartCollatorParams { + proposer_factory: DummyFactory(client.clone()), + inherent_data_providers: Default::default(), + backend, + block_import: client.clone(), + block_status: client.clone(), + client: client.clone(), + announce_block: Arc::new(announce_block), + overseer_handler: handler, + spawner, + para_id, + key: CollatorPair::generate().0, + polkadot_client: Arc::new( + substrate_test_client::TestClientBuilder::<_, _, _, ()>::default() + .build_with_native_executor::( + Some(NativeExecutor::::new( + Interpreted, + None, + 1, + )), + ) + .0, + ), + }, + ); + block_on(collator_start).expect("Should start collator"); + + let msg = block_on(sub_rx.into_future()) + .0 + .expect("message should be send by `start_collator` above."); + + let config = match msg { + CollationGenerationMessage::Initialize(config) => config, + }; + + let mut validation_data = ValidationData::default(); + validation_data.persisted.parent_head = header.encode().into(); + + let collation = block_on((config.collator)(Default::default(), &validation_data)) + .expect("Collation is build"); + + let block_data = collation.proof_of_validity.block_data; let block = Block::decode(&mut &block_data.0[..]).expect("Is a valid block"); - assert_eq!(1337, *block.header().number()); + assert_eq!(1, *block.header().number()); } } diff --git a/consensus/Cargo.toml b/consensus/Cargo.toml index 8205bb3314..32c7013213 100644 --- a/consensus/Cargo.toml +++ b/consensus/Cargo.toml @@ -7,19 +7,19 @@ edition = "2018" [dependencies] # substrate deps -sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-api = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "master" } # polkadot deps -polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-runtime = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } +polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-runtime = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } # other deps futures = { version = "0.3.1", features = ["compat"] } diff --git a/consensus/src/lib.rs b/consensus/src/lib.rs index a0d1603f86..8f06140c44 100644 --- a/consensus/src/lib.rs +++ b/consensus/src/lib.rs @@ -26,7 +26,9 @@ use sp_runtime::{ traits::{Block as BlockT, Header as HeaderT}, }; -use polkadot_primitives::v0::{Block as PBlock, Hash as PHash, Id as ParaId, ParachainHost}; +use polkadot_primitives::v1::{ + Block as PBlock, Hash as PHash, Id as ParaId, OccupiedCoreAssumption, ParachainHost, +}; use codec::Decode; use futures::{future, Future, FutureExt, Stream, StreamExt}; @@ -281,7 +283,7 @@ where para_id: ParaId, ) -> ClientResult>> { self.runtime_api() - .local_validation_data(at, para_id) + .persisted_validation_data(at, para_id, OccupiedCoreAssumption::TimedOut) .map(|s| s.map(|s| s.parent_head.0)) } } diff --git a/message-broker/Cargo.toml b/message-broker/Cargo.toml deleted file mode 100644 index 25771c7968..0000000000 --- a/message-broker/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -name = "cumulus-message-broker" -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2018" - -[dependencies] -# substrate deps -frame-support = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } -sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } - -# Other dependencies -codec = { package = "parity-scale-codec", version = "1.3.0", features = [ "derive" ], default-features = false } - -# Cumulus dependencies -cumulus-primitives = { path = "../primitives", default-features = false } -cumulus-upward-message = { path = "../upward-message", default-features = false } - -[features] -default = [ "std" ] -std = [ - "frame-support/std", - "frame-system/std", - "sp-inherents/std", - "sp-io/std", - "sp-std/std", - "sp-runtime/std", - "codec/std", - "cumulus-primitives/std", - "cumulus-upward-message/std", -] diff --git a/message-broker/src/lib.rs b/message-broker/src/lib.rs deleted file mode 100644 index f9e7a7c5f7..0000000000 --- a/message-broker/src/lib.rs +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Cumulus message broker pallet. -//! -//! This pallet provides support for handling downward, upward messages and -//! XMCP messages. - -#![cfg_attr(not(feature = "std"), no_std)] - -use codec::{Decode, Encode}; -use cumulus_primitives::{ - inherents::{DownwardMessagesType, DOWNWARD_MESSAGES_IDENTIFIER}, - well_known_keys, - xcmp::{RawXCMPMessage, XCMPMessageHandler, XCMPMessageSender}, - DownwardMessage, DownwardMessageHandler, GenericUpwardMessage, ParaId, UpwardMessageOrigin, - UpwardMessageSender, -}; -use cumulus_upward_message::XCMPMessage; -use frame_support::{ - decl_event, decl_module, storage, - traits::Get, - weights::{DispatchClass, Weight}, -}; -use frame_system::ensure_none; -use sp_inherents::{InherentData, InherentIdentifier, MakeFatalError, ProvideInherent}; -use sp_runtime::traits::Hash; -use sp_std::vec::Vec; - -/// Configuration trait of this pallet. -pub trait Trait: frame_system::Trait { - /// Event type used by the runtime. - type Event: From> + Into<::Event>; - - /// The downward message handlers that will be informed when a message is received. - type DownwardMessageHandlers: DownwardMessageHandler; - - /// The upward message type used by the Parachain runtime. - type UpwardMessage: codec::Codec + XCMPMessage; - - /// The XCMP message handlers that will be informed when a XCMP message is received. - type XCMPMessageHandlers: XCMPMessageHandler; - - /// The XCMP message type used by the Parachain runtime. - type XCMPMessage: codec::Codec; - - /// The Id of the parachain. - type ParachainId: Get; -} - -decl_event! { - pub enum Event where Hash = ::Hash { - /// An upward message was sent to the relay chain. - /// - /// The hash corresponds to the hash of the encoded upward message. - UpwardMessageSent(Hash), - } -} - -decl_module! { - pub struct Module for enum Call where origin: T::Origin { - /// Executes the given downward messages by calling the message handlers. - /// - /// The origin of this call needs to be `None` as this is an inherent. - #[weight = (10, DispatchClass::Mandatory)] - fn execute_downward_messages(origin, messages: Vec) { - ensure_none(origin)?; - - //TODO: max messages should not be hardcoded. It should be determined based on the - // weight used by the handlers. - let max_messages = 10; - messages.iter().take(max_messages).for_each(|msg| { - match msg { - DownwardMessage::XCMPMessage(msg) => { - if let Ok(msg) = RawXCMPMessage::decode(&mut &msg[..]) { - if let Ok(xcmp_msg) = T::XCMPMessage::decode(&mut &msg.data[..]) { - T::XCMPMessageHandlers::handle_xcmp_message(msg.from, &xcmp_msg); - } - } - }, - msg => T::DownwardMessageHandlers::handle_downward_message(msg), - } - }); - - let processed = sp_std::cmp::min(messages.len(), max_messages) as u32; - storage::unhashed::put(well_known_keys::PROCESSED_DOWNWARD_MESSAGES, &processed); - } - - fn on_initialize() -> Weight { - storage::unhashed::kill(well_known_keys::UPWARD_MESSAGES); - - T::DbWeight::get().writes(1) - } - - fn deposit_event() = default; - } -} - -impl UpwardMessageSender for Module { - fn send_upward_message(msg: &T::UpwardMessage, origin: UpwardMessageOrigin) -> Result<(), ()> { - //TODO: check fee schedule - let data = msg.encode(); - let data_hash = T::Hashing::hash(&data); - - let msg = GenericUpwardMessage { origin, data }; - sp_io::storage::append(well_known_keys::UPWARD_MESSAGES, msg.encode()); - - Self::deposit_event(RawEvent::UpwardMessageSent(data_hash)); - - Ok(()) - } -} - -impl XCMPMessageSender for Module { - fn send_xcmp_message(dest: ParaId, msg: &T::XCMPMessage) -> Result<(), ()> { - let message = RawXCMPMessage { - from: T::ParachainId::get(), - data: msg.encode(), - }; - - Self::send_upward_message( - &T::UpwardMessage::send_message(dest, message.encode()), - UpwardMessageOrigin::Parachain, - ) - } -} - -impl ProvideInherent for Module { - type Call = Call; - type Error = MakeFatalError<()>; - const INHERENT_IDENTIFIER: InherentIdentifier = DOWNWARD_MESSAGES_IDENTIFIER; - - fn create_inherent(data: &InherentData) -> Option { - data.get_data::(&DOWNWARD_MESSAGES_IDENTIFIER) - .expect("Downward messages inherent data failed to decode") - .map(|msgs| Call::execute_downward_messages(msgs)) - } -} diff --git a/network/Cargo.toml b/network/Cargo.toml index a4a8482c12..b6e2a25df5 100644 --- a/network/Cargo.toml +++ b/network/Cargo.toml @@ -7,18 +7,21 @@ edition = "2018" [dependencies] # substrate deps -sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-api = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" } # polkadot deps -polkadot-collator = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-statement-table = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-validation = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-network = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } +polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-statement-table = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-validation = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-overseer = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-node-primitives = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-node-subsystem = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } # cumulus deps cumulus-primitives = { path = "../primitives" } @@ -33,9 +36,7 @@ parking_lot = "0.10.2" cumulus-test-runtime = { path = "../test/runtime" } # substrate deps -sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } - -# polkadot deps -polkadot-test-runtime-client = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/network/src/lib.rs b/network/src/lib.rs index ec057c87bd..c032dbbf43 100644 --- a/network/src/lib.rs +++ b/network/src/lib.rs @@ -14,9 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! Cumulus-specific network implementation. +//! Parachain specific networking //! -//! Contains message send between collators and logic to process them. +//! Provides a custom block announcement implementation for parachains +//! that use the relay chain provided consensus. See [`BlockAnnounceValidator`] +//! and [`WaitToAnnounce`] for more information about this implementation. #[cfg(test)] mod tests; @@ -24,7 +26,7 @@ mod tests; use sp_api::ProvideRuntimeApi; use sp_blockchain::{Error as ClientError, HeaderBackend}; use sp_consensus::{ - block_validation::{BlockAnnounceValidator, Validation}, + block_validation::{BlockAnnounceValidator as BlockAnnounceValidatorT, Validation}, SyncOracle, }; use sp_core::traits::SpawnNamed; @@ -33,35 +35,60 @@ use sp_runtime::{ traits::{Block as BlockT, Header as HeaderT}, }; -use polkadot_collator::Network as CollatorNetwork; -use polkadot_network::legacy::gossip::{GossipMessage, GossipStatement}; -use polkadot_primitives::v0::{Block as PBlock, Hash as PHash, Id as ParaId, ParachainHost}; -use polkadot_statement_table::v0::{SignedStatement, Statement}; -use polkadot_validation::check_statement; - -use cumulus_primitives::HeadData; +use polkadot_node_primitives::{SignedFullStatement, Statement}; +use polkadot_node_subsystem::messages::StatementDistributionMessage; +use polkadot_overseer::OverseerHandler; +use polkadot_primitives::v1::{ + Block as PBlock, Hash as PHash, Id as ParaId, OccupiedCoreAssumption, ParachainHost, + SigningContext, +}; +use polkadot_service::ClientHandle; use codec::{Decode, Encode}; -use futures::{channel::oneshot, future::FutureExt, pin_mut, select, StreamExt}; -use log::trace; +use futures::{ + channel::{mpsc, oneshot}, + future::{ready, FutureExt}, + pin_mut, select, Future, StreamExt, +}; +use log::{trace, warn}; -use parking_lot::Mutex; -use std::{marker::PhantomData, sync::Arc}; +use std::{marker::PhantomData, pin::Pin, sync::Arc}; -/// Validate that data is a valid justification from a relay-chain validator that the block is a -/// valid parachain-block candidate. -/// Data encoding is just `GossipMessage`, the relay-chain validator candidate statement message is -/// the justification. +/// Parachain specific block announce validator. /// -/// Note: if no justification is provided the annouce is considered valid. -pub struct JustifiedBlockAnnounceValidator { +/// This block announce validator is required if the parachain is running +/// with the relay chain provided consensus to make sure each node only +/// imports a reasonable number of blocks per round. The relay chain provided +/// consensus doesn't have any authorities and so it could happen that without +/// this special block announce validator a node would need to import *millions* +/// of blocks per round, which is clearly not doable. +/// +/// To solve this problem, each block announcement is delayed until a collator +/// has received a [`Statement::Seconded`] for its `PoV`. This message tells the +/// collator that its `PoV` was validated successfully by a parachain validator and +/// that it is very likely that this `PoV` will be included in the relay chain. Every +/// collator that doesn't receive the message for its `PoV` will not announce its block. +/// For more information on the block announcement, see [`WaitToAnnounce`]. +/// +/// For each block announcement that is received, the generic block announcement validation +/// will call this validator and provides the extra data that was attached to the announcement. +/// We call this extra data `justification`. +/// It is expected that the attached data is a SCALE encoded [`SignedFullStatement`]. The +/// statement is checked to be a [`Statement::Seconded`] and that it is signed by an active +/// parachain validator. +/// +/// If no justification was provided we check if the block announcement is at the tip of the known +/// chain. If it is at the tip, it is required to provide a justification or otherwise we reject +/// it. However, if the announcement is for a block below the tip the announcement is accepted +/// as it probably comes from a node that is currently syncing the chain. +pub struct BlockAnnounceValidator { phantom: PhantomData, polkadot_client: Arc

, para_id: ParaId, polkadot_sync_oracle: Box, } -impl JustifiedBlockAnnounceValidator { +impl BlockAnnounceValidator { pub fn new( polkadot_client: Arc

, para_id: ParaId, @@ -76,192 +103,239 @@ impl JustifiedBlockAnnounceValidator { } } -impl BlockAnnounceValidator for JustifiedBlockAnnounceValidator +impl BlockAnnounceValidatorT for BlockAnnounceValidator where - P: ProvideRuntimeApi + HeaderBackend, + P: ProvideRuntimeApi + HeaderBackend + 'static, P::Api: ParachainHost, { fn validate( &mut self, header: &B::Header, mut data: &[u8], - ) -> Result> { + ) -> Pin>> + Send>> + { if self.polkadot_sync_oracle.is_major_syncing() { - return Ok(Validation::Success { is_new_best: false }); + return ready(Ok(Validation::Success { is_new_best: false })).boxed(); } let runtime_api = self.polkadot_client.runtime_api(); let polkadot_info = self.polkadot_client.info(); if data.is_empty() { - // Check if block is equal or higher than best (this requires a justification) - let runtime_api_block_id = BlockId::Hash(polkadot_info.best_hash); - let block_number = header.number(); + let polkadot_client = self.polkadot_client.clone(); + let header = header.clone(); + let para_id = self.para_id; - let local_validation_data = runtime_api - .local_validation_data(&runtime_api_block_id, self.para_id) - .map_err(|e| Box::new(ClientError::Msg(format!("{:?}", e))) as Box<_>)? - .ok_or_else(|| { - Box::new(ClientError::Msg( - "Could not find parachain head in relay chain".into(), - )) as Box<_> - })?; - let parent_head = HeadData::::decode(&mut &local_validation_data.parent_head.0[..]) - .map_err(|e| { - Box::new(ClientError::Msg(format!( - "Failed to decode parachain head: {:?}", - e - ))) as Box<_> - })?; - let known_best_number = parent_head.header.number(); + return async move { + // Check if block is equal or higher than best (this requires a justification) + let runtime_api_block_id = BlockId::Hash(polkadot_info.best_hash); + let block_number = header.number(); - return Ok(if block_number >= known_best_number { - trace!( - target: "cumulus-network", - "validation failed because a justification is needed if the block at the top of the chain." - ); + let local_validation_data = polkadot_client + .runtime_api() + .persisted_validation_data( + &runtime_api_block_id, + para_id, + OccupiedCoreAssumption::TimedOut, + ) + .map_err(|e| Box::new(ClientError::Msg(format!("{:?}", e))) as Box<_>)? + .ok_or_else(|| { + Box::new(ClientError::Msg( + "Could not find parachain head in relay chain".into(), + )) as Box<_> + })?; + let parent_head = B::Header::decode(&mut &local_validation_data.parent_head.0[..]) + .map_err(|e| { + Box::new(ClientError::Msg(format!( + "Failed to decode parachain head: {:?}", + e + ))) as Box<_> + })?; + let known_best_number = parent_head.number(); - Validation::Failure - } else { - Validation::Success { is_new_best: false } - }); + if block_number >= known_best_number { + trace!( + target: "cumulus-network", + "validation failed because a justification is needed if the block at the top of the chain." + ); + + Ok(Validation::Failure) + } else { + Ok(Validation::Success { is_new_best: false }) + } + } + .boxed(); } - // Check data is a gossip message. - let gossip_message = GossipMessage::decode(&mut data).map_err(|_| { - Box::new(ClientError::BadJustification( - "cannot decode block announced justification, must be a gossip message".to_string(), - )) as Box<_> - })?; + let signed_stmt = match SignedFullStatement::decode(&mut data) { + Ok(r) => r, + Err(_) => return ready(Err(Box::new(ClientError::BadJustification( + "cannot decode block announcement justification, must be a `SignedFullStatement`" + .to_string(), + )) as Box<_>)) + .boxed(), + }; - // Check message is a gossip statement. - let gossip_statement = match gossip_message { - GossipMessage::Statement(gossip_statement) => gossip_statement, + // Check statement is a candidate statement. + let candidate_receipt = match signed_stmt.payload() { + Statement::Seconded(ref candidate_receipt) => candidate_receipt, _ => { - return Err(Box::new(ClientError::BadJustification( - "block announced justification statement must be a gossip statement" - .to_string(), - )) as Box<_>) + return ready(Err(Box::new(ClientError::BadJustification( + "block announcement justification must be a `Statement::Seconded`".to_string(), + )) as Box<_>)) + .boxed() } }; - let GossipStatement { - relay_chain_leaf, - signed_statement: SignedStatement { - statement, - signature, - sender, - }, - } = gossip_statement; - // Check that the relay chain parent of the block is the relay chain head let best_number = polkadot_info.best_number; + let validator_index = signed_stmt.validator_index(); + let relay_parent = &candidate_receipt.descriptor.relay_parent; - match self.polkadot_client.number(relay_chain_leaf) { + match self.polkadot_client.number(*relay_parent) { Err(err) => { - return Err(Box::new(ClientError::Backend(format!( + return ready(Err(Box::new(ClientError::Backend(format!( "could not find block number for {}: {}", - relay_chain_leaf, err, - )))); + relay_parent, err, + ))) as Box<_>)) + .boxed(); } Ok(Some(x)) if x == best_number => {} Ok(None) => { - return Err(Box::new(ClientError::UnknownBlock( - relay_chain_leaf.to_string(), - ))); + return ready(Err( + Box::new(ClientError::UnknownBlock(relay_parent.to_string())) as Box<_>, + )) + .boxed(); } Ok(Some(_)) => { trace!( target: "cumulus-network", "validation failed because the relay chain parent ({}) is not the relay chain \ head ({})", - relay_chain_leaf, best_number, + relay_parent, + best_number, ); - return Ok(Validation::Failure); + return ready(Ok(Validation::Failure)).boxed(); } } - let runtime_api_block_id = BlockId::Hash(relay_chain_leaf); - let signing_context = runtime_api - .signing_context(&runtime_api_block_id) - .map_err(|e| Box::new(ClientError::Msg(format!("{:?}", e))) as Box<_>)?; - - // Check that the signer is a legit validator. - let authorities = runtime_api - .validators(&runtime_api_block_id) - .map_err(|e| Box::new(ClientError::Msg(format!("{:?}", e))) as Box<_>)?; - let signer = authorities.get(sender as usize).ok_or_else(|| { - Box::new(ClientError::BadJustification( - "block accounced justification signer is a validator index out of bound" - .to_string(), - )) as Box<_> - })?; - - // Check statement is correctly signed. - if !check_statement(&statement, &signature, signer.clone(), &signing_context) { - return Err(Box::new(ClientError::BadJustification( - "block announced justification signature is invalid".to_string(), - )) as Box<_>); - } - - // Check statement is a candidate statement. - let candidate_receipt = match statement { - Statement::Candidate(candidate_receipt) => candidate_receipt, - _ => { - return Err(Box::new(ClientError::BadJustification( - "block announced justification statement must be a candidate statement" - .to_string(), - )) as Box<_>) + let runtime_api_block_id = BlockId::Hash(*relay_parent); + let session_index = match runtime_api.session_index_for_child(&runtime_api_block_id) { + Ok(r) => r, + Err(e) => { + return ready(Err(Box::new(ClientError::Msg(format!("{:?}", e))) as Box<_>)).boxed() } }; - // Check the header in the candidate_receipt match header given header. - if header.encode() != candidate_receipt.head_data.0 { - return Err(Box::new(ClientError::BadJustification( - "block announced header does not match the one justified".to_string(), - )) as Box<_>); - } + let signing_context = SigningContext { + parent_hash: *relay_parent, + session_index, + }; - Ok(Validation::Success { is_new_best: true }) - } -} - -/// A `BlockAnnounceValidator` that will be able to validate data when its internal -/// `BlockAnnounceValidator` is set. -pub struct DelayedBlockAnnounceValidator( - Arc + Send>>>>, -); - -impl DelayedBlockAnnounceValidator { - pub fn new() -> DelayedBlockAnnounceValidator { - DelayedBlockAnnounceValidator(Arc::new(Mutex::new(None))) - } - - pub fn set(&self, validator: Box + Send>) { - *self.0.lock() = Some(validator); - } -} - -impl Clone for DelayedBlockAnnounceValidator { - fn clone(&self) -> DelayedBlockAnnounceValidator { - DelayedBlockAnnounceValidator(self.0.clone()) - } -} - -impl BlockAnnounceValidator for DelayedBlockAnnounceValidator { - fn validate( - &mut self, - header: &B::Header, - data: &[u8], - ) -> Result> { - match self.0.lock().as_mut() { - Some(validator) => validator.validate(header, data), - None => { - log::warn!("BlockAnnounce validator not yet set, rejecting block announcement"); - Ok(Validation::Failure) + // Check that the signer is a legit validator. + let authorities = match runtime_api.validators(&runtime_api_block_id) { + Ok(r) => r, + Err(e) => { + return ready(Err(Box::new(ClientError::Msg(format!("{:?}", e))) as Box<_>)).boxed() } + }; + let signer = match authorities.get(validator_index as usize) { + Some(r) => r, + None => { + return ready(Err(Box::new(ClientError::BadJustification( + "block accouncement justification signer is a validator index out of bound" + .to_string(), + )) as Box<_>)) + .boxed() + } + }; + + // Check statement is correctly signed. + if signed_stmt + .check_signature(&signing_context, &signer) + .is_err() + { + return ready(Err(Box::new(ClientError::BadJustification( + "block announced justification signature is invalid".to_string(), + )) as Box<_>)) + .boxed(); } + + // Check the header in the candidate_receipt match header given header. + if header.encode() != candidate_receipt.commitments.head_data.0 { + return ready(Err(Box::new(ClientError::BadJustification( + "block announced header does not match the one justified".to_string(), + )) as Box<_>)) + .boxed(); + } + + ready(Ok(Validation::Success { is_new_best: true })).boxed() + } +} + +/// Build a block announce validator instance. +/// +/// Returns a boxed [`BlockAnnounceValidator`]. +pub fn build_block_announce_validator( + polkadot_client: polkadot_service::Client, + para_id: ParaId, + polkadot_sync_oracle: Box, +) -> Box + Send> { + BlockAnnounceValidatorBuilder::new(polkadot_client, para_id, polkadot_sync_oracle).build() +} + +/// Block announce validator builder. +/// +/// Builds a [`BlockAnnounceValidator`] for a parachain. As this requires +/// a concrete Polkadot client instance, the builder takes a [`polkadot_service::Client`] +/// that wraps this concrete instanace. By using [`polkadot_service::ExecuteWithClient`] +/// the builder gets access to this concrete instance. +struct BlockAnnounceValidatorBuilder { + phantom: PhantomData, + polkadot_client: polkadot_service::Client, + para_id: ParaId, + polkadot_sync_oracle: Box, +} + +impl BlockAnnounceValidatorBuilder { + /// Create a new instance of the builder. + fn new( + polkadot_client: polkadot_service::Client, + para_id: ParaId, + polkadot_sync_oracle: Box, + ) -> Self { + Self { + polkadot_client, + para_id, + polkadot_sync_oracle, + phantom: PhantomData, + } + } + + /// Build the block announce validator. + fn build(self) -> Box + Send> { + self.polkadot_client.clone().execute_with(self) + } +} + +impl polkadot_service::ExecuteWithClient for BlockAnnounceValidatorBuilder { + type Output = Box + Send>; + + fn execute_with_client(self, client: Arc) -> Self::Output + where + >::StateBackend: + sp_api::StateBackend, + PBackend: sc_client_api::Backend, + PBackend::State: sp_api::StateBackend, + Api: polkadot_service::RuntimeApiCollection, + PClient: polkadot_service::AbstractClient + 'static, + { + Box::new(BlockAnnounceValidator::new( + client, + self.para_id, + self.polkadot_sync_oracle, + )) } } @@ -273,7 +347,7 @@ impl BlockAnnounceValidator for DelayedBlockAnnounceValidator { pub struct WaitToAnnounce { spawner: Arc, announce_block: Arc) + Send + Sync>, - collator_network: Arc, + overseer_handler: OverseerHandler, current_trigger: oneshot::Sender<()>, } @@ -282,29 +356,24 @@ impl WaitToAnnounce { pub fn new( spawner: Arc, announce_block: Arc) + Send + Sync>, - collator_network: Arc, + overseer_handler: OverseerHandler, ) -> WaitToAnnounce { let (tx, _rx) = oneshot::channel(); WaitToAnnounce { spawner, announce_block, - collator_network, + overseer_handler, current_trigger: tx, } } /// Wait for a candidate message for the block, then announce the block. The candidate /// message will be added as justification to the block announcement. - pub fn wait_to_announce( - &mut self, - hash: ::Hash, - relay_chain_leaf: PHash, - head_data: Vec, - ) { + pub fn wait_to_announce(&mut self, block_hash: ::Hash, pov_hash: PHash) { let (tx, rx) = oneshot::channel(); let announce_block = self.announce_block.clone(); - let collator_network = self.collator_network.clone(); + let overseer_handler = self.overseer_handler.clone(); self.current_trigger = tx; @@ -312,11 +381,10 @@ impl WaitToAnnounce { "cumulus-wait-to-announce", async move { let t1 = wait_to_announce::( - hash, - relay_chain_leaf, + block_hash, + pov_hash, announce_block, - collator_network, - &head_data, + overseer_handler, ) .fuse(); let t2 = rx.fuse(); @@ -349,24 +417,30 @@ impl WaitToAnnounce { } async fn wait_to_announce( - hash: ::Hash, - relay_chain_leaf: PHash, + block_hash: ::Hash, + pov_hash: PHash, announce_block: Arc) + Send + Sync>, - collator_network: Arc, - head_data: &Vec, + mut overseer_handler: OverseerHandler, ) { - let mut checked_statements = collator_network.checked_statements(relay_chain_leaf); + let (sender, mut receiver) = mpsc::channel(5); + if overseer_handler + .send_msg(StatementDistributionMessage::RegisterStatementListener( + sender, + )) + .await + .is_err() + { + warn!( + target: "cumulus-network", + "Failed to register the statement listener!", + ); + return; + } - while let Some(statement) = checked_statements.next().await { - match &statement.statement { - Statement::Candidate(c) if &c.head_data.0 == head_data => { - let gossip_message: GossipMessage = GossipStatement { - relay_chain_leaf, - signed_statement: statement, - } - .into(); - - announce_block(hash, gossip_message.encode()); + while let Some(statement) = receiver.next().await { + match &statement.payload() { + Statement::Seconded(c) if &c.descriptor.pov_hash == &pov_hash => { + announce_block(block_hash, statement.encode()); break; } diff --git a/network/src/tests.rs b/network/src/tests.rs index ed84ea1397..7e31894a42 100644 --- a/network/src/tests.rs +++ b/network/src/tests.rs @@ -16,21 +16,25 @@ use super::*; use cumulus_test_runtime::{Block, Header}; -use polkadot_primitives::v0::{ - AbridgedCandidateReceipt, Block as PBlock, Chain, CollatorId, DutyRoster, GlobalValidationData, - Hash as PHash, Header as PHeader, Id as ParaId, LocalValidationData, ParachainHost, Retriable, - SigningContext, ValidationCode, ValidatorId, +use futures::executor::block_on; +use polkadot_node_primitives::{SignedFullStatement, Statement}; +use polkadot_primitives::v1::{ + AuthorityDiscoveryId, Block as PBlock, BlockNumber, CandidateCommitments, CandidateDescriptor, + CandidateEvent, CommittedCandidateReceipt, CoreState, GroupRotationInfo, Hash as PHash, + HeadData, Header as PHeader, Id as ParaId, OccupiedCoreAssumption, ParachainHost, + PersistedValidationData, SessionIndex, SigningContext, ValidationCode, ValidationData, + ValidationOutputs, ValidatorId, ValidatorIndex, InboundDownwardMessage, }; -use polkadot_test_runtime_client::{ - DefaultTestClientBuilderExt, TestClient, TestClientBuilder, TestClientBuilderExt, -}; -use polkadot_validation::{sign_table_statement, Statement}; use sp_api::{ApiRef, ProvideRuntimeApi}; use sp_blockchain::{Error as ClientError, HeaderBackend}; -use sp_consensus::block_validation::BlockAnnounceValidator; +use sp_consensus::block_validation::BlockAnnounceValidator as _; use sp_core::H256; use sp_keyring::Sr25519Keyring; -use sp_runtime::traits::{Block as BlockT, NumberFor, Zero}; +use sp_keystore::{testing::KeyStore, SyncCryptoStore, SyncCryptoStorePtr}; +use sp_runtime::{ + traits::{NumberFor, Zero}, + RuntimeAppPublic, +}; #[derive(Clone)] struct DummyCollatorNetwork; @@ -45,26 +49,16 @@ impl SyncOracle for DummyCollatorNetwork { } } -fn make_validator() -> JustifiedBlockAnnounceValidator { - let (validator, _client) = make_validator_and_client(); - - validator -} - -fn make_validator_and_client() -> ( - JustifiedBlockAnnounceValidator, - Arc, -) { - let builder = TestClientBuilder::new(); - let client = Arc::new(TestApi::new(Arc::new(builder.build()))); +fn make_validator_and_api() -> (BlockAnnounceValidator, Arc) { + let api = Arc::new(TestApi::new()); ( - JustifiedBlockAnnounceValidator::new( - client.clone(), + BlockAnnounceValidator::new( + api.clone(), ParaId::from(56), Box::new(DummyCollatorNetwork), ), - client, + api, ) } @@ -79,42 +73,58 @@ fn default_header() -> Header { } fn make_gossip_message_and_header( - client: Arc, - relay_chain_leaf: H256, -) -> (GossipMessage, Header) { - let key = Sr25519Keyring::Alice.pair().into(); - let signing_context = client + api: Arc, + relay_parent: H256, + validator_index: u32, +) -> (SignedFullStatement, Header) { + let keystore: SyncCryptoStorePtr = Arc::new(KeyStore::new()); + let alice_public = SyncCryptoStore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .unwrap(); + let session_index = api .runtime_api() - .signing_context(&BlockId::Hash(relay_chain_leaf)) + .session_index_for_child(&BlockId::Hash(relay_parent)) .unwrap(); - let header = default_header(); - let candidate_receipt = AbridgedCandidateReceipt { - head_data: header.encode().into(), - ..AbridgedCandidateReceipt::default() - }; - let statement = Statement::Candidate(candidate_receipt); - let signature = sign_table_statement(&statement, &key, &signing_context); - let sender = 0; - let gossip_statement = GossipStatement { - relay_chain_leaf, - signed_statement: SignedStatement { - statement, - signature, - sender, - }, + let signing_context = SigningContext { + parent_hash: relay_parent, + session_index, }; - (GossipMessage::Statement(gossip_statement), header) + let header = default_header(); + let candidate_receipt = CommittedCandidateReceipt { + commitments: CandidateCommitments { + head_data: header.encode().into(), + ..Default::default() + }, + descriptor: CandidateDescriptor { + relay_parent, + ..Default::default() + }, + }; + let statement = Statement::Seconded(candidate_receipt); + let signed = block_on(SignedFullStatement::sign( + &keystore, + statement, + &signing_context, + validator_index, + &alice_public.into(), + )) + .expect("Signing statement"); + + (signed, header) } #[test] fn valid_if_no_data_and_less_than_best_known_number() { - let mut validator = make_validator(); + let mut validator = make_validator_and_api().0; let header = Header { number: 0, ..default_header() }; - let res = validator.validate(&header, &[]); + let res = block_on(validator.validate(&header, &[])); assert_eq!( res.unwrap(), @@ -125,12 +135,12 @@ fn valid_if_no_data_and_less_than_best_known_number() { #[test] fn invalid_if_no_data_exceeds_best_known_number() { - let mut validator = make_validator(); + let mut validator = make_validator_and_api().0; let header = Header { number: 1, ..default_header() }; - let res = validator.validate(&header, &[]); + let res = block_on(validator.validate(&header, &[])); assert_eq!( res.unwrap(), @@ -140,28 +150,26 @@ fn invalid_if_no_data_exceeds_best_known_number() { } #[test] -fn check_gossip_message_is_valid() { - let mut validator = make_validator(); +fn check_statement_is_encoded_correctly() { + let mut validator = make_validator_and_api().0; let header = default_header(); - let res = validator.validate(&header, &[0x42]).err(); + let res = block_on(validator.validate(&header, &[0x42])) + .err() + .expect("Should fail on invalid encoded statement"); - assert!( - res.is_some(), - "only data that are gossip message are allowed" - ); assert!(matches!( - *res.unwrap().downcast::().unwrap(), - ClientError::BadJustification(x) if x.contains("must be a gossip message") + *res.downcast::().unwrap(), + ClientError::BadJustification(x) if x.contains("must be a `SignedFullStatement`") )); } #[test] fn check_relay_parent_is_head() { - let (mut validator, client) = make_validator_and_client(); + let (mut validator, api) = make_validator_and_api(); let relay_chain_leaf = H256::zero(); - let (gossip_message, header) = make_gossip_message_and_header(client, relay_chain_leaf); + let (gossip_message, header) = make_gossip_message_and_header(api, relay_chain_leaf, 0); let data = gossip_message.encode(); - let res = validator.validate(&header, data.as_slice()); + let res = block_on(validator.validate(&header, data.as_slice())); assert_eq!( res.unwrap(), @@ -172,199 +180,136 @@ fn check_relay_parent_is_head() { #[test] fn check_relay_parent_actually_exists() { - let (mut validator, client) = make_validator_and_client(); - let relay_chain_leaf = H256::from_low_u64_be(42); - let (gossip_message, header) = make_gossip_message_and_header(client, relay_chain_leaf); - let data = gossip_message.encode(); - let res = validator.validate(&header, data.as_slice()).err(); + let (mut validator, api) = make_validator_and_api(); + let relay_parent = H256::from_low_u64_be(42); + let (signed_statement, header) = make_gossip_message_and_header(api, relay_parent, 0); + let data = signed_statement.encode(); + let res = block_on(validator.validate(&header, &data)) + .err() + .expect("Should fail on unknown relay parent"); - assert!( - res.is_some(), - "validation should fail if the relay chain leaf does not exist" - ); assert!(matches!( - *res.unwrap().downcast::().unwrap(), + *res.downcast::().unwrap(), ClientError::UnknownBlock(_) )); } #[test] fn check_relay_parent_fails_if_cannot_retrieve_number() { - let (mut validator, client) = make_validator_and_client(); - let relay_chain_leaf = H256::from_low_u64_be(0xdead); - let (gossip_message, header) = make_gossip_message_and_header(client, relay_chain_leaf); - let data = gossip_message.encode(); - let res = validator.validate(&header, data.as_slice()).err(); + let (mut validator, api) = make_validator_and_api(); + let relay_parent = H256::from_low_u64_be(0xdead); + let (signed_statement, header) = make_gossip_message_and_header(api, relay_parent, 0); + let data = signed_statement.encode(); + let res = block_on(validator.validate(&header, &data)) + .err() + .expect("Should fail when the relay chain number could not be retrieved"); - assert!( - res.is_some(), - "validation should fail if the relay chain leaf does not exist" - ); assert!(matches!( - *res.unwrap().downcast::().unwrap(), + *res.downcast::().unwrap(), ClientError::Backend(_) )); } #[test] fn check_signer_is_legit_validator() { - let (mut validator, client) = make_validator_and_client(); - let relay_chain_leaf = H256::from_low_u64_be(1); + let (mut validator, api) = make_validator_and_api(); + let relay_parent = H256::from_low_u64_be(1); - let key = Sr25519Keyring::Alice.pair().into(); - let signing_context = client - .runtime_api() - .signing_context(&BlockId::Hash(relay_chain_leaf)) - .unwrap(); - let header = default_header(); - let candidate_receipt = AbridgedCandidateReceipt { - head_data: header.encode().into(), - ..AbridgedCandidateReceipt::default() - }; - let statement = Statement::Candidate(candidate_receipt); - let signature = sign_table_statement(&statement, &key, &signing_context); - let sender = 1; - let gossip_statement = GossipStatement { - relay_chain_leaf, - signed_statement: SignedStatement { - statement, - signature, - sender, - }, - }; - let gossip_message = GossipMessage::Statement(gossip_statement); + let (signed_statement, header) = make_gossip_message_and_header(api, relay_parent, 1); + let data = signed_statement.encode(); - let data = gossip_message.encode(); - let res = validator.validate(&header, data.as_slice()).err(); + let res = block_on(validator.validate(&header, &data)) + .err() + .expect("Should fail on invalid validator"); - assert!( - res.is_some(), - "validation should fail if the signer is not a legit validator" - ); assert!(matches!( - *res.unwrap().downcast::().unwrap(), + *res.downcast::().unwrap(), ClientError::BadJustification(x) if x.contains("signer is a validator") )); } #[test] fn check_statement_is_correctly_signed() { - let (mut validator, client) = make_validator_and_client(); - let header = default_header(); - let relay_chain_leaf = H256::from_low_u64_be(1); + let (mut validator, api) = make_validator_and_api(); + let relay_parent = H256::from_low_u64_be(1); - let key = Sr25519Keyring::Alice.pair().into(); - let signing_context = client - .runtime_api() - .signing_context(&BlockId::Hash(relay_chain_leaf)) - .unwrap(); - let mut candidate_receipt = AbridgedCandidateReceipt::default(); - let statement = Statement::Candidate(candidate_receipt.clone()); - let signature = sign_table_statement(&statement, &key, &signing_context); + let (signed_statement, header) = make_gossip_message_and_header(api, relay_parent, 0); - // alterate statement so the signature doesn't match anymore - candidate_receipt = AbridgedCandidateReceipt { - parachain_index: candidate_receipt.parachain_index + 1, - ..candidate_receipt - }; - let statement = Statement::Candidate(candidate_receipt); + let mut data = signed_statement.encode(); - let sender = 0; - let gossip_statement = GossipStatement { - relay_chain_leaf, - signed_statement: SignedStatement { - statement, - signature, - sender, - }, - }; - let gossip_message = GossipMessage::Statement(gossip_statement); + // The signature comes at the end of the type, so change a bit to make the signature invalid. + let last = data.len() - 1; + data[last] = data[last].wrapping_add(1); - let data = gossip_message.encode(); - let res = validator.validate(&header, data.as_slice()).err(); + let res = block_on(validator.validate(&header, &data)) + .err() + .expect("Validation should fail if the statement is not signed correctly"); - assert!( - res.is_some(), - "validation should fail if the statement is not correctly signed" - ); assert!(matches!( - *res.unwrap().downcast::().unwrap(), + *res.downcast::().unwrap(), ClientError::BadJustification(x) if x.contains("signature is invalid") )); } #[test] -fn check_statement_is_a_candidate_message() { - let (mut validator, client) = make_validator_and_client(); +fn check_statement_seconded() { + let (mut validator, api) = make_validator_and_api(); let header = default_header(); - let relay_chain_leaf = H256::from_low_u64_be(1); + let relay_parent = H256::from_low_u64_be(1); - let key = Sr25519Keyring::Alice.pair().into(); - let signing_context = client + let keystore: SyncCryptoStorePtr = Arc::new(KeyStore::new()); + let alice_public = SyncCryptoStore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .unwrap(); + let session_index = api .runtime_api() - .signing_context(&BlockId::Hash(relay_chain_leaf)) + .session_index_for_child(&BlockId::Hash(relay_parent)) .unwrap(); - let statement = Statement::Valid(H256::zero()); - let signature = sign_table_statement(&statement, &key, &signing_context); - let sender = 0; - let gossip_statement = GossipStatement { - relay_chain_leaf, - signed_statement: SignedStatement { - statement, - signature, - sender, - }, + let signing_context = SigningContext { + parent_hash: relay_parent, + session_index, }; - let gossip_message = GossipMessage::Statement(gossip_statement); - let data = gossip_message.encode(); - let res = validator.validate(&header, data.as_slice()).err(); + let statement = Statement::Valid(Default::default()); + + let signed_statement = block_on(SignedFullStatement::sign( + &keystore, + statement, + &signing_context, + 0, + &alice_public.into(), + )) + .expect("Signs statement"); + let data = signed_statement.encode(); + + let res = block_on(validator.validate(&header, &data)) + .err() + .expect("validation should fail if not seconded statement"); - assert!( - res.is_some(), - "validation should fail if the statement is not a candidate message" - ); assert!(matches!( - *res.unwrap().downcast::().unwrap(), - ClientError::BadJustification(x) if x.contains("must be a candidate statement") + *res.downcast::().unwrap(), + ClientError::BadJustification(x) if x.contains("must be a `Statement::Seconded`") )); } #[test] fn check_header_match_candidate_receipt_header() { - let (mut validator, client) = make_validator_and_client(); - let relay_chain_leaf = H256::from_low_u64_be(1); + let (mut validator, api) = make_validator_and_api(); + let relay_parent = H256::from_low_u64_be(1); - let key = Sr25519Keyring::Alice.pair().into(); - let signing_context = client - .runtime_api() - .signing_context(&BlockId::Hash(relay_chain_leaf)) - .unwrap(); - let header = default_header(); - let candidate_receipt = AbridgedCandidateReceipt::default(); - let statement = Statement::Candidate(candidate_receipt); - let signature = sign_table_statement(&statement, &key, &signing_context); - let sender = 0; - let gossip_statement = GossipStatement { - relay_chain_leaf, - signed_statement: SignedStatement { - statement, - signature, - sender, - }, - }; - let gossip_message = GossipMessage::Statement(gossip_statement); + let (signed_statement, mut header) = make_gossip_message_and_header(api, relay_parent, 0); + let data = signed_statement.encode(); + header.number = 300; - let data = gossip_message.encode(); - let res = validator.validate(&header, data.as_slice()).err(); + let res = block_on(validator.validate(&header, &data)) + .err() + .expect("validation should fail if the header in doesn't match"); - assert!( - res.is_some(), - "validation should fail if the header in the candidate_receipt doesn't \ - match the header provided" - ); assert!(matches!( - *res.unwrap().downcast::().unwrap(), + *res.downcast::().unwrap(), ClientError::BadJustification(x) if x.contains("header does not match") )); } @@ -372,31 +317,25 @@ fn check_header_match_candidate_receipt_header() { #[derive(Default)] struct ApiData { validators: Vec, - duties: Vec, - active_parachains: Vec<(ParaId, Option<(CollatorId, Retriable)>)>, } -#[derive(Clone)] struct TestApi { - data: Arc>, - client: Arc, + data: Arc, } impl TestApi { - fn new(client: Arc) -> Self { + fn new() -> Self { Self { - client, - data: Arc::new(Mutex::new(ApiData { + data: Arc::new(ApiData { validators: vec![Sr25519Keyring::Alice.public().into()], - ..Default::default() - })), + }), } } } #[derive(Default)] struct RuntimeApi { - data: Arc>, + data: Arc, } impl ProvideRuntimeApi for TestApi { @@ -415,48 +354,59 @@ sp_api::mock_impl_runtime_apis! { type Error = sp_blockchain::Error; fn validators(&self) -> Vec { - self.data.lock().validators.clone() + self.data.validators.clone() } - fn duty_roster(&self) -> DutyRoster { - DutyRoster { - validator_duty: self.data.lock().duties.clone(), - } + fn validator_groups(&self) -> (Vec>, GroupRotationInfo) { + (Vec::new(), GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 0, now: 0 }) } - fn active_parachains(&self) -> Vec<(ParaId, Option<(CollatorId, Retriable)>)> { - self.data.lock().active_parachains.clone() + fn availability_cores(&self) -> Vec> { + Vec::new() } - fn parachain_code(_: ParaId) -> Option { - Some(ValidationCode(Vec::new())) + fn full_validation_data(&self, _: ParaId, _: OccupiedCoreAssumption) -> Option> { + None } - fn global_validation_data() -> GlobalValidationData { - Default::default() - } - - fn local_validation_data(_: ParaId) -> Option { - Some(LocalValidationData { - parent_head: HeadData:: { header: default_header() }.encode().into(), + fn persisted_validation_data(&self, _: ParaId, _: OccupiedCoreAssumption) -> Option> { + Some(PersistedValidationData { + parent_head: HeadData(default_header().encode()), ..Default::default() }) } - fn get_heads(_: Vec<::Extrinsic>) -> Option> { - Some(Vec::new()) + fn session_index_for_child(&self) -> SessionIndex { + 0 } - fn signing_context() -> SigningContext { - SigningContext { - session_index: Default::default(), - parent_hash: Default::default(), - } + fn validation_code(&self, _: ParaId, _: OccupiedCoreAssumption) -> Option { + None } - fn downward_messages(_: ParaId) -> Vec { + fn candidate_pending_availability(&self, _: ParaId) -> Option> { + None + } + + fn candidate_events(&self) -> Vec> { Vec::new() } + + fn validator_discovery(_: Vec) -> Vec> { + Vec::new() + } + + fn check_validation_outputs(_: ParaId, _: ValidationOutputs) -> bool { + false + } + + fn dmq_contents(_: ParaId) -> Vec> { + Vec::new() + } + + fn historical_validation_code(_: ParaId, _: BlockNumber) -> Option { + None + } } } diff --git a/parachain-upgrade/Cargo.toml b/parachain-upgrade/Cargo.toml index 87976938c7..7f3e6bf4aa 100644 --- a/parachain-upgrade/Cargo.toml +++ b/parachain-upgrade/Cargo.toml @@ -11,27 +11,27 @@ cumulus-primitives = { path = "../primitives", default-features = false } cumulus-runtime = { path = "../runtime", default-features = false } # Polkadot dependencies -parachain = { package = "polkadot-parachain", git = "https://github.com/paritytech/polkadot", branch = "rococo-branch", default-features = false } +parachain = { package = "polkadot-parachain", git = "https://github.com/paritytech/polkadot", default-features = false , branch = "bkchr-adder-collator-integration-test" } # Substrate dependencies -frame-support = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", version = "2.0.0-rc5", default-features = false } -sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } -sp-version = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +pallet-balances = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", version = "2.0.0-rc5", default-features = false , branch = "master" } +sp-inherents = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-std = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-version = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +frame-system = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } # Other Dependencies codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"]} serde = { version = "1.0.101", optional = true, features = ["derive"] } [dev-dependencies] -sp-externalities = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } -substrate-test-runtime-client = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } -sp-version = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } +sp-externalities = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +substrate-test-runtime-client = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-version = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } [features] default = ['std'] diff --git a/parachain-upgrade/src/lib.rs b/parachain-upgrade/src/lib.rs index dd11518ef7..e494f1beb2 100644 --- a/parachain-upgrade/src/lib.rs +++ b/parachain-upgrade/src/lib.rs @@ -30,12 +30,13 @@ //! Users must ensure that they register this pallet as an inherent provider. use cumulus_primitives::{ - inherents::VALIDATION_FUNCTION_PARAMS_IDENTIFIER as INHERENT_IDENTIFIER, - validation_function_params::{OnValidationFunctionParams, ValidationFunctionParams}, - well_known_keys::{NEW_VALIDATION_CODE, VALIDATION_FUNCTION_PARAMS}, + inherents::VALIDATION_DATA_IDENTIFIER as INHERENT_IDENTIFIER, + well_known_keys::{NEW_VALIDATION_CODE, VALIDATION_DATA}, + OnValidationData, ValidationData, }; use frame_support::{ - decl_error, decl_event, decl_module, decl_storage, ensure, storage, weights::DispatchClass, + decl_error, decl_event, decl_module, decl_storage, ensure, storage, + weights::{DispatchClass, Weight}, }; use frame_system::{ensure_none, ensure_root}; use parachain::primitives::RelayChainBlockNumber; @@ -50,10 +51,8 @@ pub trait Trait: frame_system::Trait { /// The overarching event type. type Event: From + Into<::Event>; - /// Something which can be notified when the validation function params are set. - /// - /// Set this to `()` if not needed. - type OnValidationFunctionParams: OnValidationFunctionParams; + /// Something which can be notified when the validation data is set. + type OnValidationData: OnValidationData; } // This pallet's storage items. @@ -64,8 +63,11 @@ decl_storage! { PendingValidationFunction get(fn new_validation_function): Option<(RelayChainBlockNumber, Vec)>; - /// Were the VFPs updated this block? - DidUpdateVFPs: bool; + /// Were the [`ValidationData`] updated in this block? + DidUpdateValidationData: bool; + + /// Were the validation data set to notify the relay chain? + DidSetValidationCode: bool; } } @@ -79,7 +81,8 @@ decl_module! { // TODO: figure out a better weight than this #[weight = (0, DispatchClass::Operational)] pub fn schedule_upgrade(origin, validation_function: Vec) { - System::::can_set_code(origin, &validation_function)?; + ensure_root(origin)?; + System::::can_set_code(&validation_function)?; Self::schedule_upgrade_impl(validation_function)?; } @@ -93,7 +96,7 @@ decl_module! { Self::schedule_upgrade_impl(validation_function)?; } - /// Set the current validation function parameters + /// Set the current validation data. /// /// This should be invoked exactly once per block. It will panic at the finalization /// phase if the call was not invoked. @@ -103,45 +106,52 @@ decl_module! { /// As a side effect, this function upgrades the current validation function /// if the appropriate time has come. #[weight = (0, DispatchClass::Mandatory)] - fn set_validation_function_parameters(origin, vfp: ValidationFunctionParams) { + fn set_validation_data(origin, vfp: ValidationData) { ensure_none(origin)?; - assert!(!DidUpdateVFPs::exists(), "VFPs must be updated only once in the block"); + assert!(!DidUpdateValidationData::exists(), "ValidationData must be updated only once in a block"); // initialization logic: we know that this runs exactly once every block, // which means we can put the initialization logic here to remove the // sequencing problem. if let Some((apply_block, validation_function)) = PendingValidationFunction::get() { - if vfp.relay_chain_height >= apply_block { + if vfp.persisted.block_number >= apply_block { PendingValidationFunction::kill(); Self::put_parachain_code(&validation_function); - Self::deposit_event(Event::ValidationFunctionApplied(vfp.relay_chain_height)); + Self::deposit_event(Event::ValidationFunctionApplied(vfp.persisted.block_number)); } } - storage::unhashed::put(VALIDATION_FUNCTION_PARAMS, &vfp); - DidUpdateVFPs::put(true); - ::on_validation_function_params(vfp); + storage::unhashed::put(VALIDATION_DATA, &vfp); + DidUpdateValidationData::put(true); + ::on_validation_data(vfp); } fn on_finalize() { - assert!(DidUpdateVFPs::take(), "VFPs must be updated once per block"); + assert!(DidUpdateValidationData::take(), "VFPs must be updated once per block"); + DidSetValidationCode::take(); + } + + fn on_initialize(n: T::BlockNumber) -> Weight { + // To prevent removing `NEW_VALIDATION_CODE` that was set by another `on_initialize` like + // for example from scheduler, we only kill the storage entry if it was not yet updated + // in the current block. + if !DidSetValidationCode::get() { + storage::unhashed::kill(NEW_VALIDATION_CODE); + } + + storage::unhashed::kill(VALIDATION_DATA); + + 0 } } } impl Module { - /// Get validation function parameters. + /// Get validation data. /// - /// This will return `None` if this module's inherent has not yet run. - /// If it returns `Some(_)`, the validation function params are current for this block. - pub fn validation_function_params() -> Option { - if DidUpdateVFPs::get() { - // this storage value is set by cumulus during block validation, - // and also by the inherent from this module. - storage::unhashed::get(VALIDATION_FUNCTION_PARAMS) - } else { - None - } + /// Returns `Some(_)` after the inherent set the data for the current block. + pub fn validation_data() -> Option { + storage::unhashed::get(VALIDATION_DATA) } /// Put a new validation function into a particular location where polkadot @@ -149,6 +159,7 @@ impl Module { /// upgrade has been scheduled. fn notify_polkadot_of_pending_upgrade(code: &[u8]) { storage::unhashed::put_raw(NEW_VALIDATION_CODE, code); + DidSetValidationCode::put(true); } /// Put a new validation function into a particular location where this @@ -159,22 +170,33 @@ impl Module { /// `true` when a code upgrade is currently legal pub fn can_set_code() -> bool { - Self::validation_function_params() - .map(|vfp| vfp.code_upgrade_allowed.is_some()) + Self::validation_data() + .map(|vfp| vfp.transient.code_upgrade_allowed.is_some()) .unwrap_or_default() } /// The maximum code size permitted, in bytes. pub fn max_code_size() -> Option { - Self::validation_function_params().map(|vfp| vfp.max_code_size) + Self::validation_data().map(|vfp| vfp.transient.max_code_size) } /// The implementation of the runtime upgrade scheduling. - fn schedule_upgrade_impl(validation_function: Vec) -> frame_support::dispatch::DispatchResult { - ensure!(!PendingValidationFunction::exists(), Error::::OverlappingUpgrades); - let vfp = Self::validation_function_params().ok_or(Error::::ValidationFunctionParamsNotAvailable)?; - ensure!(validation_function.len() <= vfp.max_code_size as usize, Error::::TooBig); - let apply_block = vfp.code_upgrade_allowed.ok_or(Error::::ProhibitedByPolkadot)?; + fn schedule_upgrade_impl( + validation_function: Vec, + ) -> frame_support::dispatch::DispatchResult { + ensure!( + !PendingValidationFunction::exists(), + Error::::OverlappingUpgrades + ); + let vfp = Self::validation_data().ok_or(Error::::ValidationDataNotAvailable)?; + ensure!( + validation_function.len() <= vfp.transient.max_code_size as usize, + Error::::TooBig + ); + let apply_block = vfp + .transient + .code_upgrade_allowed + .ok_or(Error::::ProhibitedByPolkadot)?; // When a code upgrade is scheduled, it has to be applied in two // places, synchronized: both polkadot and the individual parachain @@ -197,15 +219,13 @@ impl ProvideInherent for Module { const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; fn create_inherent(data: &InherentData) -> Option { - // If the inherent is not present, this returns None early. This in turn will - // cause the on_finalize assertion to fail. - let vfp: ValidationFunctionParams = data + let data: ValidationData = data .get_data(&INHERENT_IDENTIFIER) .ok() .flatten() .expect("validation function params are always injected into inherent data; qed"); - Some(Call::set_validation_function_parameters(vfp)) + Some(Call::set_validation_data(data)) } } @@ -226,8 +246,8 @@ decl_error! { ProhibitedByPolkadot, /// The supplied validation function has compiled into a blob larger than Polkadot is willing to run TooBig, - /// The inherent which supplies the validation function params did not run this block - ValidationFunctionParamsNotAvailable, + /// The inherent which supplies the validation data did not run this block + ValidationDataNotAvailable, } } @@ -237,6 +257,7 @@ mod tests { use super::*; use codec::Encode; + use cumulus_primitives::{PersistedValidationData, TransientValidationData}; use frame_support::{ assert_ok, dispatch::UnfilteredDispatchable, @@ -305,7 +326,7 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = Version; - type ModuleToIndex = (); + type PalletInfo = (); type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); @@ -317,7 +338,7 @@ mod tests { } impl Trait for Test { type Event = TestEvent; - type OnValidationFunctionParams = (); + type OnValidationData = (); } type ParachainUpgrade = Module; @@ -376,8 +397,7 @@ mod tests { tests: Vec, pending_upgrade: Option, ran: bool, - vfp_maker: - Option ValidationFunctionParams>>, + vfp_maker: Option ValidationData>>, } impl BlockTests { @@ -418,9 +438,9 @@ mod tests { }) } - fn with_validation_function_params(mut self, f: F) -> Self + fn with_validation_data(mut self, f: F) -> Self where - F: 'static + Fn(&BlockTests, RelayChainBlockNumber) -> ValidationFunctionParams, + F: 'static + Fn(&BlockTests, RelayChainBlockNumber) -> ValidationData, { self.vfp_maker = Some(Box::new(f)); self @@ -453,18 +473,24 @@ mod tests { // now mess with the storage the way validate_block does let vfp = match self.vfp_maker { - None => ValidationFunctionParams { - max_code_size: 10 * 1024 * 1024, // 10 mb - relay_chain_height: *n as RelayChainBlockNumber, - code_upgrade_allowed: if self.pending_upgrade.is_some() { - None - } else { - Some(*n as RelayChainBlockNumber + 1000) + None => ValidationData { + persisted: PersistedValidationData { + block_number: *n as RelayChainBlockNumber, + ..Default::default() + }, + transient: TransientValidationData { + max_code_size: 10 * 1024 * 1024, // 10 mb + code_upgrade_allowed: if self.pending_upgrade.is_some() { + None + } else { + Some(*n as RelayChainBlockNumber + 1000) + }, + ..Default::default() }, }, Some(ref maker) => maker(self, *n as RelayChainBlockNumber), }; - storage::unhashed::put(VALIDATION_FUNCTION_PARAMS, &vfp); + storage::unhashed::put(VALIDATION_DATA, &vfp); storage::unhashed::kill(NEW_VALIDATION_CODE); // It is insufficient to push the validation function params @@ -491,7 +517,7 @@ mod tests { if self.pending_upgrade.is_some() { panic!("attempted to set validation code while upgrade was pending"); } - self.pending_upgrade = vfp.code_upgrade_allowed; + self.pending_upgrade = vfp.transient.code_upgrade_allowed; } // clean up @@ -621,10 +647,16 @@ mod tests { #[test] fn checks_size() { BlockTests::new() - .with_validation_function_params(|_, n| ValidationFunctionParams { - max_code_size: 32, - relay_chain_height: n, - code_upgrade_allowed: Some(n + 1000), + .with_validation_data(|_, n| ValidationData { + persisted: PersistedValidationData { + block_number: n, + ..Default::default() + }, + transient: TransientValidationData { + max_code_size: 32, + code_upgrade_allowed: Some(n + 1000), + ..Default::default() + }, }) .add(123, || { assert_eq!( diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 3e8b38fe5a..968ad79d8f 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -6,26 +6,26 @@ edition = "2018" [dependencies] # Substrate dependencies -sc-service = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", optional = true } -sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } +sp-inherents = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sc-chain-spec = { git = "https://github.com/paritytech/substrate", optional = true, branch = "master" } # Polkadot dependencies -polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch", default-features = false } -polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch", default-features = false } +polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "bkchr-adder-collator-integration-test" } +polkadot-primitives = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "bkchr-adder-collator-integration-test" } # Other dependencies codec = { package = "parity-scale-codec", version = "1.0.5", default-features = false, features = [ "derive" ] } impl-trait-for-tuples = "0.1.3" # Polkadot dependencies -polkadot-core-primitives = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch", default-features = false } +polkadot-core-primitives = { git = "https://github.com/paritytech/polkadot", default-features = false , branch = "bkchr-adder-collator-integration-test" } [features] default = [ "std" ] std = [ - "sc-service", + "sc-chain-spec", "sp-std/std", "codec/std", "polkadot-primitives/std", diff --git a/primitives/src/genesis.rs b/primitives/src/genesis.rs index 68f3c856c6..76f80f6b27 100644 --- a/primitives/src/genesis.rs +++ b/primitives/src/genesis.rs @@ -15,7 +15,7 @@ // along with Cumulus. If not, see . use codec::Encode; -use sc_service::ChainSpec; +use sc_chain_spec::ChainSpec; use sp_runtime::traits::{Block as BlockT, Hash as HashT, Header as HeaderT, Zero}; /// Generate the genesis state for a given ChainSpec. diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index edd9f989c4..ae7c8c80f5 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -25,18 +25,15 @@ pub use polkadot_core_primitives::DownwardMessage; /// It is "generic" in such a way, that the actual message is encoded in the `data` field. /// Besides the `data` it also holds the `origin` of the message. pub use polkadot_parachain::primitives::UpwardMessage as GenericUpwardMessage; -pub use polkadot_parachain::primitives::{ - Id as ParaId, ParachainDispatchOrigin as UpwardMessageOrigin, +pub use polkadot_parachain::primitives::{Id as ParaId, ValidationParams}; +pub use polkadot_primitives::v1::{ + PersistedValidationData, TransientValidationData, ValidationData, }; #[cfg(feature = "std")] pub mod genesis; -pub mod validation_function_params; pub mod xcmp; -use codec::{Decode, Encode}; -use sp_runtime::traits::Block as BlockT; - /// Identifiers and types related to Cumulus Inherents pub mod inherents { use sp_inherents::InherentIdentifier; @@ -47,11 +44,10 @@ pub mod inherents { /// The type of the inherent downward messages. pub type DownwardMessagesType = sp_std::vec::Vec; - /// The identifier for the `validation_function_params` inherent. - pub const VALIDATION_FUNCTION_PARAMS_IDENTIFIER: InherentIdentifier = *b"valfunp0"; + /// The identifier for the `set_validation_data` inherent. + pub const VALIDATION_DATA_IDENTIFIER: InherentIdentifier = *b"valfunp0"; /// The type of the inherent. - pub type ValidationFunctionParamsType = - crate::validation_function_params::ValidationFunctionParams; + pub type ValidationDataType = crate::ValidationData; } /// Well known keys for values in the storage. @@ -61,11 +57,11 @@ pub mod well_known_keys { /// The upward messages are stored as SCALE encoded `Vec`. pub const UPWARD_MESSAGES: &'static [u8] = b":cumulus_upward_messages:"; - /// Current validation function parameters. - pub const VALIDATION_FUNCTION_PARAMS: &'static [u8] = b":cumulus_validation_function_params"; + /// Current validation data. + pub const VALIDATION_DATA: &'static [u8] = b":cumulus_validation_data:"; /// Code upgarde (set as appropriate by a pallet). - pub const NEW_VALIDATION_CODE: &'static [u8] = b":cumulus_new_validation_code"; + pub const NEW_VALIDATION_CODE: &'static [u8] = b":cumulus_new_validation_code:"; /// The storage key for the processed downward messages. /// @@ -80,16 +76,8 @@ pub trait DownwardMessageHandler { fn handle_downward_message(msg: &DownwardMessage); } -/// Something that can send upward messages. -pub trait UpwardMessageSender { - /// Send an upward message to the relay chain. - /// - /// Returns an error if sending failed. - fn send_upward_message(msg: &UpwardMessage, origin: UpwardMessageOrigin) -> Result<(), ()>; -} - -/// The head data of the parachain, stored in the relay chain. -#[derive(Decode, Encode, Debug)] -pub struct HeadData { - pub header: Block::Header, +/// A trait which is called when the validation data is set. +#[impl_trait_for_tuples::impl_for_tuples(30)] +pub trait OnValidationData { + fn on_validation_data(data: ValidationData); } diff --git a/primitives/src/validation_function_params.rs b/primitives/src/validation_function_params.rs deleted file mode 100644 index a78186f926..0000000000 --- a/primitives/src/validation_function_params.rs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Validation Function Parameters govern the ability of parachains to upgrade their validation functions. - -use codec::{Decode, Encode}; -use polkadot_parachain::primitives::{RelayChainBlockNumber, ValidationParams}; -use polkadot_primitives::v0::{GlobalValidationData, LocalValidationData}; - -/// Validation Function Parameters -/// -/// This struct is the subset of [`ValidationParams`](polkadot_parachain::ValidationParams) -/// which is of interest when upgrading parachain validation functions. -#[derive(PartialEq, Eq, Encode, Decode, Clone, Copy, Default, sp_runtime::RuntimeDebug)] -pub struct ValidationFunctionParams { - /// The maximum code size permitted, in bytes. - pub max_code_size: u32, - /// The current relay-chain block number. - pub relay_chain_height: RelayChainBlockNumber, - /// Whether a code upgrade is allowed or not, and at which height the upgrade - /// would be applied after, if so. The parachain logic should apply any upgrade - /// issued in this block after the first block - /// with `relay_chain_height` at least this value, if `Some`. if `None`, issue - /// no upgrade. - pub code_upgrade_allowed: Option, -} - -impl From<&ValidationParams> for ValidationFunctionParams { - fn from(vp: &ValidationParams) -> Self { - ValidationFunctionParams { - max_code_size: vp.max_code_size, - relay_chain_height: vp.relay_chain_height, - code_upgrade_allowed: vp.code_upgrade_allowed, - } - } -} - -impl From<(GlobalValidationData, LocalValidationData)> for ValidationFunctionParams { - fn from(t: (GlobalValidationData, LocalValidationData)) -> Self { - let (global_validation, local_validation) = t; - ValidationFunctionParams { - max_code_size: global_validation.max_code_size, - relay_chain_height: global_validation.block_number, - code_upgrade_allowed: local_validation.code_upgrade_allowed, - } - } -} - -/// A trait which is called when the validation function parameters are set -#[impl_trait_for_tuples::impl_for_tuples(30)] -pub trait OnValidationFunctionParams { - fn on_validation_function_params(vfp: ValidationFunctionParams); -} diff --git a/rococo-parachains/Cargo.toml b/rococo-parachains/Cargo.toml index 2c19020e3c..b5f51c2cde 100644 --- a/rococo-parachains/Cargo.toml +++ b/rococo-parachains/Cargo.toml @@ -18,44 +18,41 @@ parking_lot = '0.9.0' trie-root = '0.15.2' codec = { package = 'parity-scale-codec', version = '1.0.0' } structopt = "0.3.3" -ansi_term = "0.12.1" serde = { version = "1.0.101", features = ["derive"] } hex-literal = "0.2.1" # Parachain dependencies parachain-runtime = { package = "cumulus-test-parachain-runtime", path = "runtime" } -parachain-contracts-runtime = { package = "cumulus-contracts-parachain-runtime", path = "contracts-runtime" } rococo-parachain-primitives = { path = "primitives" } # Substrate dependencies -sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-session = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-cli = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-executor = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-service = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-basic-authorship = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", version = "0.8.0-rc5" } -sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-trie = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-api = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-informant = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } +sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-basic-authorship = { git = "https://github.com/paritytech/substrate", version = "0.8.0-rc5" , branch = "master" } +sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "master" } # RPC related dependencies -cumulus-pallet-contracts-rpc = { path = "./pallets/contracts/rpc" } -jsonrpc-core = "14.2.0" +jsonrpc-core = "15.1.0" # Cumulus dependencies cumulus-consensus = { path = "../consensus" } @@ -65,15 +62,28 @@ cumulus-primitives = { path = "../primitives" } cumulus-service = { path = "../service" } # Polkadot dependencies -polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-collator = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-cli = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } +polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-cli = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-test-service = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } [build-dependencies] -substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } +substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "master" } [dev-dependencies] assert_cmd = "0.12" nix = "0.17" +rand = "0.7.3" +tokio = { version = "0.2.13", features = ["macros"] } + +# Polkadot dependencies +polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-test-runtime = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-test-client = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-test-service = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } + +# Substrate dependencies +pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "master" } +substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "master" } +substrate-test-runtime-client = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/rococo-parachains/contracts-runtime/Cargo.toml b/rococo-parachains/contracts-runtime/Cargo.toml deleted file mode 100644 index b2812c1f9e..0000000000 --- a/rococo-parachains/contracts-runtime/Cargo.toml +++ /dev/null @@ -1,95 +0,0 @@ -[package] -name = 'cumulus-contracts-parachain-runtime' -version = '0.1.0' -authors = ["Parity Technologies "] -edition = '2018' - -[dependencies] -serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } - -cumulus-token-dealer = { path = "../pallets/token-dealer", default-features = false} -parachain-info = { path = "../pallets/parachain-info", default-features = false} -rococo-parachain-primitives = { path = "../primitives", default-features = false} - -# Substrate dependencies -sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-version = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-session = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-offchain = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-block-builder = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-transaction-pool = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-inherents = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } - -frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -frame-executive = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-balances = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-sudo = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } - -# In-Tree Fork of seal that does not use child trie nor storage transactions -cumulus-pallet-contracts = { path = "../pallets/contracts", default-features = false } -cumulus-pallet-contracts-primitives = { path = "../pallets/contracts/common", default-features = false } -cumulus-pallet-contracts-rpc-runtime-api = { path = "../pallets/contracts/rpc/runtime-api", default-features = false } - -# Cumulus dependencies -cumulus-runtime = { path = "../../runtime", default-features = false } -cumulus-parachain-upgrade = { path = "../../parachain-upgrade", default-features = false } -cumulus-message-broker = { path = "../../message-broker", default-features = false } -cumulus-upward-message = { path = "../../upward-message", default-features = false } -cumulus-primitives = { path = "../../primitives", default-features = false } - -# Polkadot dependencies -polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch", default-features = false } - -[build-dependencies] -wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.6" } - -[features] -default = [ "std" ] -std = [ - "codec/std", - "serde", - "sp-api/std", - "sp-std/std", - "sp-io/std", - "sp-core/std", - "sp-runtime/std", - "sp-version/std", - "sp-offchain/std", - "sp-session/std", - "sp-block-builder/std", - "sp-transaction-pool/std", - "sp-inherents/std", - "frame-support/std", - "frame-executive/std", - "frame-system/std", - "pallet-balances/std", - "cumulus-pallet-contracts/std", - "cumulus-pallet-contracts-primitives/std", - "cumulus-pallet-contracts-rpc-runtime-api/std", - "pallet-randomness-collective-flip/std", - "pallet-timestamp/std", - "pallet-sudo/std", - "pallet-transaction-payment/std", - "parachain-info/std", - "rococo-parachain-primitives/std", - "cumulus-runtime/std", - "cumulus-parachain-upgrade/std", - "cumulus-message-broker/std", - "cumulus-upward-message/std", - "cumulus-primitives/std", - "polkadot-parachain/std", - "cumulus-token-dealer/std", -] -# Will be enabled by the `wasm-builder` when building the runtime for WASM. -runtime-wasm = [ - "cumulus-upward-message/runtime-wasm", -] diff --git a/rococo-parachains/contracts-runtime/build.rs b/rococo-parachains/contracts-runtime/build.rs deleted file mode 100644 index 5fefb95548..0000000000 --- a/rococo-parachains/contracts-runtime/build.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -use wasm_builder_runner::WasmBuilder; - -fn main() { - WasmBuilder::new() - .with_current_project() - .with_wasm_builder_from_crates("2.0.0") - .export_heap_base() - .import_memory() - .build() -} diff --git a/rococo-parachains/contracts-runtime/src/lib.rs b/rococo-parachains/contracts-runtime/src/lib.rs deleted file mode 100644 index 5676b62823..0000000000 --- a/rococo-parachains/contracts-runtime/src/lib.rs +++ /dev/null @@ -1,411 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus 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. - -// Cumulus 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 Cumulus. If not, see . - -#![cfg_attr(not(feature = "std"), no_std)] -// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. -#![recursion_limit = "256"] - -// Make the WASM binary available. -#[cfg(feature = "std")] -include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); - -use cumulus_pallet_contracts_rpc_runtime_api::ContractExecResult; -use rococo_parachain_primitives::*; -use sp_api::impl_runtime_apis; -use sp_core::OpaqueMetadata; -use sp_runtime::{ - create_runtime_str, generic, impl_opaque_keys, - traits::{BlakeTwo256, Block as BlockT, IdentityLookup, Saturating}, - transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, -}; -use sp_std::prelude::*; -#[cfg(feature = "std")] -use sp_version::NativeVersion; -use sp_version::RuntimeVersion; - -// A few exports that help ease life for downstream crates. -pub use frame_support::{ - construct_runtime, parameter_types, - traits::Randomness, - weights::{constants::WEIGHT_PER_SECOND, IdentityFee, Weight}, - StorageValue, -}; -pub use pallet_balances::Call as BalancesCall; -pub use pallet_timestamp::Call as TimestampCall; -#[cfg(any(feature = "std", test))] -pub use sp_runtime::BuildStorage; -pub use sp_runtime::{Perbill, Permill}; - -pub type SessionHandlers = (); - -impl_opaque_keys! { - pub struct SessionKeys {} -} - -/// This runtime version. -pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: create_runtime_str!("cumulus-contracts-parachain"), - impl_name: create_runtime_str!("cumulus-contracts-parachain"), - authoring_version: 1, - spec_version: 4, - impl_version: 1, - apis: RUNTIME_API_VERSIONS, - transaction_version: 1, -}; - -pub const MILLISECS_PER_BLOCK: u64 = 6000; - -pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; - -pub const EPOCH_DURATION_IN_BLOCKS: u32 = 10 * MINUTES; - -// These time units are defined in number of blocks. -pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); -pub const HOURS: BlockNumber = MINUTES * 60; -pub const DAYS: BlockNumber = HOURS * 24; - -// 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks. -pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); - -#[derive(codec::Encode, codec::Decode)] -pub enum XCMPMessage { - /// Transfer tokens to the given account from the Parachain account. - TransferToken(XAccountId, XBalance), -} - -/// The version information used to identify this runtime when compiled natively. -#[cfg(feature = "std")] -pub fn native_version() -> NativeVersion { - NativeVersion { - runtime_version: VERSION, - can_author_with: Default::default(), - } -} - -parameter_types! { - pub const BlockHashCount: BlockNumber = 250; - pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND; - /// Assume 10% of weight for average on_initialize calls. - pub MaximumExtrinsicWeight: Weight = AvailableBlockRatio::get() - .saturating_sub(Perbill::from_percent(10)) * MaximumBlockWeight::get(); - pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); - pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; - pub const Version: RuntimeVersion = VERSION; - pub const ExtrinsicBaseWeight: Weight = 10_000_000; -} - -impl frame_system::Trait for Runtime { - /// The identifier used to distinguish between accounts. - type AccountId = AccountId; - /// The aggregated dispatch type that is available for extrinsics. - type Call = Call; - /// The lookup mechanism to get account ID from whatever is passed in dispatchers. - type Lookup = IdentityLookup; - /// The index type for storing how many extrinsics an account has signed. - type Index = Index; - /// The index type for blocks. - type BlockNumber = BlockNumber; - /// The type for hashing blocks and tries. - type Hash = Hash; - /// The hashing algorithm used. - type Hashing = BlakeTwo256; - /// The header type. - type Header = generic::Header; - /// The ubiquitous event type. - type Event = Event; - /// The ubiquitous origin type. - type Origin = Origin; - /// Maximum number of block number to block hash mappings to keep (oldest pruned first). - type BlockHashCount = BlockHashCount; - /// Maximum weight of each block. With a default weight system of 1byte == 1weight, 4mb is ok. - type MaximumBlockWeight = MaximumBlockWeight; - /// Maximum size of all encoded transactions (in bytes) that are allowed in one block. - type MaximumBlockLength = MaximumBlockLength; - /// Portion of the block weight that is available to all normal transactions. - type AvailableBlockRatio = AvailableBlockRatio; - /// Runtime version. - type Version = Version; - /// Converts a module to an index of this module in the runtime. - type ModuleToIndex = ModuleToIndex; - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type DbWeight = (); - type ExtrinsicBaseWeight = ExtrinsicBaseWeight; - type BlockExecutionWeight = (); - type MaximumExtrinsicWeight = MaximumExtrinsicWeight; - type BaseCallFilter = (); - type SystemWeightInfo = (); -} - -parameter_types! { - pub const MinimumPeriod: u64 = SLOT_DURATION / 2; -} - -impl pallet_timestamp::Trait for Runtime { - /// A timestamp: milliseconds since the unix epoch. - type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = MinimumPeriod; - type WeightInfo = (); -} - -parameter_types! { - pub const ExistentialDeposit: u128 = 500; - pub const TransferFee: u128 = 0; - pub const CreationFee: u128 = 0; - pub const TransactionByteFee: u128 = 1; -} - -impl pallet_balances::Trait for Runtime { - /// The type for recording an account's balance. - type Balance = Balance; - /// The ubiquitous event type. - type Event = Event; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = (); -} - -impl pallet_transaction_payment::Trait for Runtime { - type Currency = Balances; - type OnTransactionPayment = (); - type TransactionByteFee = TransactionByteFee; - type WeightToFee = IdentityFee; - type FeeMultiplierUpdate = (); -} - -impl pallet_sudo::Trait for Runtime { - type Call = Call; - type Event = Event; -} - -impl cumulus_parachain_upgrade::Trait for Runtime { - type Event = Event; - type OnValidationFunctionParams = (); -} - -impl cumulus_message_broker::Trait for Runtime { - type Event = Event; - type DownwardMessageHandlers = TokenDealer; - type UpwardMessage = cumulus_upward_message::RococoUpwardMessage; - type ParachainId = ParachainInfo; - type XCMPMessage = cumulus_token_dealer::XCMPMessage; - type XCMPMessageHandlers = TokenDealer; -} - -impl cumulus_token_dealer::Trait for Runtime { - type Event = Event; - type UpwardMessageSender = MessageBroker; - type UpwardMessage = cumulus_upward_message::RococoUpwardMessage; - type Currency = Balances; - type XCMPMessageSender = MessageBroker; -} - -impl parachain_info::Trait for Runtime {} - -// We disable the rent system for easier testing. -parameter_types! { - pub const TombstoneDeposit: Balance = 0; - pub const RentByteFee: Balance = 0; - pub const RentDepositOffset: Balance = 0; - pub const SurchargeReward: Balance = 0; -} - -impl cumulus_pallet_contracts::Trait for Runtime { - type Time = Timestamp; - type Randomness = RandomnessCollectiveFlip; - type Currency = Balances; - type Call = Call; - type Event = Event; - type DetermineContractAddress = cumulus_pallet_contracts::SimpleAddressDeterminer; - type TrieIdGenerator = cumulus_pallet_contracts::TrieIdFromParentCounter; - type RentPayment = (); - type SignedClaimHandicap = cumulus_pallet_contracts::DefaultSignedClaimHandicap; - type TombstoneDeposit = TombstoneDeposit; - type StorageSizeOffset = cumulus_pallet_contracts::DefaultStorageSizeOffset; - type RentByteFee = RentByteFee; - type RentDepositOffset = RentDepositOffset; - type SurchargeReward = SurchargeReward; - type MaxDepth = cumulus_pallet_contracts::DefaultMaxDepth; - type MaxValueSize = cumulus_pallet_contracts::DefaultMaxValueSize; - type WeightPrice = pallet_transaction_payment::Module; -} - -construct_runtime! { - pub enum Runtime where - Block = Block, - NodeBlock = rococo_parachain_primitives::Block, - UncheckedExtrinsic = UncheckedExtrinsic - { - System: frame_system::{Module, Call, Storage, Config, Event}, - Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent}, - Balances: pallet_balances::{Module, Call, Storage, Config, Event}, - Contracts: cumulus_pallet_contracts::{Module, Call, Config, Storage, Event}, - Sudo: pallet_sudo::{Module, Call, Storage, Config, Event}, - RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage}, - ParachainUpgrade: cumulus_parachain_upgrade::{Module, Call, Storage, Inherent, Event}, - MessageBroker: cumulus_message_broker::{Module, Call, Inherent, Event}, - TokenDealer: cumulus_token_dealer::{Module, Call, Event}, - TransactionPayment: pallet_transaction_payment::{Module, Storage}, - ParachainInfo: parachain_info::{Module, Storage, Config}, - } -} - -/// The address format for describing accounts. -pub type Address = AccountId; -/// Block header type as expected by this runtime. -pub type Header = generic::Header; -/// Block type as expected by this runtime. -pub type Block = generic::Block; -/// A Block signed with a Justification -pub type SignedBlock = generic::SignedBlock; -/// BlockId type as expected by this runtime. -pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( - frame_system::CheckSpecVersion, - frame_system::CheckGenesis, - frame_system::CheckEra, - frame_system::CheckNonce, - frame_system::CheckWeight, - pallet_transaction_payment::ChargeTransactionPayment, -); -/// Unchecked extrinsic type as expected by this runtime. -pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; -/// Extrinsic type that has already been checked. -pub type CheckedExtrinsic = generic::CheckedExtrinsic; -/// Executive: handles dispatch to the various modules. -pub type Executive = frame_executive::Executive< - Runtime, - Block, - frame_system::ChainContext, - Runtime, - AllModules, ->; - -impl_runtime_apis! { - impl sp_api::Core for Runtime { - fn version() -> RuntimeVersion { - VERSION - } - - fn execute_block(block: Block) { - Executive::execute_block(block) - } - - fn initialize_block(header: &::Header) { - Executive::initialize_block(header) - } - } - - impl sp_api::Metadata for Runtime { - fn metadata() -> OpaqueMetadata { - Runtime::metadata().into() - } - } - - impl sp_block_builder::BlockBuilder for Runtime { - fn apply_extrinsic( - extrinsic: ::Extrinsic, - ) -> ApplyExtrinsicResult { - Executive::apply_extrinsic(extrinsic) - } - - fn finalize_block() -> ::Header { - Executive::finalize_block() - } - - fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { - data.create_extrinsics() - } - - fn check_inherents(block: Block, data: sp_inherents::InherentData) -> sp_inherents::CheckInherentsResult { - data.check_extrinsics(&block) - } - - fn random_seed() -> ::Hash { - RandomnessCollectiveFlip::random_seed() - } - } - - impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction( - source: TransactionSource, - tx: ::Extrinsic, - ) -> TransactionValidity { - Executive::validate_transaction(source, tx) - } - } - - impl sp_offchain::OffchainWorkerApi for Runtime { - fn offchain_worker(header: &::Header) { - Executive::offchain_worker(header) - } - } - - impl sp_session::SessionKeys for Runtime { - fn decode_session_keys( - encoded: Vec, - ) -> Option, sp_core::crypto::KeyTypeId)>> { - SessionKeys::decode_into_raw_public_keys(&encoded) - } - - fn generate_session_keys(seed: Option>) -> Vec { - SessionKeys::generate(seed) - } - } - - impl cumulus_pallet_contracts_rpc_runtime_api::ContractsApi - for Runtime - { - fn call( - origin: AccountId, - dest: AccountId, - value: Balance, - gas_limit: u64, - input_data: Vec, - ) -> ContractExecResult { - let (exec_result, gas_consumed) = - Contracts::bare_call(origin, dest.into(), value, gas_limit, input_data); - match exec_result { - Ok(v) => ContractExecResult::Success { - flags: v.status.into(), - data: v.data, - gas_consumed: gas_consumed, - }, - Err(_) => ContractExecResult::Error, - } - } - - fn get_storage( - address: AccountId, - key: [u8; 32], - ) -> cumulus_pallet_contracts_primitives::GetStorageResult { - Contracts::get_storage(address, key) - } - - fn rent_projection( - address: AccountId, - ) -> cumulus_pallet_contracts_primitives::RentProjectionResult { - Contracts::rent_projection(address) - } - } -} - -cumulus_runtime::register_validate_block!(Block, Executive); diff --git a/rococo-parachains/pallets/contracts/COMPLEXITY.md b/rococo-parachains/pallets/contracts/COMPLEXITY.md deleted file mode 100644 index 7e8c2903c7..0000000000 --- a/rococo-parachains/pallets/contracts/COMPLEXITY.md +++ /dev/null @@ -1,498 +0,0 @@ -# Complexity - -This analysis is on the computing and memory complexity of specific procedures. It provides a rough estimate of operations performed in general and especially focusing on DB reads and writes. It is also an attempt to estimate the memory consumption at its peak. - -The primary goal is to come up with decent pricing for functions that can be invoked by a user (via extrinsics) or by untrusted code that prevents DoS attacks. - -# Sandboxing - -It makes sense to describe the sandboxing module first because the smart-contract module is built upon it. - -## Memory - -### set - -Copies data from the supervisor's memory to the guest's memory. - -**complexity**: It doesn't allocate, and the computational complexity is proportional to the number of bytes to copy. - -### get - -Copies data from the guest's memory to the supervisor's memory. - -**complexity**: It doesn't allocate, and the computational complexity is proportional to the number of bytes to copy. - -## Instance - -### Instantiation - -Instantiation of a sandbox module consists of the following steps: - -1. Loading the wasm module in the in-memory representation, -2. Performing validation of the wasm code, -3. Setting up the environment which will be used to instantiate the module, -4. Performing the standard wasm instantiation process, which includes (but is not limited to): - 1. Allocating of memory requested by the instance, - 2. Copying static data from the module to newly allocated memory, - 3. Executing the `start` function. - -**Note** that the `start` function can be viewed as a normal function and can do anything that a normal function can do, including allocation of more memory or calling the host environment. The complexity of running the `start` function should be considered separately. - -In order to start the process of instantiation, the supervisor should provide the wasm module code being instantiated and the environment definition (a set of functions, memories (and maybe globals and tables in the future) available for import by the guest module) for that module. While the environment definition typically is of the constant size (unless mechanisms like dynamic linking are used), the size of wasm is not. - -Validation and instantiation in WebAssembly are designed to be able to be performed in linear time. The allocation and computational complexity of loading a wasm module depend on the underlying wasm VM being used. For example, for JIT compilers it can and probably will be non-linear because of compilation. However, for wasmi, it should be linear. We can try to use other VMs that are able to compile code with memory and time consumption proportional to the size of the code. - -Since the module itself requests memory, the amount of allocation depends on the module code itself. If untrusted code is being instantiated, it's up to the supervisor to limit the amount of memory available to allocate. - -**complexity**: The computational complexity is proportional to the size of wasm code. Memory complexity is proportional to the size of wasm code and the amount of memory requested by the module. - -### Preparation to invoke - -Invocation of an exported function in the sandboxed module consists of the following steps: - -1. Marshalling, copying and unmarshalling the arguments when passing them between the supervisor and executor, -2. Calling into the underlying VM, -3. Marshalling, copying and unmarshalling the result when passing it between the executor and supervisor, - -**Note** that the complexity of running the function code itself should be considered separately. - -The actual complexity of invocation depends on the underlying VM. Wasmi will reserve a relatively large chunk of memory for the stack before execution of the code, although it's of constant size. - -The size of the arguments and the return value depends on the exact function in question, but can be considered as constant. - -**complexity**: Memory and computational complexity can be considered as a constant. - -### Call from the guest to the supervisor - -The executor handles each call from the guest. The execution of it consists of the following steps: - -1. Marshalling, copying and unmarshalling the arguments when passing them between the guest and executor, -2. Calling into the supervisor, -3. Marshaling, copying and unmarshalling the result when passing it between the executor and guest. - -**Note** that the complexity of running the supervisor handler should be considered separately. - -Because calling into the supervisor requires invoking a wasm VM, the actual complexity of invocation depends on the actual VM used for the runtime/supervisor. Wasmi will reserve a relatively large chunk of memory for the stack before execution of the code, although it's of constant size. - -The size of the arguments and the return value depends on the exact function in question, but can be considered as a constant. - -**complexity**: Memory and computational complexity can be considered as a constant. - -# `AccountDb` - -`AccountDb` is an abstraction that supports collecting changes to accounts with the ability to efficiently reverting them. Contract -execution contexts operate on the AccountDb. All changes are flushed into underlying storage only after origin transaction succeeds. - -## Relation to the underlying storage - -At present, `AccountDb` is implemented as a cascade of overlays with the direct storage at the bottom. The direct -storage `AccountDb` leverages child tries. Each overlay is represented by a `Map`. On a commit from an overlay to an -overlay, maps are merged. On commit from an overlay to the bottommost `AccountDb` all changes are flushed to the storage -and on revert, the overlay is just discarded. - -> ℹ️ The underlying storage has a overlay layer implemented as a `Map`. If the runtime reads a storage location and the -> respective key doesn't exist in the overlay, then the underlying storage performs a DB access, but the value won't be -> placed into the overlay. The overlay is only filled with writes. -> -> This means that the overlay can be abused in the following ways: -> -> - The overlay can be inflated by issuing a lot of writes to unique locations, -> - Deliberate cache misses can be induced by reading non-modified storage locations, - -It also worth noting that the performance degrades with more state stored in the trie. Due to this -there is not negligible chance that gas schedule will be updated for all operations that involve -storage access. - -## get_storage, get_code_hash, get_rent_allowance, get_balance, contract_exists - -These functions check the local cache for a requested value and, if it is there, the value is returned. Otherwise, these functions will ask an underlying `AccountDb` for the value. This means that the number of lookups is proportional to the depth of the overlay cascade. If the value can't be found before reaching the bottommost `AccountDb`, then a DB read will be performed (in case `get_balance` the function `free_balance` will be invoked). - -A lookup in the local cache consists of at least one `Map` lookup, for locating the specific account. For `get_storage` there is a second lookup: because account's storage is implemented as a nested map, another lookup is required for fetching a storage value by a key. - -These functions return an owned value as its result, so memory usage depends on the value being returned. - -**complexity**: The memory complexity is proportional to the size of the value. The computational complexity is proportional to the depth of the overlay cascade and the size of the value; the cost is dominated by the DB read though. - -## set_storage, set_balance, set_rent_allowance - -These functions only modify the local `Map`. - -A lookup in the local cache consists of at least one `Map` lookup, for locating the specific account. For `get_storage` there is a second lookup: because account's storage is implemented as a nested map, another lookup is required for fetching a storage value by a key. - -While these functions only modify the local `Map`, if changes made by them are committed to the bottommost `AccountDb`, each changed entry in the `Map` will require a DB write. Moreover, if the balance of the account is changed to be below `existential_deposit` then that account along with all its storage will be removed, which requires time proportional to the number of storage entries that account has. It should be ensured that pricing accounts for these facts. - -**complexity**: Each lookup has a logarithmical computing time to the number of already inserted entries. No additional memory is required. - -## instantiate_contract - -Calls `contract_exists` and if it doesn't exist, do not modify the local `Map` similarly to `set_rent_allowance`. - -**complexity**: The computational complexity is proportional to the depth of the overlay cascade and the size of the value; the cost is dominated by the DB read though. No additional memory is required. - -## commit - -In this function, all cached values will be inserted into the underlying `AccountDb` or into the storage. - -We are doing `N` inserts into `Map` (`O(log M)` complexity) or into the storage, where `N` is the size of the committed `Map` and `M` is the size of the map of the underlying overlay. Consider adjusting the price of modifying the `AccountDb` to account for this (since pricing for the count of entries in `commit` will make the price of commit way less predictable). No additional memory is required. - -Note that in case of storage modification we need to construct a key in the underlying storage. In order to do that we need: - -- perform `twox_128` hashing over a concatenation of some prefix literal and the `AccountId` of the storage owner. -- then perform `blake2_256` hashing of the storage key. -- concatenation of these hashes will constitute the key in the underlying storage. - -There is also a special case to think of: if the balance of some account goes below `existential_deposit`, then all storage entries of that account will be erased, which requires time proportional to the number of storage entries that account has. - -**complexity**: `N` inserts into a `Map` or eventually into the storage (if committed). Every deleted account will induce removal of all its storage which is proportional to the number of storage entries that account has. - -## revert - -Consists of dropping (in the Rust sense) of the `AccountDb`. - -**complexity**: Computing complexity is proportional to a number of changed entries in a overlay. No additional memory is required. - -# Executive - -## Transfer - -This function performs the following steps: - -1. Querying source and destination balances from an overlay (see `get_balance`), -2. Querying `existential_deposit`. -3. Executing `ensure_account_liquid` hook. -4. Updating source and destination balance in the overlay (see `set_balance`). - -**Note** that the complexity of executing `ensure_account_liquid` hook should be considered separately. - -In the course of the execution this function can perform up to 2 DB reads to `get_balance` of source and destination accounts. It can also induce up to 2 DB writes via `set_balance` if flushed to the storage. - -Moreover, if the source balance goes below `existential_deposit` then the transfer is denied and -returns with an error. - -Assuming marshaled size of a balance value is of the constant size we can neglect its effect on the performance. - -**complexity**: up to 2 DB reads and up to 2 DB writes (if flushed to the storage) in the standard case. If removal of the source account takes place then it will additionally perform a DB write per one storage entry that the account has. For the current `AccountDb` implementation computing complexity also depends on the depth of the `AccountDb` cascade. Memorywise it can be assumed to be constant. - -## Initialization - -Before a call or instantiate can be performed the execution context must be initialized. - -For the first call or instantiation in the handling of an extrinsic, this involves two calls: - -1. `>::now()` -2. `>::block_number()` - -The complexity of initialization depends on the complexity of these functions. In the current -implementation they just involve a DB read. - -For subsequent calls and instantiations during contract execution, the initialization requires no -expensive operations. - -## Terminate - -This function performs the following steps: - -1. Check the calling contract is not already on the callstack by calling `is_live`. -2. `transfer` funds from caller to the beneficiary. -3. Flag the caller contract as deleted in the overlay. - -`is_live` does not do any database access nor does it allocate memory. It walks up the call -stack and therefore executes in linear time depending on size of the call stack. Because -the call stack is of a fixed maximum size we consider this operation as constant time. - -**complexity**: Database accesses as described in Transfer + Removal of the contract. Currently, -we are using child trie removal which is linear in the amount of stored keys. Upcoming changes -will make the account removal constant time. - - -## Call - -This function receives input data for the contract execution. The execution consists of the following steps: - -1. Initialization of the execution context. -2. Checking rent payment. -3. Loading code from the DB. -4. `transfer`-ing funds between the caller and the destination account. -5. Executing the code of the destination account. -6. Committing overlayed changed to the underlying `AccountDb`. - -**Note** that the complexity of executing the contract code should be considered separately. - -Checking for rent involves 2 unconditional DB reads: `ContractInfoOf` and `block_number` -and on top of that at most once per block: - -- DB read to `free_balance` and -- `rent_deposit_offset` and -- `rent_byte_price` and -- `Currency::minimum_balance` and -- `tombstone_deposit`. -- Calls to `ensure_can_withdraw`, `withdraw`, `make_free_balance_be` can perform arbitrary logic and should be considered separately, -- `child_storage_root` -- `kill_child_storage` -- mutation of `ContractInfoOf` - -Loading code most likely will trigger a DB read, since the code is immutable and therefore will not get into the cache (unless a suicide removes it, or it has been instantiated in the same call chain). - -Also, `transfer` can make up to 2 DB reads and up to 2 DB writes (if flushed to the storage) in the standard case. If removal of the source account takes place then it will additionally perform a DB write per one storage entry that the account has. - -Finally, all changes are `commit`-ted into the underlying overlay. The complexity of this depends on the number of changes performed by the code. Thus, the pricing of storage modification should account for that. - -**complexity**: -- Only for the first invocation of the contract: up to 5 DB reads and one DB write as well as logic executed by `ensure_can_withdraw`, `withdraw`, `make_free_balance_be`. -- On top of that for every invocation: Up to 5 DB reads. DB read of the code is of dynamic size. There can also be up to 2 DB writes (if flushed to the storage). Additionally, if the source account removal takes place a DB write will be performed per one storage entry that the account has. - -## Instantiate - -This function takes the code of the constructor and input data. Instantiation of a contract consists of the following steps: - -1. Initialization of the execution context. -2. Calling `DetermineContractAddress` hook to determine an address for the contract, -3. `transfer`-ing funds between self and the newly instantiated contract. -4. Executing the constructor code. This will yield the final code of the code. -5. Storing the code for the newly instantiated contract in the overlay. -6. Committing overlayed changed to the underlying `AccountDb`. - -**Note** that the complexity of executing the constructor code should be considered separately. - -**Note** that the complexity of `DetermineContractAddress` hook should be considered separately as well. Most likely it will use some kind of hashing over the code of the constructor and input data. The default `SimpleAddressDeterminer` does precisely that. - -**Note** that the constructor returns code in the owned form and it's obtained via return facilities, which should have take fee for the return value. - -Also, `transfer` can make up to 2 DB reads and up to 2 DB writes (if flushed to the storage) in the standard case. If removal of the source account takes place then it will additionally perform a DB write per one storage entry that the account has. - -Storing the code in the overlay may induce another DB write (if flushed to the storage) with the size proportional to the size of the constructor code. - -Finally, all changes are `commit`-ted into the underlying overlay. The complexity of this depends on the number of changes performed by the constructor code. Thus, the pricing of storage modification should account for that. - -**complexity**: Up to 2 DB reads and induces up to 3 DB writes (if flushed to the storage), one of which is dependent on the size of the code. Additionally, if the source account removal takes place a DB write will be performed per one storage entry that the account has. - -# Externalities - -Each external function invoked from a contract can involve some overhead. - -## ext_gas - -**complexity**: This is of constant complexity. - -## ext_set_storage - -This function receives a `key` and `value` as arguments. It consists of the following steps: - -1. Reading the sandbox memory for `key` and `value` (see sandboxing memory get). -2. Setting the storage at the given `key` to the given `value` (see `set_storage`). - -**complexity**: Complexity is proportional to the size of the `value`. This function induces a DB write of size proportional to the `value` size (if flushed to the storage), so should be priced accordingly. - -## ext_clear_storage - -This function receives a `key` as argument. It consists of the following steps: - -1. Reading the sandbox memory for `key` (see sandboxing memory get). -2. Clearing the storage at the given `key` (see `set_storage`). - -**complexity**: Complexity is constant. This function induces a DB write to clear the storage entry -(upon being flushed to the storage) and should be priced accordingly. - -## ext_get_storage - -This function receives a `key` as an argument. It consists of the following steps: - -1. Reading the sandbox memory for `key` (see sandboxing memory get). -2. Reading the storage with the given key (see `get_storage`). It receives back the owned result buffer. -3. Replacing the scratch buffer. - -Key is of a constant size. Therefore, the sandbox memory load can be considered to be of constant complexity. - -Unless the value is cached, a DB read will be performed. The size of the value is not known until the read is -performed. Moreover, the DB read has to be synchronous and no progress can be made until the value is fetched. - -**complexity**: The memory and computing complexity is proportional to the size of the fetched value. This function performs a -DB read. - -## ext_transfer - -This function receives the following arguments: - -- `account` buffer of a marshaled `AccountId`, -- `value` buffer of a marshaled `Balance`, - -It consists of the following steps: - -1. Loading `account` buffer from the sandbox memory (see sandboxing memory get) and then decoding it. -2. Loading `value` buffer from the sandbox memory and then decoding it. -4. Invoking the executive function `transfer`. - -Loading of `account` and `value` buffers should be charged. This is because the sizes of buffers are specified by the calling code, even though marshaled representations are, essentially, of constant size. This can be fixed by assigning an upper bound for sizes of `AccountId` and `Balance`. - -## ext_call - -This function receives the following arguments: - -- `callee` buffer of a marshaled `AccountId`, -- `gas` limit which is plain u64, -- `value` buffer of a marshaled `Balance`, -- `input_data`. An arbitrarily sized byte vector. - -It consists of the following steps: - -1. Loading `callee` buffer from the sandbox memory (see sandboxing memory get) and then decoding it. -2. Loading `value` buffer from the sandbox memory and then decoding it. -3. Loading `input_data` buffer from the sandbox memory. -4. Invoking the executive function `call`. - -Loading of `callee` and `value` buffers should be charged. This is because the sizes of buffers are specified by the calling code, even though marshaled representations are, essentially, of constant size. This can be fixed by assigning an upper bound for sizes of `AccountId` and `Balance`. - -Loading `input_data` should be charged in any case. - -**complexity**: All complexity comes from loading buffers and executing `call` executive function. The former component is proportional to the sizes of `callee`, `value` and `input_data` buffers. The latter component completely depends on the complexity of `call` executive function, and also dominated by it. - -## ext_instantiate - -This function receives the following arguments: - -- `init_code`, a buffer which contains the code of the constructor. -- `gas` limit which is plain u64 -- `value` buffer of a marshaled `Balance` -- `input_data`. an arbitrarily sized byte vector. - -It consists of the following steps: - -1. Loading `init_code` buffer from the sandbox memory (see sandboxing memory get) and then decoding it. -2. Loading `value` buffer from the sandbox memory and then decoding it. -3. Loading `input_data` buffer from the sandbox memory. -4. Invoking `instantiate` executive function. - -Loading of `value` buffer should be charged. This is because the size of the buffer is specified by the calling code, even though marshaled representation is, essentially, of constant size. This can be fixed by assigning an upper bound for size for `Balance`. - -Loading `init_code` and `input_data` should be charged in any case. - -**complexity**: All complexity comes from loading buffers and executing `instantiate` executive function. The former component is proportional to the sizes of `init_code`, `value` and `input_data` buffers. The latter component completely depends on the complexity of `instantiate` executive function and also dominated by it. - -## ext_terminate - -This function receives the following arguments: - -- `beneficiary`, buffer of a marshaled `AccountId` - -It consists of the following steps: - -1. Loading `beneficiary` buffer from the sandbox memory (see sandboxing memory get) and then decoding it. - -Loading of the `beneficiary` buffer should be charged. This is because the sizes of buffers are specified by the calling code, even though marshaled representations are, essentially, of constant size. This can be fixed by assigning an upper bound for sizes of `AccountId`. - -**complexity**: All complexity comes from loading buffers and executing `terminate` executive function. The former component is proportional to the size of the `beneficiary` buffer. The latter component completely depends on the complexity of `terminate` executive function and also dominated by it. - -## ext_return - -This function receives a `data` buffer as an argument. Execution of the function consists of the following steps: - -1. Loading `data` buffer from the sandbox memory (see sandboxing memory get), -2. Trapping - -**complexity**: The complexity of this function is proportional to the size of the `data` buffer. - -## ext_deposit_event - -This function receives a `data` buffer as an argument. Execution of the function consists of the following steps: - -1. Loading `data` buffer from the sandbox memory (see sandboxing memory get), -2. Insert to nested context execution -3. Copies from nested to underlying contexts -4. Call system deposit event - -**complexity**: The complexity of this function is proportional to the size of the `data` buffer. - -## ext_caller - -This function serializes the address of the caller into the scratch buffer. - -**complexity**: Assuming that the address is of constant size, this function has constant complexity. - -## ext_random - -This function serializes a random number generated by the given subject into the scratch buffer. -The complexity of this function highly depends on the complexity of `System::random`. `max_subject_len` -limits the size of the subject buffer. - -**complexity**: The complexity of this function depends on the implementation of `System::random`. - -## ext_now - -This function serializes the current block's timestamp into the scratch buffer. - -**complexity**: Assuming that the timestamp is of constant size, this function has constant complexity. - -## ext_scratch_size - -This function returns the size of the scratch buffer. - -**complexity**: This function is of constant complexity. - -## ext_scratch_read - -This function copies slice of data from the scratch buffer to the sandbox memory. The calling code specifies the slice length. Execution of the function consists of the following steps: - -1. Storing a specified slice of the scratch buffer into the sandbox memory (see sandboxing memory set) - -**complexity**: The computing complexity of this function is proportional to the length of the slice. No additional memory is required. - -## ext_scratch_write - -This function copies slice of data from the sandbox memory to the scratch buffer. The calling code specifies the slice length. Execution of the function consists of the following steps: - -1. Loading a slice from the sandbox memory into the (see sandboxing memory get) - -**complexity**: Complexity is proportional to the length of the slice. - -## ext_set_rent_allowance - -This function receives the following argument: - -- `value` buffer of a marshaled `Balance`, - -It consists of the following steps: - -1. Loading `value` buffer from the sandbox memory and then decoding it. -2. Invoking `set_rent_allowance` AccountDB function. - -**complexity**: Complexity is proportional to the size of the `value`. This function induces a DB write of size proportional to the `value` size (if flushed to the storage), so should be priced accordingly. - -## ext_rent_allowance - -It consists of the following steps: - -1. Invoking `get_rent_allowance` AccountDB function. -2. Serializing the rent allowance of the current contract into the scratch buffer. - -**complexity**: Assuming that the rent allowance is of constant size, this function has constant complexity. This -function performs a DB read. - -## ext_block_number - -This function serializes the current block's number into the scratch buffer. - -**complexity**: Assuming that the block number is of constant size, this function has constant complexity. - -## Built-in hashing functions - -This paragraph concerns the following supported built-in hash functions: - -- `SHA2` with 256-bit width -- `KECCAK` with 256-bit width -- `BLAKE2` with 128-bit and 256-bit widths - -These functions compute a cryptographic hash on the given inputs and copy the -resulting hash directly back into the sandboxed Wasm contract output buffer. - -Execution of the function consists of the following steps: - -1. Load data stored in the input buffer into an intermediate buffer. -2. Compute the cryptographic hash `H` on the intermediate buffer. -3. Copy back the bytes of `H` into the contract side output buffer. - -**complexity**: Complexity is proportional to the size of the input buffer in bytes -as well as to the size of the output buffer in bytes. Also different cryptographic -algorithms have different inherent complexity so users must expect the above -mentioned crypto hashes to have varying gas costs. -The complexity of each cryptographic hash function highly depends on the underlying -implementation. diff --git a/rococo-parachains/pallets/contracts/Cargo.toml b/rococo-parachains/pallets/contracts/Cargo.toml deleted file mode 100644 index e53fc8c20e..0000000000 --- a/rococo-parachains/pallets/contracts/Cargo.toml +++ /dev/null @@ -1,53 +0,0 @@ -[package] -name = "cumulus-pallet-contracts" -version = "2.0.0-rc3" -authors = ["Parity Technologies "] -edition = "2018" -license = "Apache-2.0" -homepage = "https://substrate.dev" -repository = "https://github.com/paritytech/substrate/" -description = "FRAME pallet for WASM contracts" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -serde = { version = "1.0.101", optional = true, features = ["derive"] } -pwasm-utils = { version = "0.12.0", default-features = false } -codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } -parity-wasm = { version = "0.41.0", default-features = false } -wasmi-validation = { version = "0.3.0", default-features = false } -sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-sandbox = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -cumulus-pallet-contracts-primitives = { path = "./common", default-features = false } - -[dev-dependencies] -wabt = "0.10" -assert_matches = "1.3.0" -hex-literal = "0.2.1" -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } - -[features] -default = ["std"] -std = [ - "serde", - "codec/std", - "sp-core/std", - "sp-runtime/std", - "sp-io/std", - "sp-std/std", - "sp-sandbox/std", - "frame-support/std", - "frame-system/std", - "parity-wasm/std", - "pwasm-utils/std", - "wasmi-validation/std", - "cumulus-pallet-contracts-primitives/std", -] diff --git a/rococo-parachains/pallets/contracts/common/Cargo.toml b/rococo-parachains/pallets/contracts/common/Cargo.toml deleted file mode 100644 index 17e9f8d4a3..0000000000 --- a/rococo-parachains/pallets/contracts/common/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "cumulus-pallet-contracts-primitives" -version = "2.0.0-rc3" -authors = ["Parity Technologies "] -edition = "2018" -license = "Apache-2.0" -homepage = "https://substrate.dev" -repository = "https://github.com/paritytech/substrate/" -description = "A crate that hosts a common definitions that are relevant for the pallet-contracts." - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -# This crate should not rely on any of the frame primitives. -codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } -sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } - -[features] -default = ["std"] -std = [ - "codec/std", - "sp-runtime/std", - "sp-std/std", -] diff --git a/rococo-parachains/pallets/contracts/common/src/lib.rs b/rococo-parachains/pallets/contracts/common/src/lib.rs deleted file mode 100644 index 6a74a417fa..0000000000 --- a/rococo-parachains/pallets/contracts/common/src/lib.rs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! A crate that hosts a common definitions that are relevant for the pallet-contracts. - -#![cfg_attr(not(feature = "std"), no_std)] - -use sp_std::prelude::*; - -/// A result type of a get storage call. -pub type GetStorageResult = Result>, ContractAccessError>; - -/// The possible errors that can happen querying the storage of a contract. -#[derive(Eq, PartialEq, codec::Encode, codec::Decode, sp_runtime::RuntimeDebug)] -pub enum ContractAccessError { - /// The given address doesn't point to a contract. - DoesntExist, - /// The specified contract is a tombstone and thus cannot have any storage. - IsTombstone, -} - -/// A result type of a `rent_projection` call. -pub type RentProjectionResult = - Result, ContractAccessError>; - -#[derive(Eq, PartialEq, codec::Encode, codec::Decode, sp_runtime::RuntimeDebug)] -pub enum RentProjection { - /// Eviction is projected to happen at the specified block number. - EvictionAt(BlockNumber), - /// No eviction is scheduled. - /// - /// E.g. because the contract accumulated enough funds to offset the rent storage costs. - NoEviction, -} diff --git a/rococo-parachains/pallets/contracts/fixtures/caller_contract.wat b/rococo-parachains/pallets/contracts/fixtures/caller_contract.wat deleted file mode 100644 index 4bc122c0b1..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/caller_contract.wat +++ /dev/null @@ -1,275 +0,0 @@ -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_balance" (func $ext_balance)) - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "ext_println" (func $ext_println (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func $current_balance (param $sp i32) (result i64) - (call $ext_balance) - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 8)) - ) - (call $ext_scratch_read - (i32.sub (get_local $sp) (i32.const 8)) - (i32.const 0) - (i32.const 8) - ) - (i64.load (i32.sub (get_local $sp) (i32.const 8))) - ) - - (func (export "deploy")) - - (func (export "call") - (local $sp i32) - (local $exit_code i32) - (local $balance i64) - - ;; Input data is the code hash of the contract to be deployed. - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 32) - ) - ) - - ;; Copy code hash from scratch buffer into this contract's memory. - (call $ext_scratch_read - (i32.const 24) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 32) ;; Count of bytes to copy. - ) - - ;; Read current balance into local variable. - (set_local $sp (i32.const 1024)) - (set_local $balance - (call $current_balance (get_local $sp)) - ) - - ;; Fail to deploy the contract since it returns a non-zero exit status. - (set_local $exit_code - (call $ext_instantiate - (i32.const 24) ;; Pointer to the code hash. - (i32.const 32) ;; Length of the code hash. - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 9) ;; Pointer to input data buffer address - (i32.const 7) ;; Length of input data buffer - ) - ) - - ;; Check non-zero exit status. - (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x11)) - ) - - ;; Check that scratch buffer is empty since contract instantiation failed. - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 0)) - ) - - ;; Check that balance has not changed. - (call $assert - (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) - ) - - ;; Fail to deploy the contract due to insufficient gas. - (set_local $exit_code - (call $ext_instantiate - (i32.const 24) ;; Pointer to the code hash. - (i32.const 32) ;; Length of the code hash. - (i64.const 200) ;; How much gas to devote for the execution. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 8) ;; Pointer to input data buffer address - (i32.const 8) ;; Length of input data buffer - ) - ) - - ;; Check for special trap exit status. - (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x0100)) - ) - - ;; Check that scratch buffer is empty since contract instantiation failed. - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 0)) - ) - - ;; Check that balance has not changed. - (call $assert - (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) - ) - - ;; Deploy the contract successfully. - (set_local $exit_code - (call $ext_instantiate - (i32.const 24) ;; Pointer to the code hash. - (i32.const 32) ;; Length of the code hash. - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 8) ;; Pointer to input data buffer address - (i32.const 8) ;; Length of input data buffer - ) - ) - - ;; Check for success exit status. - (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x00)) - ) - - ;; Check that scratch buffer contains the address of the new contract. - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 8)) - ) - - ;; Copy contract address from scratch buffer into this contract's memory. - (call $ext_scratch_read - (i32.const 16) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; Check that balance has been deducted. - (set_local $balance - (i64.sub (get_local $balance) (i64.load (i32.const 0))) - ) - (call $assert - (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) - ) - - ;; Call the new contract and expect it to return failing exit code. - (set_local $exit_code - (call $ext_call - (i32.const 16) ;; Pointer to "callee" address. - (i32.const 8) ;; Length of "callee" address. - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 9) ;; Pointer to input data buffer address - (i32.const 7) ;; Length of input data buffer - ) - ) - - ;; Check non-zero exit status. - (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x11)) - ) - - ;; Check that scratch buffer contains the expected return data. - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 3)) - ) - (i32.store - (i32.sub (get_local $sp) (i32.const 4)) - (i32.const 0) - ) - (call $ext_scratch_read - (i32.sub (get_local $sp) (i32.const 4)) - (i32.const 0) - (i32.const 3) - ) - (call $assert - (i32.eq - (i32.load (i32.sub (get_local $sp) (i32.const 4))) - (i32.const 0x00776655) - ) - ) - - ;; Check that balance has not changed. - (call $assert - (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) - ) - - ;; Fail to call the contract due to insufficient gas. - (set_local $exit_code - (call $ext_call - (i32.const 16) ;; Pointer to "callee" address. - (i32.const 8) ;; Length of "callee" address. - (i64.const 100) ;; How much gas to devote for the execution. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 8) ;; Pointer to input data buffer address - (i32.const 8) ;; Length of input data buffer - ) - ) - - ;; Check for special trap exit status. - (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x0100)) - ) - - ;; Check that scratch buffer is empty since call trapped. - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 0)) - ) - - ;; Check that balance has not changed. - (call $assert - (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) - ) - - ;; Call the contract successfully. - (set_local $exit_code - (call $ext_call - (i32.const 16) ;; Pointer to "callee" address. - (i32.const 8) ;; Length of "callee" address. - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 8) ;; Pointer to input data buffer address - (i32.const 8) ;; Length of input data buffer - ) - ) - - ;; Check for success exit status. - (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x00)) - ) - - ;; Check that scratch buffer contains the expected return data. - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 4)) - ) - (i32.store - (i32.sub (get_local $sp) (i32.const 4)) - (i32.const 0) - ) - (call $ext_scratch_read - (i32.sub (get_local $sp) (i32.const 4)) - (i32.const 0) - (i32.const 4) - ) - (call $assert - (i32.eq - (i32.load (i32.sub (get_local $sp) (i32.const 4))) - (i32.const 0x77665544) - ) - ) - - ;; Check that balance has been deducted. - (set_local $balance - (i64.sub (get_local $balance) (i64.load (i32.const 0))) - ) - (call $assert - (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) - ) - ) - - (data (i32.const 0) "\00\80") ;; The value to transfer on instantiation and calls. - ;; Chosen to be greater than existential deposit. - (data (i32.const 8) "\00\11\22\33\44\55\66\77") ;; The input data to instantiations and calls. -) diff --git a/rococo-parachains/pallets/contracts/fixtures/check_default_rent_allowance.wat b/rococo-parachains/pallets/contracts/fixtures/check_default_rent_allowance.wat deleted file mode 100644 index 12b3004adf..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/check_default_rent_allowance.wat +++ /dev/null @@ -1,47 +0,0 @@ -(module - (import "env" "ext_rent_allowance" (func $ext_rent_allowance)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call")) - - (func (export "deploy") - ;; fill the scratch buffer with the rent allowance. - (call $ext_rent_allowance) - - ;; assert $ext_scratch_size == 8 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to >::max_value(). - (call $assert - (i64.eq - (i64.load - (i32.const 8) - ) - (i64.const 0xFFFFFFFFFFFFFFFF) - ) - ) - ) -) diff --git a/rococo-parachains/pallets/contracts/fixtures/crypto_hashes.wat b/rococo-parachains/pallets/contracts/fixtures/crypto_hashes.wat deleted file mode 100644 index 6dbca33928..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/crypto_hashes.wat +++ /dev/null @@ -1,80 +0,0 @@ -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) - - (import "env" "ext_hash_sha2_256" (func $ext_hash_sha2_256 (param i32 i32 i32))) - (import "env" "ext_hash_keccak_256" (func $ext_hash_keccak_256 (param i32 i32 i32))) - (import "env" "ext_hash_blake2_256" (func $ext_hash_blake2_256 (param i32 i32 i32))) - (import "env" "ext_hash_blake2_128" (func $ext_hash_blake2_128 (param i32 i32 i32))) - - (import "env" "memory" (memory 1 1)) - - (type $hash_fn_sig (func (param i32 i32 i32))) - (table 8 funcref) - (elem (i32.const 1) - $ext_hash_sha2_256 - $ext_hash_keccak_256 - $ext_hash_blake2_256 - $ext_hash_blake2_128 - ) - (data (i32.const 1) "20202010201008") ;; Output sizes of the hashes in order in hex. - - ;; Not in use by the tests besides instantiating the contract. - (func (export "deploy")) - - ;; Called by the tests. - ;; - ;; The `call` function expects data in a certain format in the scratch - ;; buffer. - ;; - ;; 1. The first byte encodes an identifier for the crypto hash function - ;; under test. (*) - ;; 2. The rest encodes the input data that is directly fed into the - ;; crypto hash function chosen in 1. - ;; - ;; The `deploy` function then computes the chosen crypto hash function - ;; given the input and puts the result back into the scratch buffer. - ;; After contract execution the test driver then asserts that the returned - ;; values are equal to the expected bytes for the input and chosen hash - ;; function. - ;; - ;; (*) The possible value for the crypto hash identifiers can be found below: - ;; - ;; | value | Algorithm | Bit Width | - ;; |-------|-----------|-----------| - ;; | 0 | SHA2 | 256 | - ;; | 1 | KECCAK | 256 | - ;; | 2 | BLAKE2 | 256 | - ;; | 3 | BLAKE2 | 128 | - ;; --------------------------------- - (func (export "call") (result i32) - (local $chosen_hash_fn i32) - (local $input_ptr i32) - (local $input_len i32) - (local $output_ptr i32) - (local $output_len i32) - (local.set $input_ptr (i32.const 10)) - (call $ext_scratch_read (local.get $input_ptr) (i32.const 0) (call $ext_scratch_size)) - (local.set $chosen_hash_fn (i32.load8_u (local.get $input_ptr))) - (if (i32.gt_u (local.get $chosen_hash_fn) (i32.const 7)) - ;; We check that the chosen hash fn identifier is within bounds: [0,7] - (unreachable) - ) - (local.set $input_ptr (i32.add (local.get $input_ptr) (i32.const 1))) - (local.set $input_len (i32.sub (call $ext_scratch_size) (i32.const 1))) - (local.set $output_ptr (i32.const 100)) - (local.set $output_len (i32.load8_u (local.get $chosen_hash_fn))) - (call_indirect (type $hash_fn_sig) - (local.get $input_ptr) - (local.get $input_len) - (local.get $output_ptr) - (local.get $chosen_hash_fn) ;; Which crypto hash function to execute. - ) - (call $ext_scratch_write - (local.get $output_ptr) ;; Linear memory location of the output buffer. - (local.get $output_len) ;; Number of output buffer bytes. - ) - (i32.const 0) - ) -) diff --git a/rococo-parachains/pallets/contracts/fixtures/destroy_and_transfer.wat b/rococo-parachains/pallets/contracts/fixtures/destroy_and_transfer.wat deleted file mode 100644 index c8cf7271d7..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/destroy_and_transfer.wat +++ /dev/null @@ -1,148 +0,0 @@ -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_get_storage" (func $ext_get_storage (param i32) (result i32))) - (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "deploy") - ;; Input data is the code hash of the contract to be deployed. - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 32) - ) - ) - - ;; Copy code hash from scratch buffer into this contract's memory. - (call $ext_scratch_read - (i32.const 48) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 32) ;; Count of bytes to copy. - ) - - ;; Deploy the contract with the provided code hash. - (call $assert - (i32.eq - (call $ext_instantiate - (i32.const 48) ;; Pointer to the code hash. - (i32.const 32) ;; Length of the code hash. - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - ) - (i32.const 0) - ) - ) - - ;; Read the address of the instantiated contract into memory. - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - (call $ext_scratch_read - (i32.const 80) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; Store the return address. - (call $ext_set_storage - (i32.const 16) ;; Pointer to the key - (i32.const 80) ;; Pointer to the value - (i32.const 8) ;; Length of the value - ) - ) - - (func (export "call") - ;; Read address of destination contract from storage. - (call $assert - (i32.eq - (call $ext_get_storage - (i32.const 16) ;; Pointer to the key - ) - (i32.const 0) - ) - ) - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - (call $ext_scratch_read - (i32.const 80) ;; The pointer where to store the contract address. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; Calling the destination contract with non-empty input data should fail. - (call $assert - (i32.eq - (call $ext_call - (i32.const 80) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 1) ;; Length of input data buffer - ) - (i32.const 0x0100) - ) - ) - - ;; Call the destination contract regularly, forcing it to self-destruct. - (call $assert - (i32.eq - (call $ext_call - (i32.const 80) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 8) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - ) - (i32.const 0) - ) - ) - - ;; Calling the destination address with non-empty input data should now work since the - ;; contract has been removed. Also transfer a balance to the address so we can ensure this - ;; does not keep the contract alive. - (call $assert - (i32.eq - (call $ext_call - (i32.const 80) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 1) ;; Length of input data buffer - ) - (i32.const 0) - ) - ) - ) - - (data (i32.const 0) "\00\00\01") ;; Endowment to send when creating contract. - (data (i32.const 8) "") ;; Value to send when calling contract. - (data (i32.const 16) "") ;; The key to store the contract address under. -) diff --git a/rococo-parachains/pallets/contracts/fixtures/dispatch_call.wat b/rococo-parachains/pallets/contracts/fixtures/dispatch_call.wat deleted file mode 100644 index db0995bd6c..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/dispatch_call.wat +++ /dev/null @@ -1,14 +0,0 @@ -(module - (import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "call") - (call $ext_dispatch_call - (i32.const 8) ;; Pointer to the start of encoded call buffer - (i32.const 11) ;; Length of the buffer - ) - ) - (func (export "deploy")) - - (data (i32.const 8) "\00\00\03\00\00\00\00\00\00\00\C8") -) diff --git a/rococo-parachains/pallets/contracts/fixtures/dispatch_call_then_trap.wat b/rococo-parachains/pallets/contracts/fixtures/dispatch_call_then_trap.wat deleted file mode 100644 index ce949d6823..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/dispatch_call_then_trap.wat +++ /dev/null @@ -1,15 +0,0 @@ -(module - (import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "call") - (call $ext_dispatch_call - (i32.const 8) ;; Pointer to the start of encoded call buffer - (i32.const 11) ;; Length of the buffer - ) - (unreachable) ;; trap so that the top level transaction fails - ) - (func (export "deploy")) - - (data (i32.const 8) "\00\00\03\00\00\00\00\00\00\00\C8") -) diff --git a/rococo-parachains/pallets/contracts/fixtures/drain.wat b/rococo-parachains/pallets/contracts/fixtures/drain.wat deleted file mode 100644 index d08e1dd0d2..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/drain.wat +++ /dev/null @@ -1,54 +0,0 @@ -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_balance" (func $ext_balance)) - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "deploy")) - - (func (export "call") - ;; Send entire remaining balance to the 0 address. - (call $ext_balance) - - ;; Balance should be encoded as a u64. - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; Read balance into memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer to write balance to - (i32.const 0) ;; Offset into scratch buffer - (i32.const 8) ;; Length of encoded balance - ) - - ;; Self-destruct by sending full balance to the 0 address. - (call $assert - (i32.eq - (call $ext_call - (i32.const 0) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 8) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - ) - (i32.const 0) - ) - ) - ) -) diff --git a/rococo-parachains/pallets/contracts/fixtures/get_runtime_storage.wat b/rococo-parachains/pallets/contracts/fixtures/get_runtime_storage.wat deleted file mode 100644 index 6148f1c408..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/get_runtime_storage.wat +++ /dev/null @@ -1,74 +0,0 @@ -(module - (import "env" "ext_get_runtime_storage" - (func $ext_get_runtime_storage (param i32 i32) (result i32)) - ) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "deploy")) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func $call (export "call") - ;; Load runtime storage for the first key and assert that it exists. - (call $assert - (i32.eq - (call $ext_get_runtime_storage - (i32.const 16) - (i32.const 4) - ) - (i32.const 0) - ) - ) - - ;; assert $ext_scratch_size == 4 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 4) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 4) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 4) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to the i32 value of 0x14144020. - (call $assert - (i32.eq - (i32.load - (i32.const 4) - ) - (i32.const 0x14144020) - ) - ) - - ;; Load the second key and assert that it doesn't exist. - (call $assert - (i32.eq - (call $ext_get_runtime_storage - (i32.const 20) - (i32.const 4) - ) - (i32.const 1) - ) - ) - ) - - ;; The first key, 4 bytes long. - (data (i32.const 16) "\01\02\03\04") - ;; The second key, 4 bytes long. - (data (i32.const 20) "\02\03\04\05") -) diff --git a/rococo-parachains/pallets/contracts/fixtures/restoration.wat b/rococo-parachains/pallets/contracts/fixtures/restoration.wat deleted file mode 100644 index 4e11f97d5a..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/restoration.wat +++ /dev/null @@ -1,56 +0,0 @@ -(module - (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) - (import "env" "ext_restore_to" (func $ext_restore_to (param i32 i32 i32 i32 i32 i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "call") - (call $ext_restore_to - ;; Pointer and length of the encoded dest buffer. - (i32.const 256) - (i32.const 8) - ;; Pointer and length of the encoded code hash buffer - (i32.const 264) - (i32.const 32) - ;; Pointer and length of the encoded rent_allowance buffer - (i32.const 296) - (i32.const 8) - ;; Pointer and number of items in the delta buffer. - ;; This buffer specifies multiple keys for removal before restoration. - (i32.const 100) - (i32.const 1) - ) - ) - (func (export "deploy") - ;; Data to restore - (call $ext_set_storage - (i32.const 0) - (i32.const 0) - (i32.const 4) - ) - - ;; ACL - (call $ext_set_storage - (i32.const 100) - (i32.const 0) - (i32.const 4) - ) - ) - - ;; Data to restore - (data (i32.const 0) "\28") - - ;; Buffer that has ACL storage keys. - (data (i32.const 100) "\01") - - ;; Address of bob - (data (i32.const 256) "\02\00\00\00\00\00\00\00") - - ;; Code hash of SET_RENT - (data (i32.const 264) - "\c2\1c\41\10\a5\22\d8\59\1c\4c\77\35\dd\2d\bf\a1" - "\13\0b\50\93\76\9b\92\31\97\b7\c5\74\26\aa\38\2a" - ) - - ;; Rent allowance - (data (i32.const 296) "\32\00\00\00\00\00\00\00") -) diff --git a/rococo-parachains/pallets/contracts/fixtures/return_from_start_fn.wat b/rococo-parachains/pallets/contracts/fixtures/return_from_start_fn.wat deleted file mode 100644 index ac898d4d94..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/return_from_start_fn.wat +++ /dev/null @@ -1,27 +0,0 @@ -(module - (import "env" "ext_return" (func $ext_return (param i32 i32))) - (import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (start $start) - (func $start - (call $ext_deposit_event - (i32.const 0) ;; The topics buffer - (i32.const 0) ;; The topics buffer's length - (i32.const 8) ;; The data buffer - (i32.const 4) ;; The data buffer's length - ) - (call $ext_return - (i32.const 8) - (i32.const 4) - ) - (unreachable) - ) - - (func (export "call") - (unreachable) - ) - (func (export "deploy")) - - (data (i32.const 8) "\01\02\03\04") -) diff --git a/rococo-parachains/pallets/contracts/fixtures/return_with_data.wat b/rococo-parachains/pallets/contracts/fixtures/return_with_data.wat deleted file mode 100644 index 8cc84006a0..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/return_with_data.wat +++ /dev/null @@ -1,39 +0,0 @@ -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; Deploy routine is the same as call. - (func (export "deploy") (result i32) - (call $call) - ) - - ;; Call reads the first 4 bytes (LE) as the exit status and returns the rest as output data. - (func $call (export "call") (result i32) - (local $buf_size i32) - (local $exit_status i32) - - ;; Find out the size of the scratch buffer - (set_local $buf_size (call $ext_scratch_size)) - - ;; Copy scratch buffer into this contract memory. - (call $ext_scratch_read - (i32.const 0) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (get_local $buf_size) ;; Count of bytes to copy. - ) - - ;; Copy all but the first 4 bytes of the input data as the output data. - (call $ext_scratch_write - (i32.const 4) ;; Pointer to the data to return. - (i32.sub ;; Count of bytes to copy. - (get_local $buf_size) - (i32.const 4) - ) - ) - - ;; Return the first 4 bytes of the input data as the exit status. - (i32.load (i32.const 0)) - ) -) diff --git a/rococo-parachains/pallets/contracts/fixtures/run_out_of_gas.wat b/rococo-parachains/pallets/contracts/fixtures/run_out_of_gas.wat deleted file mode 100644 index 52ee92539f..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/run_out_of_gas.wat +++ /dev/null @@ -1,7 +0,0 @@ -(module - (func (export "call") - (loop $inf (br $inf)) ;; just run out of gas - (unreachable) - ) - (func (export "deploy")) -) diff --git a/rococo-parachains/pallets/contracts/fixtures/self_destruct.wat b/rococo-parachains/pallets/contracts/fixtures/self_destruct.wat deleted file mode 100644 index 464b5c663e..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/self_destruct.wat +++ /dev/null @@ -1,72 +0,0 @@ -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_address" (func $ext_address)) - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "ext_terminate" (func $ext_terminate (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "deploy")) - - (func (export "call") - ;; If the input data is not empty, then recursively call self with empty input data. - ;; This should trap instead of self-destructing since a contract cannot be removed live in - ;; the execution stack cannot be removed. If the recursive call traps, then trap here as - ;; well. - (if (call $ext_scratch_size) - (then - (call $ext_address) - - ;; Expect address to be 8 bytes. - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; Read own address into memory. - (call $ext_scratch_read - (i32.const 16) ;; Pointer to write address to - (i32.const 0) ;; Offset into scratch buffer - (i32.const 8) ;; Length of encoded address - ) - - ;; Recursively call self with empty input data. - (call $assert - (i32.eq - (call $ext_call - (i32.const 16) ;; Pointer to own address - (i32.const 8) ;; Length of own address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 8) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - ) - (i32.const 0) - ) - ) - ) - (else - ;; Try to terminate and give balance to django. - (call $ext_terminate - (i32.const 32) ;; Pointer to beneficiary address - (i32.const 8) ;; Length of beneficiary address - ) - (unreachable) ;; ext_terminate never returns - ) - ) - ) - ;; Address of django - (data (i32.const 32) "\04\00\00\00\00\00\00\00") -) diff --git a/rococo-parachains/pallets/contracts/fixtures/self_destructing_constructor.wat b/rococo-parachains/pallets/contracts/fixtures/self_destructing_constructor.wat deleted file mode 100644 index b19d6e5b50..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/self_destructing_constructor.wat +++ /dev/null @@ -1,54 +0,0 @@ -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_balance" (func $ext_balance)) - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "deploy") - ;; Send entire remaining balance to the 0 address. - (call $ext_balance) - - ;; Balance should be encoded as a u64. - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; Read balance into memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer to write balance to - (i32.const 0) ;; Offset into scratch buffer - (i32.const 8) ;; Length of encoded balance - ) - - ;; Self-destruct by sending full balance to the 0 address. - (call $assert - (i32.eq - (call $ext_call - (i32.const 0) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 8) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - ) - (i32.const 0) - ) - ) - ) - - (func (export "call")) -) diff --git a/rococo-parachains/pallets/contracts/fixtures/set_empty_storage.wat b/rococo-parachains/pallets/contracts/fixtures/set_empty_storage.wat deleted file mode 100644 index d550eb2314..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/set_empty_storage.wat +++ /dev/null @@ -1,15 +0,0 @@ -;; This module stores a KV pair into the storage -(module - (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) - (import "env" "memory" (memory 16 16)) - - (func (export "call") - ) - (func (export "deploy") - (call $ext_set_storage - (i32.const 0) ;; Pointer to storage key - (i32.const 0) ;; Pointer to value - (i32.load (i32.const 0)) ;; Size of value - ) - ) -) diff --git a/rococo-parachains/pallets/contracts/fixtures/set_rent.wat b/rococo-parachains/pallets/contracts/fixtures/set_rent.wat deleted file mode 100644 index d1affa0d74..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/set_rent.wat +++ /dev/null @@ -1,101 +0,0 @@ -(module - (import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32))) - (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) - (import "env" "ext_clear_storage" (func $ext_clear_storage (param i32))) - (import "env" "ext_set_rent_allowance" (func $ext_set_rent_allowance (param i32 i32))) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; insert a value of 4 bytes into storage - (func $call_0 - (call $ext_set_storage - (i32.const 1) - (i32.const 0) - (i32.const 4) - ) - ) - - ;; remove the value inserted by call_1 - (func $call_1 - (call $ext_clear_storage - (i32.const 1) - ) - ) - - ;; transfer 50 to ALICE - (func $call_2 - (call $ext_dispatch_call - (i32.const 68) - (i32.const 11) - ) - ) - - ;; do nothing - (func $call_else) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - ;; Dispatch the call according to input size - (func (export "call") - (local $input_size i32) - (set_local $input_size - (call $ext_scratch_size) - ) - (block $IF_ELSE - (block $IF_2 - (block $IF_1 - (block $IF_0 - (br_table $IF_0 $IF_1 $IF_2 $IF_ELSE - (get_local $input_size) - ) - (unreachable) - ) - (call $call_0) - return - ) - (call $call_1) - return - ) - (call $call_2) - return - ) - (call $call_else) - ) - - ;; Set into storage a 4 bytes value - ;; Set call set_rent_allowance with input - (func (export "deploy") - (local $input_size i32) - (set_local $input_size - (call $ext_scratch_size) - ) - (call $ext_set_storage - (i32.const 0) - (i32.const 0) - (i32.const 4) - ) - (call $ext_scratch_read - (i32.const 0) - (i32.const 0) - (get_local $input_size) - ) - (call $ext_set_rent_allowance - (i32.const 0) - (get_local $input_size) - ) - ) - - ;; Encoding of 10 in balance - (data (i32.const 0) "\28") - - ;; Encoding of call transfer 50 to CHARLIE - (data (i32.const 68) "\00\00\03\00\00\00\00\00\00\00\C8") -) diff --git a/rococo-parachains/pallets/contracts/fixtures/storage_size.wat b/rococo-parachains/pallets/contracts/fixtures/storage_size.wat deleted file mode 100644 index 8de9f42ee9..0000000000 --- a/rococo-parachains/pallets/contracts/fixtures/storage_size.wat +++ /dev/null @@ -1,60 +0,0 @@ -(module - (import "env" "ext_get_storage" (func $ext_get_storage (param i32) (result i32))) - (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 16 16)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; assert $ext_scratch_size == 8 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 4) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 32) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 4) ;; Count of bytes to copy. - ) - - ;; place a garbage value in storage, the size of which is specified by the call input. - (call $ext_set_storage - (i32.const 0) ;; Pointer to storage key - (i32.const 0) ;; Pointer to value - (i32.load (i32.const 32)) ;; Size of value - ) - - (call $assert - (i32.eq - (call $ext_get_storage - (i32.const 0) ;; Pointer to storage key - ) - (i32.const 0) - ) - ) - - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.load (i32.const 32)) - ) - ) - ) - - (func (export "deploy")) - - (data (i32.const 0) "\01") ;; Storage key (32 B) -) diff --git a/rococo-parachains/pallets/contracts/rpc/Cargo.toml b/rococo-parachains/pallets/contracts/rpc/Cargo.toml deleted file mode 100644 index 127c3202ef..0000000000 --- a/rococo-parachains/pallets/contracts/rpc/Cargo.toml +++ /dev/null @@ -1,29 +0,0 @@ -[package] -name = "cumulus-pallet-contracts-rpc" -version = "0.8.0-rc3" -authors = ["Parity Technologies "] -edition = "2018" -license = "Apache-2.0" -homepage = "https://substrate.dev" -repository = "https://github.com/paritytech/substrate/" -description = "Node-specific RPC methods for interaction with contracts." - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -codec = { package = "parity-scale-codec", version = "1.3.1" } -jsonrpc-core = "14.2.0" -jsonrpc-core-client = "14.2.0" -jsonrpc-derive = "14.2.1" -sp-blockchain = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-rpc = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -serde = { version = "1.0.101", features = ["derive"] } -sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -cumulus-pallet-contracts-primitives = { path = "../common" } -cumulus-pallet-contracts-rpc-runtime-api = { path = "./runtime-api" } - -[dev-dependencies] -serde_json = "1.0.41" diff --git a/rococo-parachains/pallets/contracts/rpc/runtime-api/Cargo.toml b/rococo-parachains/pallets/contracts/rpc/runtime-api/Cargo.toml deleted file mode 100644 index 9a6caac5de..0000000000 --- a/rococo-parachains/pallets/contracts/rpc/runtime-api/Cargo.toml +++ /dev/null @@ -1,29 +0,0 @@ -[package] -name = "cumulus-pallet-contracts-rpc-runtime-api" -version = "0.8.0-rc3" -authors = ["Parity Technologies "] -edition = "2018" -license = "Apache-2.0" -homepage = "https://substrate.dev" -repository = "https://github.com/paritytech/substrate/" -description = "Runtime API definition required by Contracts RPC extensions." - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -sp-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } -sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -cumulus-pallet-contracts-primitives = { path = "../../common", default-features = false } - -[features] -default = ["std"] -std = [ - "sp-api/std", - "codec/std", - "sp-std/std", - "sp-runtime/std", - "cumulus-pallet-contracts-primitives/std", -] diff --git a/rococo-parachains/pallets/contracts/rpc/runtime-api/src/lib.rs b/rococo-parachains/pallets/contracts/rpc/runtime-api/src/lib.rs deleted file mode 100644 index f92fac6d37..0000000000 --- a/rococo-parachains/pallets/contracts/rpc/runtime-api/src/lib.rs +++ /dev/null @@ -1,89 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Runtime API definition required by Contracts RPC extensions. -//! -//! This API should be imported and implemented by the runtime, -//! of a node that wants to use the custom RPC extension -//! adding Contracts access methods. - -#![cfg_attr(not(feature = "std"), no_std)] - -use codec::{Codec, Decode, Encode}; -use cumulus_pallet_contracts_primitives::{GetStorageResult, RentProjectionResult}; -use sp_runtime::RuntimeDebug; -use sp_std::vec::Vec; - -/// A result of execution of a contract. -#[derive(Eq, PartialEq, Encode, Decode, RuntimeDebug)] -pub enum ContractExecResult { - /// The contract returned successfully. - /// - /// There is a status code and, optionally, some data returned by the contract. - Success { - /// Flags that the contract passed along on returning to alter its exit behaviour. - /// Described in `pallet_contracts::exec::ReturnFlags`. - flags: u32, - /// Output data returned by the contract. - /// - /// Can be empty. - data: Vec, - /// How much gas was consumed by the call. - gas_consumed: u64, - }, - /// The contract execution either trapped or returned an error. - Error, -} - -sp_api::decl_runtime_apis! { - /// The API to interact with contracts without using executive. - pub trait ContractsApi where - AccountId: Codec, - Balance: Codec, - BlockNumber: Codec, - { - /// Perform a call from a specified account to a given contract. - /// - /// See the contracts' `call` dispatchable function for more details. - fn call( - origin: AccountId, - dest: AccountId, - value: Balance, - gas_limit: u64, - input_data: Vec, - ) -> ContractExecResult; - - /// Query a given storage key in a given contract. - /// - /// Returns `Ok(Some(Vec))` if the storage value exists under the given key in the - /// specified account and `Ok(None)` if it doesn't. If the account specified by the address - /// doesn't exist, or doesn't have a contract or if the contract is a tombstone, then `Err` - /// is returned. - fn get_storage( - address: AccountId, - key: [u8; 32], - ) -> GetStorageResult; - - /// Returns the projected time a given contract will be able to sustain paying its rent. - /// - /// The returned projection is relevant for the current block, i.e. it is as if the contract - /// was accessed at the current block. - /// - /// Returns `Err` if the contract is in a tombstone state or doesn't exist. - fn rent_projection(address: AccountId) -> RentProjectionResult; - } -} diff --git a/rococo-parachains/pallets/contracts/rpc/src/lib.rs b/rococo-parachains/pallets/contracts/rpc/src/lib.rs deleted file mode 100644 index 7922ada4a5..0000000000 --- a/rococo-parachains/pallets/contracts/rpc/src/lib.rs +++ /dev/null @@ -1,325 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Node-specific RPC methods for interaction with contracts. - -use std::sync::Arc; - -use codec::Codec; -use cumulus_pallet_contracts_primitives::RentProjection; -use jsonrpc_core::{Error, ErrorCode, Result}; -use jsonrpc_derive::rpc; -use serde::{Deserialize, Serialize}; -use sp_api::ProvideRuntimeApi; -use sp_blockchain::HeaderBackend; -use sp_core::{Bytes, H256}; -use sp_rpc::number; -use sp_runtime::{ - generic::BlockId, - traits::{Block as BlockT, Header as HeaderT}, -}; -use std::convert::TryInto; - -pub use self::gen_client::Client as ContractsClient; -pub use cumulus_pallet_contracts_rpc_runtime_api::{ - self as runtime_api, ContractExecResult, ContractsApi as ContractsRuntimeApi, -}; - -const RUNTIME_ERROR: i64 = 1; -const CONTRACT_DOESNT_EXIST: i64 = 2; -const CONTRACT_IS_A_TOMBSTONE: i64 = 3; - -/// A rough estimate of how much gas a decent hardware consumes per second, -/// using native execution. -/// This value is used to set the upper bound for maximal contract calls to -/// prevent blocking the RPC for too long. -/// -/// As 1 gas is equal to 1 weight we base this on the conducted benchmarks which -/// determined runtime weights: -/// https://github.com/paritytech/substrate/pull/5446 -const GAS_PER_SECOND: u64 = 1_000_000_000_000; - -/// A private newtype for converting `ContractAccessError` into an RPC error. -struct ContractAccessError(cumulus_pallet_contracts_primitives::ContractAccessError); -impl From for Error { - fn from(e: ContractAccessError) -> Error { - use cumulus_pallet_contracts_primitives::ContractAccessError::*; - match e.0 { - DoesntExist => Error { - code: ErrorCode::ServerError(CONTRACT_DOESNT_EXIST), - message: "The specified contract doesn't exist.".into(), - data: None, - }, - IsTombstone => Error { - code: ErrorCode::ServerError(CONTRACT_IS_A_TOMBSTONE), - message: "The contract is a tombstone and doesn't have any storage.".into(), - data: None, - }, - } - } -} - -/// A struct that encodes RPC parameters required for a call to a smart-contract. -#[derive(Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -#[serde(deny_unknown_fields)] -pub struct CallRequest { - origin: AccountId, - dest: AccountId, - value: Balance, - gas_limit: number::NumberOrHex, - input_data: Bytes, -} - -/// An RPC serializable result of contract execution -#[derive(Serialize, Deserialize)] -#[serde(deny_unknown_fields)] -#[serde(rename_all = "camelCase")] -pub enum RpcContractExecResult { - /// Successful execution - Success { - /// The return flags - flags: u32, - /// Output data - data: Bytes, - /// How much gas was consumed by the call. - gas_consumed: u64, - }, - /// Error execution - Error(()), -} - -impl From for RpcContractExecResult { - fn from(r: ContractExecResult) -> Self { - match r { - ContractExecResult::Success { - flags, - data, - gas_consumed, - } => RpcContractExecResult::Success { - flags, - data: data.into(), - gas_consumed, - }, - ContractExecResult::Error => RpcContractExecResult::Error(()), - } - } -} - -/// Contracts RPC methods. -#[rpc] -pub trait ContractsApi { - /// Executes a call to a contract. - /// - /// This call is performed locally without submitting any transactions. Thus executing this - /// won't change any state. Nonetheless, the calling state-changing contracts is still possible. - /// - /// This method is useful for calling getter-like methods on contracts. - #[rpc(name = "contracts_call")] - fn call( - &self, - call_request: CallRequest, - at: Option, - ) -> Result; - - /// Returns the value under a specified storage `key` in a contract given by `address` param, - /// or `None` if it is not set. - #[rpc(name = "contracts_getStorage")] - fn get_storage( - &self, - address: AccountId, - key: H256, - at: Option, - ) -> Result>; - - /// Returns the projected time a given contract will be able to sustain paying its rent. - /// - /// The returned projection is relevant for the given block, i.e. it is as if the contract was - /// accessed at the beginning of that block. - /// - /// Returns `None` if the contract is exempted from rent. - #[rpc(name = "contracts_rentProjection")] - fn rent_projection( - &self, - address: AccountId, - at: Option, - ) -> Result>; -} - -/// An implementation of contract specific RPC methods. -pub struct Contracts { - client: Arc, - _marker: std::marker::PhantomData, -} - -impl Contracts { - /// Create new `Contracts` with the given reference to the client. - pub fn new(client: Arc) -> Self { - Contracts { - client, - _marker: Default::default(), - } - } -} -impl - ContractsApi< - ::Hash, - <::Header as HeaderT>::Number, - AccountId, - Balance, - > for Contracts -where - Block: BlockT, - C: Send + Sync + 'static + ProvideRuntimeApi + HeaderBackend, - C::Api: ContractsRuntimeApi< - Block, - AccountId, - Balance, - <::Header as HeaderT>::Number, - >, - AccountId: Codec, - Balance: Codec, -{ - fn call( - &self, - call_request: CallRequest, - at: Option<::Hash>, - ) -> Result { - let api = self.client.runtime_api(); - let at = BlockId::hash(at.unwrap_or_else(|| - // If the block hash is not supplied assume the best block. - self.client.info().best_hash)); - - let CallRequest { - origin, - dest, - value, - gas_limit, - input_data, - } = call_request; - - // Make sure that gas_limit fits into 64 bits. - let gas_limit: u64 = gas_limit.try_into().map_err(|_| Error { - code: ErrorCode::InvalidParams, - message: format!("{:?} doesn't fit in 64 bit unsigned value", gas_limit), - data: None, - })?; - - let max_gas_limit = 5 * GAS_PER_SECOND; - if gas_limit > max_gas_limit { - return Err(Error { - code: ErrorCode::InvalidParams, - message: format!( - "Requested gas limit is greater than maximum allowed: {} > {}", - gas_limit, max_gas_limit - ), - data: None, - }); - } - - let exec_result = api - .call(&at, origin, dest, value, gas_limit, input_data.to_vec()) - .map_err(|e| runtime_error_into_rpc_err(e))?; - - Ok(exec_result.into()) - } - - fn get_storage( - &self, - address: AccountId, - key: H256, - at: Option<::Hash>, - ) -> Result> { - let api = self.client.runtime_api(); - let at = BlockId::hash(at.unwrap_or_else(|| - // If the block hash is not supplied assume the best block. - self.client.info().best_hash)); - - let result = api - .get_storage(&at, address, key.into()) - .map_err(|e| runtime_error_into_rpc_err(e))? - .map_err(ContractAccessError)? - .map(Bytes); - - Ok(result) - } - - fn rent_projection( - &self, - address: AccountId, - at: Option<::Hash>, - ) -> Result::Header as HeaderT>::Number>> { - let api = self.client.runtime_api(); - let at = BlockId::hash(at.unwrap_or_else(|| - // If the block hash is not supplied assume the best block. - self.client.info().best_hash)); - - let result = api - .rent_projection(&at, address) - .map_err(|e| runtime_error_into_rpc_err(e))? - .map_err(ContractAccessError)?; - - Ok(match result { - RentProjection::NoEviction => None, - RentProjection::EvictionAt(block_num) => Some(block_num), - }) - } -} - -/// Converts a runtime trap into an RPC error. -fn runtime_error_into_rpc_err(err: impl std::fmt::Debug) -> Error { - Error { - code: ErrorCode::ServerError(RUNTIME_ERROR), - message: "Runtime trapped".into(), - data: Some(format!("{:?}", err).into()), - } -} - -#[cfg(test)] -mod tests { - use super::*; - use sp_core::U256; - - #[test] - fn call_request_should_serialize_deserialize_properly() { - type Req = CallRequest; - let req: Req = serde_json::from_str( - r#" - { - "origin": "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", - "dest": "5DRakbLVnjVrW6niwLfHGW24EeCEvDAFGEXrtaYS5M4ynoom", - "value": 0, - "gasLimit": 1000000000000, - "inputData": "0x8c97db39" - } - "#, - ) - .unwrap(); - assert_eq!(req.gas_limit.into_u256(), U256::from(0xe8d4a51000u64)); - } - - #[test] - fn result_should_serialize_deserialize_properly() { - fn test(expected: &str) { - let res: RpcContractExecResult = serde_json::from_str(expected).unwrap(); - let actual = serde_json::to_string(&res).unwrap(); - assert_eq!(actual, expected); - } - test(r#"{"success":{"flags":5,"data":"0x1234","gas_consumed":99}}"#); - test(r#"{"error":null}"#); - } -} diff --git a/rococo-parachains/pallets/contracts/src/account_db.rs b/rococo-parachains/pallets/contracts/src/account_db.rs deleted file mode 100644 index 5e9ab01a9e..0000000000 --- a/rococo-parachains/pallets/contracts/src/account_db.rs +++ /dev/null @@ -1,450 +0,0 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Auxiliaries to help with managing partial changes to accounts state. - -use super::{ - AliveContractInfo, BalanceOf, CodeHash, ContractInfo, ContractInfoOf, Trait, TrieId, - TrieIdGenerator, -}; -use crate::exec::StorageKey; -use frame_support::{ - storage::unhashed as storage, - traits::{Currency, Imbalance, SignedImbalance}, - StorageMap, -}; -use frame_system; -use sp_io::hashing::blake2_256; -use sp_runtime::traits::{Bounded, Zero}; -use sp_std::{ - cell::RefCell, - collections::btree_map::{BTreeMap, Entry}, - prelude::*, -}; - -// Note: we don't provide Option because we can't create -// the trie_id in the overlay, thus we provide an overlay on the fields -// specifically. -pub struct ChangeEntry { - /// If Some(_), then the account balance is modified to the value. If None and `reset` is false, - /// the balance unmodified. If None and `reset` is true, the balance is reset to 0. - balance: Option>, - /// If Some(_), then a contract is instantiated with the code hash. If None and `reset` is false, - /// then the contract code is unmodified. If None and `reset` is true, the contract is deleted. - code_hash: Option>, - /// If Some(_), then the rent allowance is set to the value. If None and `reset` is false, then - /// the rent allowance is unmodified. If None and `reset` is true, the contract is deleted. - rent_allowance: Option>, - storage: BTreeMap>>, - /// If true, indicates that the existing contract and all its storage entries should be removed - /// and replaced with the fields on this change entry. Otherwise, the fields on this change - /// entry are updates merged into the existing contract info and storage. - reset: bool, -} - -impl ChangeEntry { - fn balance(&self) -> Option> { - self.balance.or_else(|| { - if self.reset { - Some(>::zero()) - } else { - None - } - }) - } - - fn code_hash(&self) -> Option>> { - if self.reset { - Some(self.code_hash) - } else { - self.code_hash.map(Some) - } - } - - fn rent_allowance(&self) -> Option>> { - if self.reset { - Some(self.rent_allowance) - } else { - self.rent_allowance.map(Some) - } - } - - fn storage(&self, location: &StorageKey) -> Option>> { - let value = self.storage.get(location).cloned(); - if self.reset { - Some(value.unwrap_or(None)) - } else { - value - } - } -} - -// Cannot derive(Default) since it erroneously bounds T by Default. -impl Default for ChangeEntry { - fn default() -> Self { - ChangeEntry { - rent_allowance: Default::default(), - balance: Default::default(), - code_hash: Default::default(), - storage: Default::default(), - reset: false, - } - } -} - -pub type ChangeSet = BTreeMap<::AccountId, ChangeEntry>; - -pub trait AccountDb { - /// Account is used when overlayed otherwise trie_id must be provided. - /// This is for performance reason. - /// - /// Trie id is None iff account doesn't have an associated trie id in >. - /// Because DirectAccountDb bypass the lookup for this association. - fn get_storage( - &self, - account: &T::AccountId, - trie_id: Option<&TrieId>, - location: &StorageKey, - ) -> Option>; - /// If account has an alive contract then return the code hash associated. - fn get_code_hash(&self, account: &T::AccountId) -> Option>; - /// If account has an alive contract then return the rent allowance associated. - fn get_rent_allowance(&self, account: &T::AccountId) -> Option>; - /// Returns false iff account has no alive contract nor tombstone. - fn contract_exists(&self, account: &T::AccountId) -> bool; - fn get_balance(&self, account: &T::AccountId) -> BalanceOf; - - fn commit(&mut self, change_set: ChangeSet); -} - -pub struct DirectAccountDb; -impl AccountDb for DirectAccountDb { - fn get_storage( - &self, - _account: &T::AccountId, - trie_id: Option<&TrieId>, - location: &StorageKey, - ) -> Option> { - trie_id.and_then(|id| storage::get_raw(&crate::prefixed_key(id, &blake2_256(location)))) - } - fn get_code_hash(&self, account: &T::AccountId) -> Option> { - >::get(account).and_then(|i| i.as_alive().map(|i| i.code_hash)) - } - fn get_rent_allowance(&self, account: &T::AccountId) -> Option> { - >::get(account).and_then(|i| i.as_alive().map(|i| i.rent_allowance)) - } - fn contract_exists(&self, account: &T::AccountId) -> bool { - >::contains_key(account) - } - fn get_balance(&self, account: &T::AccountId) -> BalanceOf { - T::Currency::free_balance(account) - } - fn commit(&mut self, s: ChangeSet) { - let mut total_imbalance = SignedImbalance::zero(); - for (address, changed) in s.into_iter() { - if let Some(balance) = changed.balance() { - let imbalance = T::Currency::make_free_balance_be(&address, balance); - total_imbalance = total_imbalance.merge(imbalance); - } - - if changed.code_hash().is_some() - || changed.rent_allowance().is_some() - || !changed.storage.is_empty() - || changed.reset - { - let old_info = match >::get(&address) { - Some(ContractInfo::Alive(alive)) => Some(alive), - None => None, - // Cannot commit changes to tombstone contract - Some(ContractInfo::Tombstone(_)) => continue, - }; - - let mut new_info = match (changed.reset, old_info.clone(), changed.code_hash) { - // Existing contract is being modified. - (false, Some(info), _) => info, - // Existing contract is being removed. - (true, Some(info), None) => { - storage::kill_prefix(&info.trie_id); - >::remove(&address); - continue; - } - // Existing contract is being replaced by a new one. - (true, Some(info), Some(code_hash)) => { - storage::kill_prefix(&info.trie_id); - AliveContractInfo:: { - code_hash, - storage_size: 0, - empty_pair_count: 0, - total_pair_count: 0, - trie_id: ::TrieIdGenerator::trie_id(&address), - deduct_block: >::block_number(), - rent_allowance: >::max_value(), - last_write: None, - } - } - // New contract is being instantiated. - (_, None, Some(code_hash)) => AliveContractInfo:: { - code_hash, - storage_size: 0, - empty_pair_count: 0, - total_pair_count: 0, - trie_id: ::TrieIdGenerator::trie_id(&address), - deduct_block: >::block_number(), - rent_allowance: >::max_value(), - last_write: None, - }, - // There is no existing at the address nor a new one to be instantiated. - (_, None, None) => continue, - }; - - if let Some(rent_allowance) = changed.rent_allowance { - new_info.rent_allowance = rent_allowance; - } - - if let Some(code_hash) = changed.code_hash { - new_info.code_hash = code_hash; - } - - if !changed.storage.is_empty() { - new_info.last_write = Some(>::block_number()); - } - - // Here we iterate over all storage key-value pairs that were changed throughout the - // execution of a contract and apply them to the substrate storage. - for (key, opt_new_value) in changed.storage.into_iter() { - let hashed_key = new_info.prefixed_key(&blake2_256(&key)); - - // In order to correctly update the book keeping we need to fetch the previous - // value of the key-value pair. - // - // It might be a bit more clean if we had an API that supported getting the size - // of the value without going through the loading of it. But at the moment of - // writing, there is no such API. - // - // That's not a show stopper in any case, since the performance cost is - // dominated by the trie traversal anyway. - let opt_prev_value = storage::get_raw(&hashed_key); - - // Update the total number of KV pairs and the number of empty pairs. - match (&opt_prev_value, &opt_new_value) { - (Some(prev_value), None) => { - new_info.total_pair_count -= 1; - if prev_value.is_empty() { - new_info.empty_pair_count -= 1; - } - } - (None, Some(new_value)) => { - new_info.total_pair_count += 1; - if new_value.is_empty() { - new_info.empty_pair_count += 1; - } - } - (Some(prev_value), Some(new_value)) => { - if prev_value.is_empty() { - new_info.empty_pair_count -= 1; - } - if new_value.is_empty() { - new_info.empty_pair_count += 1; - } - } - (None, None) => {} - } - - // Update the total storage size. - let prev_value_len = opt_prev_value - .as_ref() - .map(|old_value| old_value.len() as u32) - .unwrap_or(0); - let new_value_len = opt_new_value - .as_ref() - .map(|new_value| new_value.len() as u32) - .unwrap_or(0); - new_info.storage_size = new_info - .storage_size - .saturating_add(new_value_len) - .saturating_sub(prev_value_len); - - // Finally, perform the change on the storage. - match opt_new_value { - Some(new_value) => storage::put_raw(&hashed_key, &new_value[..]), - None => storage::kill(&hashed_key), - } - } - - if old_info - .map(|old_info| old_info != new_info) - .unwrap_or(true) - { - >::insert(&address, ContractInfo::Alive(new_info)); - } - } - } - - match total_imbalance { - // If we've detected a positive imbalance as a result of our contract-level machinations - // then it's indicative of a buggy contracts system. - // Panicking is far from ideal as it opens up a DoS attack on block validators, however - // it's a less bad option than allowing arbitrary value to be created. - SignedImbalance::Positive(ref p) if !p.peek().is_zero() => { - panic!("contract subsystem resulting in positive imbalance!") - } - _ => {} - } - } -} - -pub struct OverlayAccountDb<'a, T: Trait + 'a> { - local: RefCell>, - underlying: &'a dyn AccountDb, -} -impl<'a, T: Trait> OverlayAccountDb<'a, T> { - pub fn new(underlying: &'a dyn AccountDb) -> OverlayAccountDb<'a, T> { - OverlayAccountDb { - local: RefCell::new(ChangeSet::new()), - underlying, - } - } - - pub fn into_change_set(self) -> ChangeSet { - self.local.into_inner() - } - - pub fn set_storage( - &mut self, - account: &T::AccountId, - location: StorageKey, - value: Option>, - ) { - self.local - .borrow_mut() - .entry(account.clone()) - .or_insert(Default::default()) - .storage - .insert(location, value); - } - - /// Return an error if contract already exists (either if it is alive or tombstone) - pub fn instantiate_contract( - &mut self, - account: &T::AccountId, - code_hash: CodeHash, - ) -> Result<(), &'static str> { - if self.contract_exists(account) { - return Err("Alive contract or tombstone already exists"); - } - - let mut local = self.local.borrow_mut(); - let contract = local.entry(account.clone()).or_default(); - - contract.code_hash = Some(code_hash); - contract.rent_allowance = Some(>::max_value()); - - Ok(()) - } - - /// Mark a contract as deleted. - pub fn destroy_contract(&mut self, account: &T::AccountId) { - let mut local = self.local.borrow_mut(); - local.insert( - account.clone(), - ChangeEntry { - reset: true, - ..Default::default() - }, - ); - } - - /// Assume contract exists - pub fn set_rent_allowance(&mut self, account: &T::AccountId, rent_allowance: BalanceOf) { - self.local - .borrow_mut() - .entry(account.clone()) - .or_insert(Default::default()) - .rent_allowance = Some(rent_allowance); - } - pub fn set_balance(&mut self, account: &T::AccountId, balance: BalanceOf) { - self.local - .borrow_mut() - .entry(account.clone()) - .or_insert(Default::default()) - .balance = Some(balance); - } -} - -impl<'a, T: Trait> AccountDb for OverlayAccountDb<'a, T> { - fn get_storage( - &self, - account: &T::AccountId, - trie_id: Option<&TrieId>, - location: &StorageKey, - ) -> Option> { - self.local - .borrow() - .get(account) - .and_then(|changes| changes.storage(location)) - .unwrap_or_else(|| self.underlying.get_storage(account, trie_id, location)) - } - fn get_code_hash(&self, account: &T::AccountId) -> Option> { - self.local - .borrow() - .get(account) - .and_then(|changes| changes.code_hash()) - .unwrap_or_else(|| self.underlying.get_code_hash(account)) - } - fn get_rent_allowance(&self, account: &T::AccountId) -> Option> { - self.local - .borrow() - .get(account) - .and_then(|changes| changes.rent_allowance()) - .unwrap_or_else(|| self.underlying.get_rent_allowance(account)) - } - fn contract_exists(&self, account: &T::AccountId) -> bool { - self.local - .borrow() - .get(account) - .and_then(|changes| changes.code_hash().map(|code_hash| code_hash.is_some())) - .unwrap_or_else(|| self.underlying.contract_exists(account)) - } - fn get_balance(&self, account: &T::AccountId) -> BalanceOf { - self.local - .borrow() - .get(account) - .and_then(|changes| changes.balance()) - .unwrap_or_else(|| self.underlying.get_balance(account)) - } - fn commit(&mut self, s: ChangeSet) { - let mut local = self.local.borrow_mut(); - - for (address, changed) in s.into_iter() { - match local.entry(address) { - Entry::Occupied(e) => { - let mut value = e.into_mut(); - if changed.reset { - *value = changed; - } else { - value.balance = changed.balance.or(value.balance); - value.code_hash = changed.code_hash.or(value.code_hash); - value.rent_allowance = changed.rent_allowance.or(value.rent_allowance); - value.storage.extend(changed.storage.into_iter()); - } - } - Entry::Vacant(e) => { - e.insert(changed); - } - } - } - } -} diff --git a/rococo-parachains/pallets/contracts/src/exec.rs b/rococo-parachains/pallets/contracts/src/exec.rs deleted file mode 100644 index 76caa5be8e..0000000000 --- a/rococo-parachains/pallets/contracts/src/exec.rs +++ /dev/null @@ -1,1828 +0,0 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -use super::{ - BalanceOf, CodeHash, Config, ContractAddressFor, ContractInfo, Event, RawEvent, Trait, TrieId, -}; -use crate::{ - account_db::{AccountDb, DirectAccountDb, OverlayAccountDb}, - gas::{Gas, GasMeter, Token}, - rent, -}; - -use frame_support::{ - dispatch::DispatchError, - storage::unhashed, - traits::{Currency, Randomness, Time, WithdrawReason}, - weights::Weight, -}; -use sp_runtime::traits::{Bounded, CheckedAdd, CheckedSub, Convert, Zero}; -use sp_std::prelude::*; - -pub type AccountIdOf = ::AccountId; -pub type CallOf = ::Call; -pub type MomentOf = <::Time as Time>::Moment; -pub type SeedOf = ::Hash; -pub type BlockNumberOf = ::BlockNumber; -pub type StorageKey = [u8; 32]; - -/// A type that represents a topic of an event. At the moment a hash is used. -pub type TopicOf = ::Hash; - -/// A status code return to the source of a contract call or instantiation indicating success or -/// failure. A code of 0 indicates success and that changes are applied. All other codes indicate -/// failure and that changes are reverted. The particular code in the case of failure is opaque and -/// may be interpreted by the calling contract. -pub type StatusCode = u8; - -/// The status code indicating success. -pub const STATUS_SUCCESS: StatusCode = 0; - -/// Output of a contract call or instantiation which ran to completion. -#[cfg_attr(test, derive(PartialEq, Eq, Debug))] -pub struct ExecReturnValue { - pub status: StatusCode, - pub data: Vec, -} - -impl ExecReturnValue { - /// Returns whether the call or instantiation exited with a successful status code. - pub fn is_success(&self) -> bool { - self.status == STATUS_SUCCESS - } -} - -/// An error indicating some failure to execute a contract call or instantiation. This can include -/// VM-specific errors during execution (eg. division by 0, OOB access, failure to satisfy some -/// precondition of a system call, etc.) or errors with the orchestration (eg. out-of-gas errors, a -/// non-existent destination contract, etc.). -#[cfg_attr(test, derive(sp_runtime::RuntimeDebug))] -pub struct ExecError { - pub reason: DispatchError, - /// This is an allocated buffer that may be reused. The buffer must be cleared explicitly - /// before reuse. - pub buffer: Vec, -} - -pub type ExecResult = Result; - -/// Evaluate an expression of type Result<_, &'static str> and either resolve to the value if Ok or -/// wrap the error string into an ExecutionError with the provided buffer and return from the -/// enclosing function. This macro is used instead of .map_err(..)? in order to avoid taking -/// ownership of buffer unless there is an error. -#[macro_export] -macro_rules! try_or_exec_error { - ($e:expr, $buffer:expr) => { - match $e { - Ok(val) => val, - Err(reason) => { - return Err($crate::exec::ExecError { - reason: reason.into(), - buffer: $buffer, - }) - } - } - }; -} - -/// An interface that provides access to the external environment in which the -/// smart-contract is executed. -/// -/// This interface is specialized to an account of the executing code, so all -/// operations are implicitly performed on that account. -pub trait Ext { - type T: Trait; - - /// Returns the storage entry of the executing account by the given `key`. - /// - /// Returns `None` if the `key` wasn't previously set by `set_storage` or - /// was deleted. - fn get_storage(&self, key: &StorageKey) -> Option>; - - /// Sets the storage entry by the given key to the specified value. If `value` is `None` then - /// the storage entry is deleted. Returns an Err if the value size is too large. - fn set_storage(&mut self, key: StorageKey, value: Option>) -> Result<(), &'static str>; - - /// Instantiate a contract from the given code. - /// - /// The newly created account will be associated with `code`. `value` specifies the amount of value - /// transferred from this to the newly created account (also known as endowment). - fn instantiate( - &mut self, - code: &CodeHash, - value: BalanceOf, - gas_meter: &mut GasMeter, - input_data: Vec, - ) -> Result<(AccountIdOf, ExecReturnValue), ExecError>; - - /// Transfer some amount of funds into the specified account. - fn transfer( - &mut self, - to: &AccountIdOf, - value: BalanceOf, - gas_meter: &mut GasMeter, - ) -> Result<(), DispatchError>; - - /// Transfer all funds to `beneficiary` and delete the contract. - fn terminate( - &mut self, - beneficiary: &AccountIdOf, - gas_meter: &mut GasMeter, - ) -> Result<(), DispatchError>; - - /// Call (possibly transferring some amount of funds) into the specified account. - fn call( - &mut self, - to: &AccountIdOf, - value: BalanceOf, - gas_meter: &mut GasMeter, - input_data: Vec, - ) -> ExecResult; - - /// Notes a call dispatch. - fn note_dispatch_call(&mut self, call: CallOf); - - /// Notes a restoration request. - fn note_restore_to( - &mut self, - dest: AccountIdOf, - code_hash: CodeHash, - rent_allowance: BalanceOf, - delta: Vec, - ); - - /// Returns a reference to the account id of the caller. - fn caller(&self) -> &AccountIdOf; - - /// Returns a reference to the account id of the current contract. - fn address(&self) -> &AccountIdOf; - - /// Returns the balance of the current contract. - /// - /// The `value_transferred` is already added. - fn balance(&self) -> BalanceOf; - - /// Returns the value transferred along with this call or as endowment. - fn value_transferred(&self) -> BalanceOf; - - /// Returns a reference to the timestamp of the current block - fn now(&self) -> &MomentOf; - - /// Returns the minimum balance that is required for creating an account. - fn minimum_balance(&self) -> BalanceOf; - - /// Returns the deposit required to create a tombstone upon contract eviction. - fn tombstone_deposit(&self) -> BalanceOf; - - /// Returns a random number for the current block with the given subject. - fn random(&self, subject: &[u8]) -> SeedOf; - - /// Deposit an event with the given topics. - /// - /// There should not be any duplicates in `topics`. - fn deposit_event(&mut self, topics: Vec>, data: Vec); - - /// Set rent allowance of the contract - fn set_rent_allowance(&mut self, rent_allowance: BalanceOf); - - /// Rent allowance of the contract - fn rent_allowance(&self) -> BalanceOf; - - /// Returns the current block number. - fn block_number(&self) -> BlockNumberOf; - - /// Returns the maximum allowed size of a storage item. - fn max_value_size(&self) -> u32; - - /// Returns the value of runtime under the given key. - /// - /// Returns `None` if the value doesn't exist. - fn get_runtime_storage(&self, key: &[u8]) -> Option>; - - /// Returns the price for the specified amount of weight. - fn get_weight_price(&self, weight: Weight) -> BalanceOf; -} - -/// Loader is a companion of the `Vm` trait. It loads an appropriate abstract -/// executable to be executed by an accompanying `Vm` implementation. -pub trait Loader { - type Executable; - - /// Load the initializer portion of the code specified by the `code_hash`. This - /// executable is called upon instantiation. - fn load_init(&self, code_hash: &CodeHash) -> Result; - /// Load the main portion of the code specified by the `code_hash`. This executable - /// is called for each call to a contract. - fn load_main(&self, code_hash: &CodeHash) -> Result; -} - -/// A trait that represent a virtual machine. -/// -/// You can view a virtual machine as something that takes code, an input data buffer, -/// queries it and/or performs actions on the given `Ext` and optionally -/// returns an output data buffer. The type of code depends on the particular virtual machine. -/// -/// Execution of code can end by either implicit termination (that is, reached the end of -/// executable), explicit termination via returning a buffer or termination due to a trap. -pub trait Vm { - type Executable; - - fn execute>( - &self, - exec: &Self::Executable, - ext: E, - input_data: Vec, - gas_meter: &mut GasMeter, - ) -> ExecResult; -} - -#[cfg_attr(test, derive(Debug, PartialEq, Eq))] -#[derive(Copy, Clone)] -pub enum ExecFeeToken { - /// Base fee charged for a call. - Call, - /// Base fee charged for a instantiate. - Instantiate, -} - -impl Token for ExecFeeToken { - type Metadata = Config; - #[inline] - fn calculate_amount(&self, metadata: &Config) -> Gas { - match *self { - ExecFeeToken::Call => metadata.schedule.call_base_cost, - ExecFeeToken::Instantiate => metadata.schedule.instantiate_base_cost, - } - } -} - -#[cfg_attr(any(feature = "std", test), derive(PartialEq, Eq, Clone))] -#[derive(sp_runtime::RuntimeDebug)] -pub enum DeferredAction { - DepositEvent { - /// A list of topics this event will be deposited with. - topics: Vec, - /// The event to deposit. - event: Event, - }, - DispatchRuntimeCall { - /// The account id of the contract who dispatched this call. - origin: T::AccountId, - /// The call to dispatch. - call: ::Call, - }, - RestoreTo { - /// The account id of the contract which is removed during the restoration and transfers - /// its storage to the restored contract. - donor: T::AccountId, - /// The account id of the restored contract. - dest: T::AccountId, - /// The code hash of the restored contract. - code_hash: CodeHash, - /// The initial rent allowance to set. - rent_allowance: BalanceOf, - /// The keys to delete upon restoration. - delta: Vec, - }, -} - -pub struct ExecutionContext<'a, T: Trait + 'a, V, L> { - pub caller: Option<&'a ExecutionContext<'a, T, V, L>>, - pub self_account: T::AccountId, - pub self_trie_id: Option, - pub overlay: OverlayAccountDb<'a, T>, - pub depth: usize, - pub deferred: Vec>, - pub config: &'a Config, - pub vm: &'a V, - pub loader: &'a L, - pub timestamp: MomentOf, - pub block_number: T::BlockNumber, -} - -impl<'a, T, E, V, L> ExecutionContext<'a, T, V, L> -where - T: Trait, - L: Loader, - V: Vm, -{ - /// Create the top level execution context. - /// - /// The specified `origin` address will be used as `sender` for. The `origin` must be a regular - /// account (not a contract). - pub fn top_level(origin: T::AccountId, cfg: &'a Config, vm: &'a V, loader: &'a L) -> Self { - ExecutionContext { - caller: None, - self_trie_id: None, - self_account: origin, - overlay: OverlayAccountDb::::new(&DirectAccountDb), - depth: 0, - deferred: Vec::new(), - config: &cfg, - vm: &vm, - loader: &loader, - timestamp: T::Time::now(), - block_number: >::block_number(), - } - } - - fn nested<'b, 'c: 'b>( - &'c self, - dest: T::AccountId, - trie_id: Option, - ) -> ExecutionContext<'b, T, V, L> { - ExecutionContext { - caller: Some(self), - self_trie_id: trie_id, - self_account: dest, - overlay: OverlayAccountDb::new(&self.overlay), - depth: self.depth + 1, - deferred: Vec::new(), - config: self.config, - vm: self.vm, - loader: self.loader, - timestamp: self.timestamp.clone(), - block_number: self.block_number.clone(), - } - } - - /// Transfer balance to `dest` without calling any contract code. - pub fn transfer( - &mut self, - dest: T::AccountId, - value: BalanceOf, - gas_meter: &mut GasMeter, - ) -> Result<(), DispatchError> { - transfer( - gas_meter, - TransferCause::Call, - &self.self_account.clone(), - &dest, - value, - self, - ) - } - - /// Make a call to the specified address, optionally transferring some funds. - pub fn call( - &mut self, - dest: T::AccountId, - value: BalanceOf, - gas_meter: &mut GasMeter, - input_data: Vec, - ) -> ExecResult { - if self.depth == self.config.max_depth as usize { - return Err(ExecError { - reason: "reached maximum depth, cannot make a call".into(), - buffer: input_data, - }); - } - - if gas_meter - .charge(self.config, ExecFeeToken::Call) - .is_out_of_gas() - { - return Err(ExecError { - reason: "not enough gas to pay base call fee".into(), - buffer: input_data, - }); - } - - // Assumption: `collect_rent` doesn't collide with overlay because - // `collect_rent` will be done on first call and destination contract and balance - // cannot be changed before the first call - let contract_info = rent::collect_rent::(&dest); - - // Calls to dead contracts always fail. - if let Some(ContractInfo::Tombstone(_)) = contract_info { - return Err(ExecError { - reason: "contract has been evicted".into(), - buffer: input_data, - }); - }; - - let caller = self.self_account.clone(); - let dest_trie_id = contract_info.and_then(|i| i.as_alive().map(|i| i.trie_id.clone())); - - self.with_nested_context(dest.clone(), dest_trie_id, |nested| { - if value > BalanceOf::::zero() { - try_or_exec_error!( - transfer( - gas_meter, - TransferCause::Call, - &caller, - &dest, - value, - nested, - ), - input_data - ); - } - - // If code_hash is not none, then the destination account is a live contract, otherwise - // it is a regular account since tombstone accounts have already been rejected. - match nested.overlay.get_code_hash(&dest) { - Some(dest_code_hash) => { - let executable = - try_or_exec_error!(nested.loader.load_main(&dest_code_hash), input_data); - let output = nested.vm.execute( - &executable, - nested.new_call_context(caller, value), - input_data, - gas_meter, - )?; - - Ok(output) - } - None => Ok(ExecReturnValue { - status: STATUS_SUCCESS, - data: Vec::new(), - }), - } - }) - } - - pub fn instantiate( - &mut self, - endowment: BalanceOf, - gas_meter: &mut GasMeter, - code_hash: &CodeHash, - input_data: Vec, - ) -> Result<(T::AccountId, ExecReturnValue), ExecError> { - if self.depth == self.config.max_depth as usize { - return Err(ExecError { - reason: "reached maximum depth, cannot instantiate".into(), - buffer: input_data, - }); - } - - if gas_meter - .charge(self.config, ExecFeeToken::Instantiate) - .is_out_of_gas() - { - return Err(ExecError { - reason: "not enough gas to pay base instantiate fee".into(), - buffer: input_data, - }); - } - - let caller = self.self_account.clone(); - let dest = - T::DetermineContractAddress::contract_address_for(code_hash, &input_data, &caller); - - // TrieId has not been generated yet and storage is empty since contract is new. - let dest_trie_id = None; - - let output = self.with_nested_context(dest.clone(), dest_trie_id, |nested| { - try_or_exec_error!( - nested - .overlay - .instantiate_contract(&dest, code_hash.clone()), - input_data - ); - - // Send funds unconditionally here. If the `endowment` is below existential_deposit - // then error will be returned here. - try_or_exec_error!( - transfer( - gas_meter, - TransferCause::Instantiate, - &caller, - &dest, - endowment, - nested, - ), - input_data - ); - - let executable = try_or_exec_error!(nested.loader.load_init(&code_hash), input_data); - let output = nested.vm.execute( - &executable, - nested.new_call_context(caller.clone(), endowment), - input_data, - gas_meter, - )?; - - // Error out if insufficient remaining balance. - if nested.overlay.get_balance(&dest) < nested.config.existential_deposit { - return Err(ExecError { - reason: "insufficient remaining balance".into(), - buffer: output.data, - }); - } - - // Deposit an instantiation event. - nested.deferred.push(DeferredAction::DepositEvent { - event: RawEvent::Instantiated(caller.clone(), dest.clone()), - topics: Vec::new(), - }); - - Ok(output) - })?; - - Ok((dest, output)) - } - - pub fn terminate( - &mut self, - beneficiary: &T::AccountId, - gas_meter: &mut GasMeter, - ) -> Result<(), DispatchError> { - let self_id = self.self_account.clone(); - let value = self.overlay.get_balance(&self_id); - if let Some(caller) = self.caller { - if caller.is_live(&self_id) { - return Err(DispatchError::Other( - "Cannot terminate a contract that is present on the call stack", - )); - } - } - transfer( - gas_meter, - TransferCause::Terminate, - &self_id, - beneficiary, - value, - self, - )?; - self.overlay.destroy_contract(&self_id); - Ok(()) - } - - fn new_call_context<'b>( - &'b mut self, - caller: T::AccountId, - value: BalanceOf, - ) -> CallContext<'b, 'a, T, V, L> { - let timestamp = self.timestamp.clone(); - let block_number = self.block_number.clone(); - CallContext { - ctx: self, - caller, - value_transferred: value, - timestamp, - block_number, - } - } - - fn with_nested_context( - &mut self, - dest: T::AccountId, - trie_id: Option, - func: F, - ) -> ExecResult - where - F: FnOnce(&mut ExecutionContext) -> ExecResult, - { - let (output, change_set, deferred) = { - let mut nested = self.nested(dest, trie_id); - let output = func(&mut nested)?; - (output, nested.overlay.into_change_set(), nested.deferred) - }; - - if output.is_success() { - self.overlay.commit(change_set); - self.deferred.extend(deferred); - } - - Ok(output) - } - - /// Returns whether a contract, identified by address, is currently live in the execution - /// stack, meaning it is in the middle of an execution. - fn is_live(&self, account: &T::AccountId) -> bool { - &self.self_account == account || self.caller.map_or(false, |caller| caller.is_live(account)) - } -} - -#[cfg_attr(test, derive(Debug, PartialEq, Eq))] -#[derive(Copy, Clone)] -pub enum TransferFeeKind { - ContractInstantiate, - Transfer, -} - -#[cfg_attr(test, derive(Debug, PartialEq, Eq))] -#[derive(Copy, Clone)] -pub struct TransferFeeToken { - kind: TransferFeeKind, -} - -impl Token for TransferFeeToken { - type Metadata = Config; - - #[inline] - fn calculate_amount(&self, metadata: &Config) -> Gas { - match self.kind { - TransferFeeKind::ContractInstantiate => metadata.schedule.instantiate_cost, - TransferFeeKind::Transfer => metadata.schedule.transfer_cost, - } - } -} - -/// Describes possible transfer causes. -enum TransferCause { - Call, - Instantiate, - Terminate, -} - -/// Transfer some funds from `transactor` to `dest`. -/// -/// All balance changes are performed in the `overlay`. -/// -/// This function also handles charging the fee. The fee depends -/// on whether the transfer happening because of contract instantiation -/// (transferring endowment) or because of a transfer via `call`. This -/// is specified using the `cause` parameter. -/// -/// NOTE: that the fee is denominated in `BalanceOf` units, but -/// charged in `Gas` from the provided `gas_meter`. This means -/// that the actual amount charged might differ. -/// -/// NOTE: that we allow for draining all funds of the contract so it -/// can go below existential deposit, essentially giving a contract -/// the chance to give up it's life. -fn transfer<'a, T: Trait, V: Vm, L: Loader>( - gas_meter: &mut GasMeter, - cause: TransferCause, - transactor: &T::AccountId, - dest: &T::AccountId, - value: BalanceOf, - ctx: &mut ExecutionContext<'a, T, V, L>, -) -> Result<(), DispatchError> { - use self::{TransferCause::*, TransferFeeKind::*}; - - let token = { - let kind: TransferFeeKind = match cause { - // If this function is called from `Instantiate` routine, then we always - // charge contract account creation fee. - Instantiate => ContractInstantiate, - - // Otherwise the fee is to transfer to an account. - Call | Terminate => TransferFeeKind::Transfer, - }; - TransferFeeToken { kind } - }; - - if gas_meter.charge(ctx.config, token).is_out_of_gas() { - Err("not enough gas to pay transfer fee")? - } - - // We allow balance to go below the existential deposit here: - let from_balance = ctx.overlay.get_balance(transactor); - let new_from_balance = match from_balance.checked_sub(&value) { - Some(b) => b, - None => Err("balance too low to send value")?, - }; - let to_balance = ctx.overlay.get_balance(dest); - if to_balance.is_zero() && value < ctx.config.existential_deposit { - Err("value too low to create account")? - } - - // Only ext_terminate is allowed to bring the sender below the existential deposit - let required_balance = match cause { - Terminate => 0.into(), - _ => ctx.config.existential_deposit, - }; - - T::Currency::ensure_can_withdraw( - transactor, - value, - WithdrawReason::Transfer.into(), - new_from_balance - .checked_sub(&required_balance) - .ok_or("brings sender below existential deposit")?, - )?; - - let new_to_balance = match to_balance.checked_add(&value) { - Some(b) => b, - None => Err("destination balance too high to receive value")?, - }; - - if transactor != dest { - ctx.overlay.set_balance(transactor, new_from_balance); - ctx.overlay.set_balance(dest, new_to_balance); - ctx.deferred.push(DeferredAction::DepositEvent { - event: RawEvent::Transfer(transactor.clone(), dest.clone(), value), - topics: Vec::new(), - }); - } - - Ok(()) -} - -struct CallContext<'a, 'b: 'a, T: Trait + 'b, V: Vm + 'b, L: Loader> { - ctx: &'a mut ExecutionContext<'b, T, V, L>, - caller: T::AccountId, - value_transferred: BalanceOf, - timestamp: MomentOf, - block_number: T::BlockNumber, -} - -impl<'a, 'b: 'a, T, E, V, L> Ext for CallContext<'a, 'b, T, V, L> -where - T: Trait + 'b, - V: Vm, - L: Loader, -{ - type T = T; - - fn get_storage(&self, key: &StorageKey) -> Option> { - self.ctx - .overlay - .get_storage(&self.ctx.self_account, self.ctx.self_trie_id.as_ref(), key) - } - - fn set_storage(&mut self, key: StorageKey, value: Option>) -> Result<(), &'static str> { - if let Some(ref value) = value { - if self.max_value_size() < value.len() as u32 { - return Err("value size exceeds maximum"); - } - } - - self.ctx - .overlay - .set_storage(&self.ctx.self_account, key, value); - Ok(()) - } - - fn instantiate( - &mut self, - code_hash: &CodeHash, - endowment: BalanceOf, - gas_meter: &mut GasMeter, - input_data: Vec, - ) -> Result<(AccountIdOf, ExecReturnValue), ExecError> { - self.ctx - .instantiate(endowment, gas_meter, code_hash, input_data) - } - - fn transfer( - &mut self, - to: &T::AccountId, - value: BalanceOf, - gas_meter: &mut GasMeter, - ) -> Result<(), DispatchError> { - self.ctx.transfer(to.clone(), value, gas_meter) - } - - fn terminate( - &mut self, - beneficiary: &AccountIdOf, - gas_meter: &mut GasMeter, - ) -> Result<(), DispatchError> { - self.ctx.terminate(beneficiary, gas_meter) - } - - fn call( - &mut self, - to: &T::AccountId, - value: BalanceOf, - gas_meter: &mut GasMeter, - input_data: Vec, - ) -> ExecResult { - self.ctx.call(to.clone(), value, gas_meter, input_data) - } - - fn note_dispatch_call(&mut self, call: CallOf) { - self.ctx.deferred.push(DeferredAction::DispatchRuntimeCall { - origin: self.ctx.self_account.clone(), - call, - }); - } - - fn note_restore_to( - &mut self, - dest: AccountIdOf, - code_hash: CodeHash, - rent_allowance: BalanceOf, - delta: Vec, - ) { - self.ctx.deferred.push(DeferredAction::RestoreTo { - donor: self.ctx.self_account.clone(), - dest, - code_hash, - rent_allowance, - delta, - }); - } - - fn address(&self) -> &T::AccountId { - &self.ctx.self_account - } - - fn caller(&self) -> &T::AccountId { - &self.caller - } - - fn balance(&self) -> BalanceOf { - self.ctx.overlay.get_balance(&self.ctx.self_account) - } - - fn value_transferred(&self) -> BalanceOf { - self.value_transferred - } - - fn random(&self, subject: &[u8]) -> SeedOf { - T::Randomness::random(subject) - } - - fn now(&self) -> &MomentOf { - &self.timestamp - } - - fn minimum_balance(&self) -> BalanceOf { - self.ctx.config.existential_deposit - } - - fn tombstone_deposit(&self) -> BalanceOf { - self.ctx.config.tombstone_deposit - } - - fn deposit_event(&mut self, topics: Vec, data: Vec) { - self.ctx.deferred.push(DeferredAction::DepositEvent { - topics, - event: RawEvent::ContractExecution(self.ctx.self_account.clone(), data), - }); - } - - fn set_rent_allowance(&mut self, rent_allowance: BalanceOf) { - self.ctx - .overlay - .set_rent_allowance(&self.ctx.self_account, rent_allowance) - } - - fn rent_allowance(&self) -> BalanceOf { - self.ctx - .overlay - .get_rent_allowance(&self.ctx.self_account) - .unwrap_or(>::max_value()) // Must never be triggered actually - } - - fn block_number(&self) -> T::BlockNumber { - self.block_number - } - - fn max_value_size(&self) -> u32 { - self.ctx.config.max_value_size - } - - fn get_runtime_storage(&self, key: &[u8]) -> Option> { - unhashed::get_raw(&key) - } - - fn get_weight_price(&self, weight: Weight) -> BalanceOf { - T::WeightPrice::convert(weight) - } -} - -/// These tests exercise the executive layer. -/// -/// In these tests the VM/loader are mocked. Instead of dealing with wasm bytecode they use simple closures. -/// This allows you to tackle executive logic more thoroughly without writing a -/// wasm VM code. -/// -/// Because it's the executive layer: -/// -/// - no gas meter setup and teardown logic. All balances are *AFTER* gas purchase. -/// - executive layer doesn't alter any storage! -#[cfg(test)] -mod tests { - use super::{ - BalanceOf, DeferredAction, ExecFeeToken, ExecResult, ExecutionContext, Ext, Loader, - RawEvent, TransferFeeKind, TransferFeeToken, Vm, - }; - use crate::{ - account_db::AccountDb, - exec::{ExecError, ExecReturnValue, STATUS_SUCCESS}, - gas::{Gas, GasMeter}, - tests::{ExtBuilder, Test}, - CodeHash, Config, - }; - use assert_matches::assert_matches; - use sp_runtime::DispatchError; - use std::{cell::RefCell, collections::HashMap, marker::PhantomData, rc::Rc}; - - const ALICE: u64 = 1; - const BOB: u64 = 2; - const CHARLIE: u64 = 3; - - const GAS_LIMIT: Gas = 10_000_000_000; - - impl<'a, T, V, L> ExecutionContext<'a, T, V, L> - where - T: crate::Trait, - { - fn events(&self) -> Vec> { - self.deferred - .iter() - .filter(|action| match *action { - DeferredAction::DepositEvent { .. } => true, - _ => false, - }) - .cloned() - .collect() - } - } - - struct MockCtx<'a> { - ext: &'a mut dyn Ext, - input_data: Vec, - gas_meter: &'a mut GasMeter, - } - - #[derive(Clone)] - struct MockExecutable<'a>(Rc ExecResult + 'a>); - - impl<'a> MockExecutable<'a> { - fn new(f: impl Fn(MockCtx) -> ExecResult + 'a) -> Self { - MockExecutable(Rc::new(f)) - } - } - - struct MockLoader<'a> { - map: HashMap, MockExecutable<'a>>, - counter: u64, - } - - impl<'a> MockLoader<'a> { - fn empty() -> Self { - MockLoader { - map: HashMap::new(), - counter: 0, - } - } - - fn insert(&mut self, f: impl Fn(MockCtx) -> ExecResult + 'a) -> CodeHash { - // Generate code hashes as monotonically increasing values. - let code_hash = ::Hash::from_low_u64_be(self.counter); - - self.counter += 1; - self.map.insert(code_hash, MockExecutable::new(f)); - code_hash - } - } - - struct MockVm<'a> { - _marker: PhantomData<&'a ()>, - } - - impl<'a> MockVm<'a> { - fn new() -> Self { - MockVm { - _marker: PhantomData, - } - } - } - - impl<'a> Loader for MockLoader<'a> { - type Executable = MockExecutable<'a>; - - fn load_init(&self, code_hash: &CodeHash) -> Result { - self.map - .get(code_hash) - .cloned() - .ok_or_else(|| "code not found") - } - fn load_main(&self, code_hash: &CodeHash) -> Result { - self.map - .get(code_hash) - .cloned() - .ok_or_else(|| "code not found") - } - } - - impl<'a> Vm for MockVm<'a> { - type Executable = MockExecutable<'a>; - - fn execute>( - &self, - exec: &MockExecutable, - mut ext: E, - input_data: Vec, - gas_meter: &mut GasMeter, - ) -> ExecResult { - (exec.0)(MockCtx { - ext: &mut ext, - input_data, - gas_meter, - }) - } - } - - fn exec_success() -> ExecResult { - Ok(ExecReturnValue { - status: STATUS_SUCCESS, - data: Vec::new(), - }) - } - - #[test] - fn it_works() { - let value = Default::default(); - let mut gas_meter = GasMeter::::new(GAS_LIMIT); - let data = vec![]; - - let vm = MockVm::new(); - - let test_data = Rc::new(RefCell::new(vec![0usize])); - - let mut loader = MockLoader::empty(); - let exec_ch = loader.insert(|_ctx| { - test_data.borrow_mut().push(1); - exec_success() - }); - - ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.instantiate_contract(&BOB, exec_ch).unwrap(); - - assert_matches!(ctx.call(BOB, value, &mut gas_meter, data), Ok(_)); - }); - - assert_eq!(&*test_data.borrow(), &vec![0, 1]); - } - - #[test] - fn base_fees() { - let origin = ALICE; - let dest = BOB; - - // This test verifies that base fee for call is taken. - ExtBuilder::default().build().execute_with(|| { - let vm = MockVm::new(); - let loader = MockLoader::empty(); - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 0); - - let mut gas_meter = GasMeter::::new(GAS_LIMIT); - - let result = ctx.call(dest, 0, &mut gas_meter, vec![]); - assert_matches!(result, Ok(_)); - - let mut toks = gas_meter.tokens().iter(); - match_tokens!(toks, ExecFeeToken::Call,); - }); - - // This test verifies that base fee for instantiation is taken. - ExtBuilder::default().build().execute_with(|| { - let mut loader = MockLoader::empty(); - let code = loader.insert(|_| exec_success()); - - let vm = MockVm::new(); - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - - ctx.overlay.set_balance(&origin, 100); - - let mut gas_meter = GasMeter::::new(GAS_LIMIT); - - let result = ctx.instantiate(1, &mut gas_meter, &code, vec![]); - assert_matches!(result, Ok(_)); - - let mut toks = gas_meter.tokens().iter(); - match_tokens!(toks, ExecFeeToken::Instantiate,); - }); - } - - #[test] - fn transfer_works() { - // This test verifies that a contract is able to transfer - // some funds to another account. - let origin = ALICE; - let dest = BOB; - - let vm = MockVm::new(); - let loader = MockLoader::empty(); - - ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 0); - - let output = ctx - .call(dest, 55, &mut GasMeter::::new(GAS_LIMIT), vec![]) - .unwrap(); - - assert!(output.is_success()); - assert_eq!(ctx.overlay.get_balance(&origin), 45); - assert_eq!(ctx.overlay.get_balance(&dest), 55); - }); - } - - #[test] - fn changes_are_reverted_on_failing_call() { - // This test verifies that a contract is able to transfer - // some funds to another account. - let origin = ALICE; - let dest = BOB; - - let vm = MockVm::new(); - let mut loader = MockLoader::empty(); - let return_ch = loader.insert(|_| { - Ok(ExecReturnValue { - status: 1, - data: Vec::new(), - }) - }); - - ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 0); - - let output = ctx - .call(dest, 55, &mut GasMeter::::new(GAS_LIMIT), vec![]) - .unwrap(); - - assert!(!output.is_success()); - assert_eq!(ctx.overlay.get_balance(&origin), 100); - assert_eq!(ctx.overlay.get_balance(&dest), 0); - }); - } - - #[test] - fn transfer_fees() { - let origin = ALICE; - let dest = BOB; - - // This test sends 50 units of currency to a non-existent account. - // This should lead to creation of a new account thus - // a fee should be charged. - ExtBuilder::default() - .existential_deposit(15) - .build() - .execute_with(|| { - let vm = MockVm::new(); - let loader = MockLoader::empty(); - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 0); - - let mut gas_meter = GasMeter::::new(GAS_LIMIT); - - let result = ctx.call(dest, 50, &mut gas_meter, vec![]); - assert_matches!(result, Ok(_)); - - let mut toks = gas_meter.tokens().iter(); - match_tokens!( - toks, - ExecFeeToken::Call, - TransferFeeToken { - kind: TransferFeeKind::Transfer, - }, - ); - }); - - // This one is similar to the previous one but transfer to an existing account. - // In this test we expect that a regular transfer fee is charged. - ExtBuilder::default() - .existential_deposit(15) - .build() - .execute_with(|| { - let vm = MockVm::new(); - let loader = MockLoader::empty(); - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 15); - - let mut gas_meter = GasMeter::::new(GAS_LIMIT); - - let result = ctx.call(dest, 50, &mut gas_meter, vec![]); - assert_matches!(result, Ok(_)); - - let mut toks = gas_meter.tokens().iter(); - match_tokens!( - toks, - ExecFeeToken::Call, - TransferFeeToken { - kind: TransferFeeKind::Transfer, - }, - ); - }); - - // This test sends 50 units of currency as an endowment to a newly - // instantiated contract. - ExtBuilder::default() - .existential_deposit(15) - .build() - .execute_with(|| { - let mut loader = MockLoader::empty(); - let code = loader.insert(|_| exec_success()); - - let vm = MockVm::new(); - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 15); - - let mut gas_meter = GasMeter::::new(GAS_LIMIT); - - let result = ctx.instantiate(50, &mut gas_meter, &code, vec![]); - assert_matches!(result, Ok(_)); - - let mut toks = gas_meter.tokens().iter(); - match_tokens!( - toks, - ExecFeeToken::Instantiate, - TransferFeeToken { - kind: TransferFeeKind::ContractInstantiate, - }, - ); - }); - } - - #[test] - fn balance_too_low() { - // This test verifies that a contract can't send value if it's - // balance is too low. - let origin = ALICE; - let dest = BOB; - - let vm = MockVm::new(); - let loader = MockLoader::empty(); - - ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.set_balance(&origin, 0); - - let result = ctx.call(dest, 100, &mut GasMeter::::new(GAS_LIMIT), vec![]); - - assert_matches!( - result, - Err(ExecError { - reason: DispatchError::Other("balance too low to send value"), - buffer: _, - }) - ); - assert_eq!(ctx.overlay.get_balance(&origin), 0); - assert_eq!(ctx.overlay.get_balance(&dest), 0); - }); - } - - #[test] - fn output_is_returned_on_success() { - // Verifies that if a contract returns data with a successful exit status, this data - // is returned from the execution context. - let origin = ALICE; - let dest = BOB; - - let vm = MockVm::new(); - let mut loader = MockLoader::empty(); - let return_ch = loader.insert(|_| { - Ok(ExecReturnValue { - status: STATUS_SUCCESS, - data: vec![1, 2, 3, 4], - }) - }); - - ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); - - let result = ctx.call(dest, 0, &mut GasMeter::::new(GAS_LIMIT), vec![]); - - let output = result.unwrap(); - assert!(output.is_success()); - assert_eq!(output.data, vec![1, 2, 3, 4]); - }); - } - - #[test] - fn output_is_returned_on_failure() { - // Verifies that if a contract returns data with a failing exit status, this data - // is returned from the execution context. - let origin = ALICE; - let dest = BOB; - - let vm = MockVm::new(); - let mut loader = MockLoader::empty(); - let return_ch = loader.insert(|_| { - Ok(ExecReturnValue { - status: 1, - data: vec![1, 2, 3, 4], - }) - }); - - ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); - - let result = ctx.call(dest, 0, &mut GasMeter::::new(GAS_LIMIT), vec![]); - - let output = result.unwrap(); - assert!(!output.is_success()); - assert_eq!(output.data, vec![1, 2, 3, 4]); - }); - } - - #[test] - fn input_data_to_call() { - let vm = MockVm::new(); - let mut loader = MockLoader::empty(); - let input_data_ch = loader.insert(|ctx| { - assert_eq!(ctx.input_data, &[1, 2, 3, 4]); - exec_success() - }); - - // This one tests passing the input data into a contract via call. - ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay - .instantiate_contract(&BOB, input_data_ch) - .unwrap(); - - let result = ctx.call( - BOB, - 0, - &mut GasMeter::::new(GAS_LIMIT), - vec![1, 2, 3, 4], - ); - assert_matches!(result, Ok(_)); - }); - } - - #[test] - fn input_data_to_instantiate() { - let vm = MockVm::new(); - let mut loader = MockLoader::empty(); - let input_data_ch = loader.insert(|ctx| { - assert_eq!(ctx.input_data, &[1, 2, 3, 4]); - exec_success() - }); - - // This one tests passing the input data into a contract via instantiate. - ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - - ctx.overlay.set_balance(&ALICE, 100); - - let result = ctx.instantiate( - 1, - &mut GasMeter::::new(GAS_LIMIT), - &input_data_ch, - vec![1, 2, 3, 4], - ); - assert_matches!(result, Ok(_)); - }); - } - - #[test] - fn max_depth() { - // This test verifies that when we reach the maximal depth creation of an - // yet another context fails. - let value = Default::default(); - let reached_bottom = RefCell::new(false); - - let vm = MockVm::new(); - let mut loader = MockLoader::empty(); - let recurse_ch = loader.insert(|ctx| { - // Try to call into yourself. - let r = ctx.ext.call(&BOB, 0, ctx.gas_meter, vec![]); - - let mut reached_bottom = reached_bottom.borrow_mut(); - if !*reached_bottom { - // We are first time here, it means we just reached bottom. - // Verify that we've got proper error and set `reached_bottom`. - assert_matches!( - r, - Err(ExecError { - reason: DispatchError::Other("reached maximum depth, cannot make a call"), - buffer: _, - }) - ); - *reached_bottom = true; - } else { - // We just unwinding stack here. - assert_matches!(r, Ok(_)); - } - - exec_success() - }); - - ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&BOB, 1); - ctx.overlay.instantiate_contract(&BOB, recurse_ch).unwrap(); - - let result = ctx.call(BOB, value, &mut GasMeter::::new(GAS_LIMIT), vec![]); - - assert_matches!(result, Ok(_)); - }); - } - - #[test] - fn caller_returns_proper_values() { - let origin = ALICE; - let dest = BOB; - - let vm = MockVm::new(); - - let witnessed_caller_bob = RefCell::new(None::); - let witnessed_caller_charlie = RefCell::new(None::); - - let mut loader = MockLoader::empty(); - let bob_ch = loader.insert(|ctx| { - // Record the caller for bob. - *witnessed_caller_bob.borrow_mut() = Some(*ctx.ext.caller()); - - // Call into CHARLIE contract. - assert_matches!(ctx.ext.call(&CHARLIE, 0, ctx.gas_meter, vec![]), Ok(_)); - exec_success() - }); - let charlie_ch = loader.insert(|ctx| { - // Record the caller for charlie. - *witnessed_caller_charlie.borrow_mut() = Some(*ctx.ext.caller()); - exec_success() - }); - - ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); - - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.instantiate_contract(&dest, bob_ch).unwrap(); - ctx.overlay - .instantiate_contract(&CHARLIE, charlie_ch) - .unwrap(); - - let result = ctx.call(dest, 0, &mut GasMeter::::new(GAS_LIMIT), vec![]); - - assert_matches!(result, Ok(_)); - }); - - assert_eq!(&*witnessed_caller_bob.borrow(), &Some(origin)); - assert_eq!(&*witnessed_caller_charlie.borrow(), &Some(dest)); - } - - #[test] - fn address_returns_proper_values() { - let vm = MockVm::new(); - - let mut loader = MockLoader::empty(); - let bob_ch = loader.insert(|ctx| { - // Verify that address matches BOB. - assert_eq!(*ctx.ext.address(), BOB); - - // Call into charlie contract. - assert_matches!(ctx.ext.call(&CHARLIE, 0, ctx.gas_meter, vec![]), Ok(_)); - exec_success() - }); - let charlie_ch = loader.insert(|ctx| { - assert_eq!(*ctx.ext.address(), CHARLIE); - exec_success() - }); - - ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.instantiate_contract(&BOB, bob_ch).unwrap(); - ctx.overlay - .instantiate_contract(&CHARLIE, charlie_ch) - .unwrap(); - - let result = ctx.call(BOB, 0, &mut GasMeter::::new(GAS_LIMIT), vec![]); - - assert_matches!(result, Ok(_)); - }); - } - - #[test] - fn refuse_instantiate_with_value_below_existential_deposit() { - let vm = MockVm::new(); - - let mut loader = MockLoader::empty(); - let dummy_ch = loader.insert(|_| exec_success()); - - ExtBuilder::default() - .existential_deposit(15) - .build() - .execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - - assert_matches!( - ctx.instantiate( - 0, // <- zero endowment - &mut GasMeter::::new(GAS_LIMIT), - &dummy_ch, - vec![], - ), - Err(_) - ); - }); - } - - #[test] - fn instantiation_work_with_success_output() { - let vm = MockVm::new(); - - let mut loader = MockLoader::empty(); - let dummy_ch = loader.insert(|_| { - Ok(ExecReturnValue { - status: STATUS_SUCCESS, - data: vec![80, 65, 83, 83], - }) - }); - - ExtBuilder::default() - .existential_deposit(15) - .build() - .execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 1000); - - let instantiated_contract_address = assert_matches!( - ctx.instantiate( - 100, - &mut GasMeter::::new(GAS_LIMIT), - &dummy_ch, - vec![], - ), - Ok((address, ref output)) if output.data == vec![80, 65, 83, 83] => address - ); - - // Check that the newly created account has the expected code hash and - // there are instantiation event. - assert_eq!( - ctx.overlay - .get_code_hash(&instantiated_contract_address) - .unwrap(), - dummy_ch - ); - assert_eq!( - &ctx.events(), - &[ - DeferredAction::DepositEvent { - event: RawEvent::Transfer(ALICE, instantiated_contract_address, 100), - topics: Vec::new(), - }, - DeferredAction::DepositEvent { - event: RawEvent::Instantiated(ALICE, instantiated_contract_address), - topics: Vec::new(), - } - ] - ); - }); - } - - #[test] - fn instantiation_fails_with_failing_output() { - let vm = MockVm::new(); - - let mut loader = MockLoader::empty(); - let dummy_ch = loader.insert(|_| { - Ok(ExecReturnValue { - status: 1, - data: vec![70, 65, 73, 76], - }) - }); - - ExtBuilder::default() - .existential_deposit(15) - .build() - .execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 1000); - - let instantiated_contract_address = assert_matches!( - ctx.instantiate( - 100, - &mut GasMeter::::new(GAS_LIMIT), - &dummy_ch, - vec![], - ), - Ok((address, ref output)) if output.data == vec![70, 65, 73, 76] => address - ); - - // Check that the account has not been created. - assert!(ctx - .overlay - .get_code_hash(&instantiated_contract_address) - .is_none()); - assert!(ctx.events().is_empty()); - }); - } - - #[test] - fn instantiation_from_contract() { - let vm = MockVm::new(); - - let mut loader = MockLoader::empty(); - let dummy_ch = loader.insert(|_| exec_success()); - let instantiated_contract_address = Rc::new(RefCell::new(None::)); - let instantiator_ch = loader.insert({ - let dummy_ch = dummy_ch.clone(); - let instantiated_contract_address = Rc::clone(&instantiated_contract_address); - move |ctx| { - // Instantiate a contract and save it's address in `instantiated_contract_address`. - let (address, output) = ctx - .ext - .instantiate(&dummy_ch, 15u64, ctx.gas_meter, vec![]) - .unwrap(); - - *instantiated_contract_address.borrow_mut() = address.into(); - Ok(output) - } - }); - - ExtBuilder::default() - .existential_deposit(15) - .build() - .execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 1000); - ctx.overlay.set_balance(&BOB, 100); - ctx.overlay - .instantiate_contract(&BOB, instantiator_ch) - .unwrap(); - - assert_matches!( - ctx.call(BOB, 20, &mut GasMeter::::new(GAS_LIMIT), vec![]), - Ok(_) - ); - - let instantiated_contract_address = instantiated_contract_address - .borrow() - .as_ref() - .unwrap() - .clone(); - - // Check that the newly created account has the expected code hash and - // there are instantiation event. - assert_eq!( - ctx.overlay - .get_code_hash(&instantiated_contract_address) - .unwrap(), - dummy_ch - ); - assert_eq!( - &ctx.events(), - &[ - DeferredAction::DepositEvent { - event: RawEvent::Transfer(ALICE, BOB, 20), - topics: Vec::new(), - }, - DeferredAction::DepositEvent { - event: RawEvent::Transfer(BOB, instantiated_contract_address, 15), - topics: Vec::new(), - }, - DeferredAction::DepositEvent { - event: RawEvent::Instantiated(BOB, instantiated_contract_address), - topics: Vec::new(), - }, - ] - ); - }); - } - - #[test] - fn instantiation_traps() { - let vm = MockVm::new(); - - let mut loader = MockLoader::empty(); - let dummy_ch = loader.insert(|_| { - Err(ExecError { - reason: "It's a trap!".into(), - buffer: Vec::new(), - }) - }); - let instantiator_ch = loader.insert({ - let dummy_ch = dummy_ch.clone(); - move |ctx| { - // Instantiate a contract and save it's address in `instantiated_contract_address`. - assert_matches!( - ctx.ext.instantiate(&dummy_ch, 15u64, ctx.gas_meter, vec![]), - Err(ExecError { - reason: DispatchError::Other("It's a trap!"), - buffer: _, - }) - ); - - exec_success() - } - }); - - ExtBuilder::default() - .existential_deposit(15) - .build() - .execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 1000); - ctx.overlay.set_balance(&BOB, 100); - ctx.overlay - .instantiate_contract(&BOB, instantiator_ch) - .unwrap(); - - assert_matches!( - ctx.call(BOB, 20, &mut GasMeter::::new(GAS_LIMIT), vec![]), - Ok(_) - ); - - // The contract wasn't instantiated so we don't expect to see an instantiation - // event here. - assert_eq!( - &ctx.events(), - &[DeferredAction::DepositEvent { - event: RawEvent::Transfer(ALICE, BOB, 20), - topics: Vec::new(), - },] - ); - }); - } - - #[test] - fn termination_from_instantiate_fails() { - let vm = MockVm::new(); - - let mut loader = MockLoader::empty(); - - let terminate_ch = loader.insert(|mut ctx| { - ctx.ext.terminate(&ALICE, &mut ctx.gas_meter).unwrap(); - exec_success() - }); - - ExtBuilder::default() - .existential_deposit(15) - .build() - .execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 1000); - - assert_matches!( - ctx.instantiate( - 100, - &mut GasMeter::::new(GAS_LIMIT), - &terminate_ch, - vec![], - ), - Err(ExecError { - reason: DispatchError::Other("insufficient remaining balance"), - buffer - }) if buffer == Vec::::new() - ); - - assert_eq!(&ctx.events(), &[]); - }); - } - - #[test] - fn rent_allowance() { - let vm = MockVm::new(); - let mut loader = MockLoader::empty(); - let rent_allowance_ch = loader.insert(|ctx| { - assert_eq!(ctx.ext.rent_allowance(), >::max_value()); - ctx.ext.set_rent_allowance(10); - assert_eq!(ctx.ext.rent_allowance(), 10); - exec_success() - }); - - ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - - ctx.overlay.set_balance(&ALICE, 100); - - let result = ctx.instantiate( - 1, - &mut GasMeter::::new(GAS_LIMIT), - &rent_allowance_ch, - vec![], - ); - assert_matches!(result, Ok(_)); - }); - } -} diff --git a/rococo-parachains/pallets/contracts/src/gas.rs b/rococo-parachains/pallets/contracts/src/gas.rs deleted file mode 100644 index a9b5155507..0000000000 --- a/rococo-parachains/pallets/contracts/src/gas.rs +++ /dev/null @@ -1,348 +0,0 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -use crate::Trait; -use frame_support::dispatch::{ - DispatchError, DispatchErrorWithPostInfo, DispatchResultWithPostInfo, PostDispatchInfo, -}; -use sp_runtime::traits::Zero; -use sp_std::marker::PhantomData; - -#[cfg(test)] -use std::{any::Any, fmt::Debug}; - -// Gas is essentially the same as weight. It is a 1 to 1 correspondence. -pub type Gas = frame_support::weights::Weight; - -#[must_use] -#[derive(Debug, PartialEq, Eq)] -pub enum GasMeterResult { - Proceed, - OutOfGas, -} - -impl GasMeterResult { - pub fn is_out_of_gas(&self) -> bool { - match *self { - GasMeterResult::OutOfGas => true, - GasMeterResult::Proceed => false, - } - } -} - -#[cfg(not(test))] -pub trait TestAuxiliaries {} -#[cfg(not(test))] -impl TestAuxiliaries for T {} - -#[cfg(test)] -pub trait TestAuxiliaries: Any + Debug + PartialEq + Eq {} -#[cfg(test)] -impl TestAuxiliaries for T {} - -/// This trait represents a token that can be used for charging `GasMeter`. -/// There is no other way of charging it. -/// -/// Implementing type is expected to be super lightweight hence `Copy` (`Clone` is added -/// for consistency). If inlined there should be no observable difference compared -/// to a hand-written code. -pub trait Token: Copy + Clone + TestAuxiliaries { - /// Metadata type, which the token can require for calculating the amount - /// of gas to charge. Can be a some configuration type or - /// just the `()`. - type Metadata; - - /// Calculate amount of gas that should be taken by this token. - /// - /// This function should be really lightweight and must not fail. It is not - /// expected that implementors will query the storage or do any kinds of heavy operations. - /// - /// That said, implementors of this function still can run into overflows - /// while calculating the amount. In this case it is ok to use saturating operations - /// since on overflow they will return `max_value` which should consume all gas. - fn calculate_amount(&self, metadata: &Self::Metadata) -> Gas; -} - -/// A wrapper around a type-erased trait object of what used to be a `Token`. -#[cfg(test)] -pub struct ErasedToken { - pub description: String, - pub token: Box, -} - -pub struct GasMeter { - gas_limit: Gas, - /// Amount of gas left from initial gas limit. Can reach zero. - gas_left: Gas, - _phantom: PhantomData, - #[cfg(test)] - tokens: Vec, -} -impl GasMeter { - pub fn new(gas_limit: Gas) -> Self { - GasMeter { - gas_limit, - gas_left: gas_limit, - _phantom: PhantomData, - #[cfg(test)] - tokens: Vec::new(), - } - } - - /// Account for used gas. - /// - /// Amount is calculated by the given `token`. - /// - /// Returns `OutOfGas` if there is not enough gas or addition of the specified - /// amount of gas has lead to overflow. On success returns `Proceed`. - /// - /// NOTE that amount is always consumed, i.e. if there is not enough gas - /// then the counter will be set to zero. - #[inline] - pub fn charge>( - &mut self, - metadata: &Tok::Metadata, - token: Tok, - ) -> GasMeterResult { - #[cfg(test)] - { - // Unconditionally add the token to the storage. - let erased_tok = ErasedToken { - description: format!("{:?}", token), - token: Box::new(token), - }; - self.tokens.push(erased_tok); - } - - let amount = token.calculate_amount(metadata); - let new_value = match self.gas_left.checked_sub(amount) { - None => None, - Some(val) => Some(val), - }; - - // We always consume the gas even if there is not enough gas. - self.gas_left = new_value.unwrap_or_else(Zero::zero); - - match new_value { - Some(_) => GasMeterResult::Proceed, - None => GasMeterResult::OutOfGas, - } - } - - // Account for not fully used gas. - // - // This can be used after dispatching a runtime call to refund gas that was not - // used by the dispatchable. - pub fn refund(&mut self, gas: Gas) { - self.gas_left = self.gas_left.saturating_add(gas).max(self.gas_limit); - } - - /// Allocate some amount of gas and perform some work with - /// a newly created nested gas meter. - /// - /// Invokes `f` with either the gas meter that has `amount` gas left or - /// with `None`, if this gas meter has not enough gas to allocate given `amount`. - /// - /// All unused gas in the nested gas meter is returned to this gas meter. - pub fn with_nested>) -> R>( - &mut self, - amount: Gas, - f: F, - ) -> R { - // NOTE that it is ok to allocate all available gas since it still ensured - // by `charge` that it doesn't reach zero. - if self.gas_left < amount { - f(None) - } else { - self.gas_left = self.gas_left - amount; - let mut nested = GasMeter::new(amount); - - let r = f(Some(&mut nested)); - - self.gas_left = self.gas_left + nested.gas_left; - - r - } - } - - /// Returns how much gas left from the initial budget. - pub fn gas_spent(&self) -> Gas { - self.gas_limit - self.gas_left - } - - /// Returns how much gas left from the initial budget. - pub fn gas_left(&self) -> Gas { - self.gas_left - } - - /// Turn this GasMeter into a DispatchResult that contains the actually used gas. - pub fn into_dispatch_result(self, result: Result) -> DispatchResultWithPostInfo - where - E: Into, - { - let post_info = PostDispatchInfo { - actual_weight: Some(self.gas_spent()), - pays_fee: Default::default(), - }; - - result - .map(|_| post_info) - .map_err(|e| DispatchErrorWithPostInfo { - post_info, - error: e.into(), - }) - } - - #[cfg(test)] - pub fn tokens(&self) -> &[ErasedToken] { - &self.tokens - } -} - -/// A simple utility macro that helps to match against a -/// list of tokens. -#[macro_export] -macro_rules! match_tokens { - ($tokens_iter:ident,) => { - }; - ($tokens_iter:ident, $x:expr, $($rest:tt)*) => { - { - let next = ($tokens_iter).next().unwrap(); - let pattern = $x; - - // Note that we don't specify the type name directly in this macro, - // we only have some expression $x of some type. At the same time, we - // have an iterator of Box and to downcast we need to specify - // the type which we want downcast to. - // - // So what we do is we assign `_pattern_typed_next_ref` to a variable which has - // the required type. - // - // Then we make `_pattern_typed_next_ref = token.downcast_ref()`. This makes - // rustc infer the type `T` (in `downcast_ref`) to be the same as in $x. - - let mut _pattern_typed_next_ref = &pattern; - _pattern_typed_next_ref = match next.token.downcast_ref() { - Some(p) => { - assert_eq!(p, &pattern); - p - } - None => { - panic!("expected type {} got {}", stringify!($x), next.description); - } - }; - } - - match_tokens!($tokens_iter, $($rest)*); - }; -} - -#[cfg(test)] -mod tests { - use super::{GasMeter, Token}; - use crate::tests::Test; - - /// A trivial token that charges the specified number of gas units. - #[derive(Copy, Clone, PartialEq, Eq, Debug)] - struct SimpleToken(u64); - impl Token for SimpleToken { - type Metadata = (); - fn calculate_amount(&self, _metadata: &()) -> u64 { - self.0 - } - } - - struct MultiplierTokenMetadata { - multiplier: u64, - } - /// A simple token that charges for the given amount multiplied to - /// a multiplier taken from a given metadata. - #[derive(Copy, Clone, PartialEq, Eq, Debug)] - struct MultiplierToken(u64); - - impl Token for MultiplierToken { - type Metadata = MultiplierTokenMetadata; - fn calculate_amount(&self, metadata: &MultiplierTokenMetadata) -> u64 { - // Probably you want to use saturating mul in production code. - self.0 * metadata.multiplier - } - } - - #[test] - fn it_works() { - let gas_meter = GasMeter::::new(50000); - assert_eq!(gas_meter.gas_left(), 50000); - } - - #[test] - fn simple() { - let mut gas_meter = GasMeter::::new(50000); - - let result = gas_meter.charge( - &MultiplierTokenMetadata { multiplier: 3 }, - MultiplierToken(10), - ); - assert!(!result.is_out_of_gas()); - - assert_eq!(gas_meter.gas_left(), 49_970); - } - - #[test] - fn tracing() { - let mut gas_meter = GasMeter::::new(50000); - assert!(!gas_meter.charge(&(), SimpleToken(1)).is_out_of_gas()); - assert!(!gas_meter - .charge( - &MultiplierTokenMetadata { multiplier: 3 }, - MultiplierToken(10) - ) - .is_out_of_gas()); - - let mut tokens = gas_meter.tokens()[0..2].iter(); - match_tokens!(tokens, SimpleToken(1), MultiplierToken(10),); - } - - // This test makes sure that nothing can be executed if there is no gas. - #[test] - fn refuse_to_execute_anything_if_zero() { - let mut gas_meter = GasMeter::::new(0); - assert!(gas_meter.charge(&(), SimpleToken(1)).is_out_of_gas()); - } - - // Make sure that if the gas meter is charged by exceeding amount then not only an error - // returned for that charge, but also for all consequent charges. - // - // This is not strictly necessary, because the execution should be interrupted immediately - // if the gas meter runs out of gas. However, this is just a nice property to have. - #[test] - fn overcharge_is_unrecoverable() { - let mut gas_meter = GasMeter::::new(200); - - // The first charge is should lead to OOG. - assert!(gas_meter.charge(&(), SimpleToken(300)).is_out_of_gas()); - - // The gas meter is emptied at this moment, so this should also fail. - assert!(gas_meter.charge(&(), SimpleToken(1)).is_out_of_gas()); - } - - // Charging the exact amount that the user paid for should be - // possible. - #[test] - fn charge_exact_amount() { - let mut gas_meter = GasMeter::::new(25); - assert!(!gas_meter.charge(&(), SimpleToken(25)).is_out_of_gas()); - } -} diff --git a/rococo-parachains/pallets/contracts/src/lib.rs b/rococo-parachains/pallets/contracts/src/lib.rs deleted file mode 100644 index 6751e8bcd8..0000000000 --- a/rococo-parachains/pallets/contracts/src/lib.rs +++ /dev/null @@ -1,927 +0,0 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! # Contract Module -//! -//! The Contract module provides functionality for the runtime to deploy and execute WebAssembly smart-contracts. -//! -//! - [`contract::Trait`](./trait.Trait.html) -//! - [`Call`](./enum.Call.html) -//! -//! ## Overview -//! -//! This module extends accounts based on the `Currency` trait to have smart-contract functionality. It can -//! be used with other modules that implement accounts based on `Currency`. These "smart-contract accounts" -//! have the ability to instantiate smart-contracts and make calls to other contract and non-contract accounts. -//! -//! The smart-contract code is stored once in a `code_cache`, and later retrievable via its `code_hash`. -//! This means that multiple smart-contracts can be instantiated from the same `code_cache`, without replicating -//! the code each time. -//! -//! When a smart-contract is called, its associated code is retrieved via the code hash and gets executed. -//! This call can alter the storage entries of the smart-contract account, instantiate new smart-contracts, -//! or call other smart-contracts. -//! -//! Finally, when an account is reaped, its associated code and storage of the smart-contract account -//! will also be deleted. -//! -//! ### Gas -//! -//! Senders must specify a gas limit with every call, as all instructions invoked by the smart-contract require gas. -//! Unused gas is refunded after the call, regardless of the execution outcome. -//! -//! If the gas limit is reached, then all calls and state changes (including balance transfers) are only -//! reverted at the current call's contract level. For example, if contract A calls B and B runs out of gas mid-call, -//! then all of B's calls are reverted. Assuming correct error handling by contract A, A's other calls and state -//! changes still persist. -//! -//! ### Notable Scenarios -//! -//! Contract call failures are not always cascading. When failures occur in a sub-call, they do not "bubble up", -//! and the call will only revert at the specific contract level. For example, if contract A calls contract B, and B -//! fails, A can decide how to handle that failure, either proceeding or reverting A's changes. -//! -//! ## Interface -//! -//! ### Dispatchable functions -//! -//! * `put_code` - Stores the given binary Wasm code into the chain's storage and returns its `code_hash`. -//! * `instantiate` - Deploys a new contract from the given `code_hash`, optionally transferring some balance. -//! This instantiates a new smart contract account and calls its contract deploy handler to -//! initialize the contract. -//! * `call` - Makes a call to an account, optionally transferring some balance. -//! -//! ## Usage -//! -//! The Contract module is a work in progress. The following examples show how this Contract module -//! can be used to instantiate and call contracts. -//! -//! * [`ink`](https://github.com/paritytech/ink) is -//! an [`eDSL`](https://wiki.haskell.org/Embedded_domain_specific_language) that enables writing -//! WebAssembly based smart contracts in the Rust programming language. This is a work in progress. -//! -//! ## Related Modules -//! -//! * [Balances](../pallet_balances/index.html) - -#![cfg_attr(not(feature = "std"), no_std)] - -#[macro_use] -mod gas; - -mod account_db; -mod exec; -mod rent; -mod wasm; - -#[cfg(test)] -mod tests; - -use crate::{ - account_db::{AccountDb, DirectAccountDb}, - exec::ExecutionContext, - wasm::{WasmLoader, WasmVm}, -}; - -pub use crate::{ - exec::{ExecError, ExecResult, ExecReturnValue, StatusCode}, - gas::{Gas, GasMeter}, -}; - -use codec::{Codec, Decode, Encode}; -use cumulus_pallet_contracts_primitives::{ContractAccessError, RentProjection}; -use frame_support::{ - decl_error, decl_event, decl_module, decl_storage, - dispatch::{DispatchResult, DispatchResultWithPostInfo, Dispatchable, PostDispatchInfo}, - parameter_types, - traits::{Currency, Get, OnUnbalanced, Randomness, Time}, - weights::{GetDispatchInfo, Weight}, - Parameter, -}; -use frame_system::{ensure_root, ensure_signed, RawOrigin}; -#[cfg(feature = "std")] -use serde::{Deserialize, Serialize}; -use sp_core::crypto::UncheckedFrom; -use sp_runtime::{ - traits::{Convert, Hash, MaybeSerializeDeserialize, Member, StaticLookup, Zero}, - RuntimeDebug, -}; -use sp_std::{fmt::Debug, marker::PhantomData, prelude::*}; - -pub type CodeHash = ::Hash; -pub type TrieId = Vec; - -/// A function that generates an `AccountId` for a contract upon instantiation. -pub trait ContractAddressFor { - fn contract_address_for(code_hash: &CodeHash, data: &[u8], origin: &AccountId) -> AccountId; -} - -/// A function that returns the fee for dispatching a `Call`. -pub trait ComputeDispatchFee { - fn compute_dispatch_fee(call: &Call) -> Balance; -} - -/// Information for managing an account and its sub trie abstraction. -/// This is the required info to cache for an account -#[derive(Encode, Decode, RuntimeDebug)] -pub enum ContractInfo { - Alive(AliveContractInfo), - Tombstone(TombstoneContractInfo), -} - -impl ContractInfo { - /// If contract is alive then return some alive info - pub fn get_alive(self) -> Option> { - if let ContractInfo::Alive(alive) = self { - Some(alive) - } else { - None - } - } - /// If contract is alive then return some reference to alive info - pub fn as_alive(&self) -> Option<&AliveContractInfo> { - if let ContractInfo::Alive(ref alive) = self { - Some(alive) - } else { - None - } - } - /// If contract is alive then return some mutable reference to alive info - pub fn as_alive_mut(&mut self) -> Option<&mut AliveContractInfo> { - if let ContractInfo::Alive(ref mut alive) = self { - Some(alive) - } else { - None - } - } - - /// If contract is tombstone then return some tombstone info - pub fn get_tombstone(self) -> Option> { - if let ContractInfo::Tombstone(tombstone) = self { - Some(tombstone) - } else { - None - } - } - /// If contract is tombstone then return some reference to tombstone info - pub fn as_tombstone(&self) -> Option<&TombstoneContractInfo> { - if let ContractInfo::Tombstone(ref tombstone) = self { - Some(tombstone) - } else { - None - } - } - /// If contract is tombstone then return some mutable reference to tombstone info - pub fn as_tombstone_mut(&mut self) -> Option<&mut TombstoneContractInfo> { - if let ContractInfo::Tombstone(ref mut tombstone) = self { - Some(tombstone) - } else { - None - } - } -} - -pub type AliveContractInfo = - RawAliveContractInfo, BalanceOf, ::BlockNumber>; - -/// Information for managing an account and its sub trie abstraction. -/// This is the required info to cache for an account. -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] -pub struct RawAliveContractInfo { - /// Unique ID for the subtree encoded as a bytes vector. - pub trie_id: TrieId, - /// The total number of bytes used by this contract. - /// - /// It is a sum of each key-value pair stored by this contract. - pub storage_size: u32, - /// The number of key-value pairs that have values of zero length. - /// The condition `empty_pair_count ≤ total_pair_count` always holds. - pub empty_pair_count: u32, - /// The total number of key-value pairs in storage of this contract. - pub total_pair_count: u32, - /// The code associated with a given account. - pub code_hash: CodeHash, - /// Pay rent at most up to this value. - pub rent_allowance: Balance, - /// Last block rent has been payed. - pub deduct_block: BlockNumber, - /// Last block child storage has been written. - pub last_write: Option, -} - -impl RawAliveContractInfo { - pub fn prefixed_key(&self, key: &[u8]) -> Vec { - prefixed_key(&self.trie_id, key) - } -} - -pub(crate) fn prefixed_key(prefix: &[u8], key: &[u8]) -> Vec { - prefix.iter().chain(key.iter()).cloned().collect() -} - -pub type TombstoneContractInfo = - RawTombstoneContractInfo<::Hash, ::Hashing>; - -#[derive(Encode, Decode, PartialEq, Eq, RuntimeDebug)] -pub struct RawTombstoneContractInfo(H, PhantomData); - -impl RawTombstoneContractInfo -where - H: Member - + MaybeSerializeDeserialize - + Debug - + AsRef<[u8]> - + AsMut<[u8]> - + Copy - + Default - + sp_std::hash::Hash - + Codec, - Hasher: Hash, -{ - fn new(storage_root: &[u8], code_hash: H) -> Self { - let mut buf = Vec::new(); - storage_root.using_encoded(|encoded| buf.extend_from_slice(encoded)); - buf.extend_from_slice(code_hash.as_ref()); - RawTombstoneContractInfo(::hash(&buf[..]), PhantomData) - } -} - -/// Get a trie id (trie id must be unique and collision resistant depending upon its context). -/// Note that it is different than encode because trie id should be collision resistant -/// (being a proper unique identifier). -pub trait TrieIdGenerator { - /// Get a trie id for an account, using reference to parent account trie id to ensure - /// uniqueness of trie id. - /// - /// The implementation must ensure every new trie id is unique: two consecutive calls with the - /// same parameter needs to return different trie id values. - fn trie_id(account_id: &AccountId) -> TrieId; -} - -/// Get trie id from `account_id`. -pub struct TrieIdFromParentCounter(PhantomData); - -/// This generator uses inner counter for account id and applies the hash over `AccountId + -/// accountid_counter`. -impl TrieIdGenerator for TrieIdFromParentCounter -where - T::AccountId: AsRef<[u8]>, -{ - fn trie_id(account_id: &T::AccountId) -> TrieId { - // Note that skipping a value due to error is not an issue here. - // We only need uniqueness, not sequence. - let new_seed = AccountCounter::mutate(|v| { - *v = v.wrapping_add(1); - *v - }); - - let mut buf = Vec::new(); - buf.extend_from_slice(account_id.as_ref()); - buf.extend_from_slice(&new_seed.to_le_bytes()[..]); - T::Hashing::hash(&buf[..]).as_ref().into() - } -} - -pub type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; -pub type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; - -parameter_types! { - /// A reasonable default value for [`Trait::SignedClaimedHandicap`]. - pub const DefaultSignedClaimHandicap: u32 = 2; - /// A reasonable default value for [`Trait::TombstoneDeposit`]. - pub const DefaultTombstoneDeposit: u32 = 16; - /// A reasonable default value for [`Trait::StorageSizeOffset`]. - pub const DefaultStorageSizeOffset: u32 = 8; - /// A reasonable default value for [`Trait::RentByteFee`]. - pub const DefaultRentByteFee: u32 = 4; - /// A reasonable default value for [`Trait::RentDepositOffset`]. - pub const DefaultRentDepositOffset: u32 = 1000; - /// A reasonable default value for [`Trait::SurchargeReward`]. - pub const DefaultSurchargeReward: u32 = 150; - /// A reasonable default value for [`Trait::MaxDepth`]. - pub const DefaultMaxDepth: u32 = 32; - /// A reasonable default value for [`Trait::MaxValueSize`]. - pub const DefaultMaxValueSize: u32 = 16_384; -} - -pub trait Trait: frame_system::Trait { - type Time: Time; - type Randomness: Randomness; - - /// The currency in which fees are paid and contract balances are held. - type Currency: Currency; - - /// The outer call dispatch type. - type Call: Parameter - + Dispatchable::Origin> - + GetDispatchInfo; - - /// The overarching event type. - type Event: From> + Into<::Event>; - - /// A function type to get the contract address given the instantiator. - type DetermineContractAddress: ContractAddressFor, Self::AccountId>; - - /// trie id generator - type TrieIdGenerator: TrieIdGenerator; - - /// Handler for rent payments. - type RentPayment: OnUnbalanced>; - - /// Number of block delay an extrinsic claim surcharge has. - /// - /// When claim surcharge is called by an extrinsic the rent is checked - /// for current_block - delay - type SignedClaimHandicap: Get; - - /// The minimum amount required to generate a tombstone. - type TombstoneDeposit: Get>; - - /// A size offset for an contract. A just created account with untouched storage will have that - /// much of storage from the perspective of the state rent. - /// - /// This is a simple way to ensure that contracts with empty storage eventually get deleted by - /// making them pay rent. This creates an incentive to remove them early in order to save rent. - type StorageSizeOffset: Get; - - /// Price of a byte of storage per one block interval. Should be greater than 0. - type RentByteFee: Get>; - - /// The amount of funds a contract should deposit in order to offset - /// the cost of one byte. - /// - /// Let's suppose the deposit is 1,000 BU (balance units)/byte and the rent is 1 BU/byte/day, - /// then a contract with 1,000,000 BU that uses 1,000 bytes of storage would pay no rent. - /// But if the balance reduced to 500,000 BU and the storage stayed the same at 1,000, - /// then it would pay 500 BU/day. - type RentDepositOffset: Get>; - - /// Reward that is received by the party whose touch has led - /// to removal of a contract. - type SurchargeReward: Get>; - - /// The maximum nesting level of a call/instantiate stack. - type MaxDepth: Get; - - /// The maximum size of a storage value in bytes. - type MaxValueSize: Get; - - /// Used to answer contracts's queries regarding the current weight price. This is **not** - /// used to calculate the actual fee and is only for informational purposes. - type WeightPrice: Convert>; -} - -/// Simple contract address determiner. -/// -/// Address calculated from the code (of the constructor), input data to the constructor, -/// and the account id that requested the account creation. -/// -/// Formula: `blake2_256(blake2_256(code) + blake2_256(data) + origin)` -pub struct SimpleAddressDeterminer(PhantomData); -impl ContractAddressFor, T::AccountId> for SimpleAddressDeterminer -where - T::AccountId: UncheckedFrom + AsRef<[u8]>, -{ - fn contract_address_for( - code_hash: &CodeHash, - data: &[u8], - origin: &T::AccountId, - ) -> T::AccountId { - let data_hash = T::Hashing::hash(data); - - let mut buf = Vec::new(); - buf.extend_from_slice(code_hash.as_ref()); - buf.extend_from_slice(data_hash.as_ref()); - buf.extend_from_slice(origin.as_ref()); - - UncheckedFrom::unchecked_from(T::Hashing::hash(&buf[..])) - } -} - -decl_error! { - /// Error for the contracts module. - pub enum Error for Module { - /// A new schedule must have a greater version than the current one. - InvalidScheduleVersion, - /// An origin must be signed or inherent and auxiliary sender only provided on inherent. - InvalidSurchargeClaim, - /// Cannot restore from nonexisting or tombstone contract. - InvalidSourceContract, - /// Cannot restore to nonexisting or alive contract. - InvalidDestinationContract, - /// Tombstones don't match. - InvalidTombstone, - /// An origin TrieId written in the current block. - InvalidContractOrigin - } -} - -decl_module! { - /// Contracts module. - pub struct Module for enum Call where origin: ::Origin { - type Error = Error; - - /// Number of block delay an extrinsic claim surcharge has. - /// - /// When claim surcharge is called by an extrinsic the rent is checked - /// for current_block - delay - const SignedClaimHandicap: T::BlockNumber = T::SignedClaimHandicap::get(); - - /// The minimum amount required to generate a tombstone. - const TombstoneDeposit: BalanceOf = T::TombstoneDeposit::get(); - - /// A size offset for an contract. A just created account with untouched storage will have that - /// much of storage from the perspective of the state rent. - /// - /// This is a simple way to ensure that contracts with empty storage eventually get deleted - /// by making them pay rent. This creates an incentive to remove them early in order to save - /// rent. - const StorageSizeOffset: u32 = T::StorageSizeOffset::get(); - - /// Price of a byte of storage per one block interval. Should be greater than 0. - const RentByteFee: BalanceOf = T::RentByteFee::get(); - - /// The amount of funds a contract should deposit in order to offset - /// the cost of one byte. - /// - /// Let's suppose the deposit is 1,000 BU (balance units)/byte and the rent is 1 BU/byte/day, - /// then a contract with 1,000,000 BU that uses 1,000 bytes of storage would pay no rent. - /// But if the balance reduced to 500,000 BU and the storage stayed the same at 1,000, - /// then it would pay 500 BU/day. - const RentDepositOffset: BalanceOf = T::RentDepositOffset::get(); - - /// Reward that is received by the party whose touch has led - /// to removal of a contract. - const SurchargeReward: BalanceOf = T::SurchargeReward::get(); - - /// The maximum nesting level of a call/instantiate stack. A reasonable default - /// value is 100. - const MaxDepth: u32 = T::MaxDepth::get(); - - /// The maximum size of a storage value in bytes. A reasonable default is 16 KiB. - const MaxValueSize: u32 = T::MaxValueSize::get(); - - fn deposit_event() = default; - - /// Updates the schedule for metering contracts. - /// - /// The schedule must have a greater version than the stored schedule. - #[weight = 0] - pub fn update_schedule(origin, schedule: Schedule) -> DispatchResult { - ensure_root(origin)?; - if >::current_schedule().version >= schedule.version { - Err(Error::::InvalidScheduleVersion)? - } - - Self::deposit_event(RawEvent::ScheduleUpdated(schedule.version)); - CurrentSchedule::put(schedule); - - Ok(()) - } - - /// Stores the given binary Wasm code into the chain's storage and returns its `codehash`. - /// You can instantiate contracts only with stored code. - #[weight = Module::::calc_code_put_costs(&code)] - pub fn put_code( - origin, - code: Vec - ) -> DispatchResult { - ensure_signed(origin)?; - let schedule = >::current_schedule(); - let result = wasm::save_code::(code, &schedule); - if let Ok(code_hash) = result { - Self::deposit_event(RawEvent::CodeStored(code_hash)); - } - result.map(|_| ()).map_err(Into::into) - } - - /// Makes a call to an account, optionally transferring some balance. - /// - /// * If the account is a smart-contract account, the associated code will be - /// executed and any value will be transferred. - /// * If the account is a regular account, any value will be transferred. - /// * If no account exists and the call value is not less than `existential_deposit`, - /// a regular account will be created and any value will be transferred. - #[weight = *gas_limit] - pub fn call( - origin, - dest: ::Source, - #[compact] value: BalanceOf, - #[compact] gas_limit: Gas, - data: Vec - ) -> DispatchResultWithPostInfo { - let origin = ensure_signed(origin)?; - let dest = T::Lookup::lookup(dest)?; - let mut gas_meter = GasMeter::new(gas_limit); - - let result = Self::execute_wasm(origin, &mut gas_meter, |ctx, gas_meter| { - ctx.call(dest, value, gas_meter, data) - }); - gas_meter.into_dispatch_result(result.map_err(|e| e.reason)) - } - - /// Instantiates a new contract from the `codehash` generated by `put_code`, optionally transferring some balance. - /// - /// Instantiation is executed as follows: - /// - /// - The destination address is computed based on the sender and hash of the code. - /// - The smart-contract account is created at the computed address. - /// - The `ctor_code` is executed in the context of the newly-created account. Buffer returned - /// after the execution is saved as the `code` of the account. That code will be invoked - /// upon any call received by this account. - /// - The contract is initialized. - #[weight = *gas_limit] - pub fn instantiate( - origin, - #[compact] endowment: BalanceOf, - #[compact] gas_limit: Gas, - code_hash: CodeHash, - data: Vec - ) -> DispatchResultWithPostInfo { - let origin = ensure_signed(origin)?; - let mut gas_meter = GasMeter::new(gas_limit); - - let result = Self::execute_wasm(origin, &mut gas_meter, |ctx, gas_meter| { - ctx.instantiate(endowment, gas_meter, &code_hash, data) - .map(|(_address, output)| output) - }); - gas_meter.into_dispatch_result(result.map_err(|e| e.reason)) - } - - /// Allows block producers to claim a small reward for evicting a contract. If a block producer - /// fails to do so, a regular users will be allowed to claim the reward. - /// - /// If contract is not evicted as a result of this call, no actions are taken and - /// the sender is not eligible for the reward. - #[weight = 0] - fn claim_surcharge(origin, dest: T::AccountId, aux_sender: Option) { - let origin = origin.into(); - let (signed, rewarded) = match (origin, aux_sender) { - (Ok(frame_system::RawOrigin::Signed(account)), None) => { - (true, account) - }, - (Ok(frame_system::RawOrigin::None), Some(aux_sender)) => { - (false, aux_sender) - }, - _ => Err(Error::::InvalidSurchargeClaim)?, - }; - - // Add some advantage for block producers (who send unsigned extrinsics) by - // adding a handicap: for signed extrinsics we use a slightly older block number - // for the eviction check. This can be viewed as if we pushed regular users back in past. - let handicap = if signed { - T::SignedClaimHandicap::get() - } else { - Zero::zero() - }; - - // If poking the contract has lead to eviction of the contract, give out the rewards. - if rent::snitch_contract_should_be_evicted::(&dest, handicap) { - T::Currency::deposit_into_existing(&rewarded, T::SurchargeReward::get())?; - } - } - } -} - -/// Public APIs provided by the contracts module. -impl Module { - /// Perform a call to a specified contract. - /// - /// This function is similar to `Self::call`, but doesn't perform any address lookups and better - /// suitable for calling directly from Rust. - /// - /// It returns the exection result and the amount of used weight. - pub fn bare_call( - origin: T::AccountId, - dest: T::AccountId, - value: BalanceOf, - gas_limit: Gas, - input_data: Vec, - ) -> (ExecResult, Gas) { - let mut gas_meter = GasMeter::new(gas_limit); - ( - Self::execute_wasm(origin, &mut gas_meter, |ctx, gas_meter| { - ctx.call(dest, value, gas_meter, input_data) - }), - gas_meter.gas_spent(), - ) - } - - /// Query storage of a specified contract under a specified key. - pub fn get_storage( - address: T::AccountId, - key: [u8; 32], - ) -> sp_std::result::Result>, ContractAccessError> { - let contract_info = >::get(&address) - .ok_or(ContractAccessError::DoesntExist)? - .get_alive() - .ok_or(ContractAccessError::IsTombstone)?; - - let maybe_value = AccountDb::::get_storage( - &DirectAccountDb, - &address, - Some(&contract_info.trie_id), - &key, - ); - Ok(maybe_value) - } - - pub fn rent_projection( - address: T::AccountId, - ) -> sp_std::result::Result, ContractAccessError> { - rent::compute_rent_projection::(&address) - } -} - -impl Module { - fn calc_code_put_costs(code: &Vec) -> Gas { - >::current_schedule() - .put_code_per_byte_cost - .saturating_mul(code.len() as Gas) - } - - fn execute_wasm( - origin: T::AccountId, - gas_meter: &mut GasMeter, - func: impl FnOnce(&mut ExecutionContext, &mut GasMeter) -> ExecResult, - ) -> ExecResult { - let cfg = Config::preload(); - let vm = WasmVm::new(&cfg.schedule); - let loader = WasmLoader::new(&cfg.schedule); - let mut ctx = ExecutionContext::top_level(origin.clone(), &cfg, &vm, &loader); - - let result = func(&mut ctx, gas_meter); - - if result - .as_ref() - .map(|output| output.is_success()) - .unwrap_or(false) - { - // Commit all changes that made it thus far into the persistent storage. - DirectAccountDb.commit(ctx.overlay.into_change_set()); - } - - // Execute deferred actions. - ctx.deferred.into_iter().for_each(|deferred| { - use self::exec::DeferredAction::*; - match deferred { - DepositEvent { topics, event } => >::deposit_event_indexed( - &*topics, - ::Event::from(event).into(), - ), - DispatchRuntimeCall { origin: who, call } => { - let info = call.get_dispatch_info(); - let result = call.dispatch(RawOrigin::Signed(who.clone()).into()); - let post_info = match result { - Ok(post_info) => post_info, - Err(err) => err.post_info, - }; - gas_meter.refund(post_info.calc_unspent(&info)); - Self::deposit_event(RawEvent::Dispatched(who, result.is_ok())); - } - RestoreTo { - donor, - dest, - code_hash, - rent_allowance, - delta, - } => { - let result = Self::restore_to( - donor.clone(), - dest.clone(), - code_hash.clone(), - rent_allowance.clone(), - delta, - ); - Self::deposit_event(RawEvent::Restored( - donor, - dest, - code_hash, - rent_allowance, - result.is_ok(), - )); - } - } - }); - - result - } - - fn restore_to( - _origin: T::AccountId, - _dest: T::AccountId, - _code_hash: CodeHash, - _rent_allowance: BalanceOf, - _delta: Vec, - ) -> DispatchResult { - Err("Restoration currently unsupported for parachains")? - } -} - -decl_event! { - pub enum Event - where - Balance = BalanceOf, - ::AccountId, - ::Hash - { - /// Transfer happened `from` to `to` with given `value` as part of a `call` or `instantiate`. - Transfer(AccountId, AccountId, Balance), - - /// Contract deployed by address at the specified address. - Instantiated(AccountId, AccountId), - - /// Contract has been evicted and is now in tombstone state. - /// - /// # Params - /// - /// - `contract`: `AccountId`: The account ID of the evicted contract. - /// - `tombstone`: `bool`: True if the evicted contract left behind a tombstone. - Evicted(AccountId, bool), - - /// Restoration for a contract has been initiated. - /// - /// # Params - /// - /// - `donor`: `AccountId`: Account ID of the restoring contract - /// - `dest`: `AccountId`: Account ID of the restored contract - /// - `code_hash`: `Hash`: Code hash of the restored contract - /// - `rent_allowance: `Balance`: Rent allowance of the restored contract - /// - `success`: `bool`: True if the restoration was successful - Restored(AccountId, AccountId, Hash, Balance, bool), - - /// Code with the specified hash has been stored. - CodeStored(Hash), - - /// Triggered when the current schedule is updated. - ScheduleUpdated(u32), - - /// A call was dispatched from the given account. The bool signals whether it was - /// successful execution or not. - Dispatched(AccountId, bool), - - /// An event deposited upon execution of a contract from the account. - ContractExecution(AccountId, Vec), - } -} - -decl_storage! { - trait Store for Module as Contracts { - /// Current cost schedule for contracts. - CurrentSchedule get(fn current_schedule) config(): Schedule = Schedule::default(); - /// A mapping from an original code hash to the original code, untouched by instrumentation. - pub PristineCode: map hasher(identity) CodeHash => Option>; - /// A mapping between an original code hash and instrumented wasm code, ready for execution. - pub CodeStorage: map hasher(identity) CodeHash => Option; - /// The subtrie counter. - pub AccountCounter: u64 = 0; - /// The code associated with a given account. - /// - /// TWOX-NOTE: SAFE since `AccountId` is a secure hash. - pub ContractInfoOf: map hasher(twox_64_concat) T::AccountId => Option>; - } -} - -/// In-memory cache of configuration values. -/// -/// We assume that these values can't be changed in the -/// course of transaction execution. -pub struct Config { - pub schedule: Schedule, - pub existential_deposit: BalanceOf, - pub tombstone_deposit: BalanceOf, - pub max_depth: u32, - pub max_value_size: u32, -} - -impl Config { - fn preload() -> Config { - Config { - schedule: >::current_schedule(), - existential_deposit: T::Currency::minimum_balance(), - tombstone_deposit: T::TombstoneDeposit::get(), - max_depth: T::MaxDepth::get(), - max_value_size: T::MaxValueSize::get(), - } - } -} - -/// Definition of the cost schedule and other parameterizations for wasm vm. -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug)] -pub struct Schedule { - /// Version of the schedule. - pub version: u32, - - /// Cost of putting a byte of code into storage. - pub put_code_per_byte_cost: Gas, - - /// Gas cost of a growing memory by single page. - pub grow_mem_cost: Gas, - - /// Gas cost of a regular operation. - pub regular_op_cost: Gas, - - /// Gas cost per one byte returned. - pub return_data_per_byte_cost: Gas, - - /// Gas cost to deposit an event; the per-byte portion. - pub event_data_per_byte_cost: Gas, - - /// Gas cost to deposit an event; the cost per topic. - pub event_per_topic_cost: Gas, - - /// Gas cost to deposit an event; the base. - pub event_base_cost: Gas, - - /// Base gas cost to call into a contract. - pub call_base_cost: Gas, - - /// Base gas cost to instantiate a contract. - pub instantiate_base_cost: Gas, - - /// Base gas cost to dispatch a runtime call. - pub dispatch_base_cost: Gas, - - /// Gas cost per one byte read from the sandbox memory. - pub sandbox_data_read_cost: Gas, - - /// Gas cost per one byte written to the sandbox memory. - pub sandbox_data_write_cost: Gas, - - /// Cost for a simple balance transfer. - pub transfer_cost: Gas, - - /// Cost for instantiating a new contract. - pub instantiate_cost: Gas, - - /// The maximum number of topics supported by an event. - pub max_event_topics: u32, - - /// Maximum allowed stack height. - /// - /// See https://wiki.parity.io/WebAssembly-StackHeight to find out - /// how the stack frame cost is calculated. - pub max_stack_height: u32, - - /// Maximum number of memory pages allowed for a contract. - pub max_memory_pages: u32, - - /// Maximum allowed size of a declared table. - pub max_table_size: u32, - - /// Whether the `ext_println` function is allowed to be used contracts. - /// MUST only be enabled for `dev` chains, NOT for production chains - pub enable_println: bool, - - /// The maximum length of a subject used for PRNG generation. - pub max_subject_len: u32, -} - -// 500 (2 instructions per nano second on 2GHZ) * 1000x slowdown through wasmi -// This is a wild guess and should be viewed as a rough estimation. -// Proper benchmarks are needed before this value and its derivatives can be used in production. -const WASM_INSTRUCTION_COST: Gas = 500_000; - -impl Default for Schedule { - fn default() -> Schedule { - Schedule { - version: 0, - put_code_per_byte_cost: WASM_INSTRUCTION_COST, - grow_mem_cost: WASM_INSTRUCTION_COST, - regular_op_cost: WASM_INSTRUCTION_COST, - return_data_per_byte_cost: WASM_INSTRUCTION_COST, - event_data_per_byte_cost: WASM_INSTRUCTION_COST, - event_per_topic_cost: WASM_INSTRUCTION_COST, - event_base_cost: WASM_INSTRUCTION_COST, - call_base_cost: 135 * WASM_INSTRUCTION_COST, - dispatch_base_cost: 135 * WASM_INSTRUCTION_COST, - instantiate_base_cost: 175 * WASM_INSTRUCTION_COST, - sandbox_data_read_cost: WASM_INSTRUCTION_COST, - sandbox_data_write_cost: WASM_INSTRUCTION_COST, - transfer_cost: 100 * WASM_INSTRUCTION_COST, - instantiate_cost: 200 * WASM_INSTRUCTION_COST, - max_event_topics: 4, - max_stack_height: 64 * 1024, - max_memory_pages: 16, - max_table_size: 16 * 1024, - enable_println: false, - max_subject_len: 32, - } - } -} diff --git a/rococo-parachains/pallets/contracts/src/rent.rs b/rococo-parachains/pallets/contracts/src/rent.rs deleted file mode 100644 index 253ccd568f..0000000000 --- a/rococo-parachains/pallets/contracts/src/rent.rs +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! A module responsible for computing the right amount of weight and charging it. - -use crate::{ - AliveContractInfo, BalanceOf, ContractInfo, ContractInfoOf, Module, RawEvent, - TombstoneContractInfo, Trait, -}; -use cumulus_pallet_contracts_primitives::{ - ContractAccessError, RentProjection, RentProjectionResult, -}; -use frame_support::{ - storage::unhashed as storage, - traits::{Currency, ExistenceRequirement, Get, OnUnbalanced, WithdrawReason}, - StorageMap, -}; -use sp_runtime::traits::{Bounded, CheckedDiv, CheckedMul, SaturatedConversion, Saturating, Zero}; - -/// The amount to charge. -/// -/// This amount respects the contract's rent allowance and the subsistence deposit. -/// Because of that, charging the amount cannot remove the contract. -struct OutstandingAmount { - amount: BalanceOf, -} - -impl OutstandingAmount { - /// Create the new outstanding amount. - /// - /// The amount should be always withdrawable and it should not kill the account. - fn new(amount: BalanceOf) -> Self { - Self { amount } - } - - /// Returns the amount this instance wraps. - fn peek(&self) -> BalanceOf { - self.amount - } - - /// Withdraws the outstanding amount from the given account. - fn withdraw(self, account: &T::AccountId) { - if let Ok(imbalance) = T::Currency::withdraw( - account, - self.amount, - WithdrawReason::Fee.into(), - ExistenceRequirement::KeepAlive, - ) { - // This should never fail. However, let's err on the safe side. - T::RentPayment::on_unbalanced(imbalance); - } - } -} - -enum Verdict { - /// The contract is exempted from paying rent. - /// - /// For example, it already paid its rent in the current block, or it has enough deposit for not - /// paying rent at all. - Exempt, - /// Funds dropped below the subsistence deposit. - /// - /// Remove the contract along with it's storage. - Kill, - /// The contract cannot afford payment within its rent budget so it gets evicted. However, - /// because its balance is greater than the subsistence threshold it leaves a tombstone. - Evict { - amount: Option>, - }, - /// Everything is OK, we just only take some charge. - Charge { amount: OutstandingAmount }, -} - -/// Returns a fee charged per block from the contract. -/// -/// This function accounts for the storage rent deposit. I.e. if the contract possesses enough funds -/// then the fee can drop to zero. -fn compute_fee_per_block( - balance: &BalanceOf, - contract: &AliveContractInfo, -) -> BalanceOf { - let free_storage = balance - .checked_div(&T::RentDepositOffset::get()) - .unwrap_or_else(Zero::zero); - - // For now, we treat every empty KV pair as if it was one byte long. - let empty_pairs_equivalent = contract.empty_pair_count; - - let effective_storage_size = >::from( - contract.storage_size + T::StorageSizeOffset::get() + empty_pairs_equivalent, - ) - .saturating_sub(free_storage); - - effective_storage_size - .checked_mul(&T::RentByteFee::get()) - .unwrap_or(>::max_value()) -} - -/// Subsistence threshold is the extension of the minimum balance (aka existential deposit) by the -/// tombstone deposit, required for leaving a tombstone. -/// -/// Rent mechanism cannot make the balance lower than subsistence threshold. -fn subsistence_threshold() -> BalanceOf { - T::Currency::minimum_balance() + T::TombstoneDeposit::get() -} - -/// Returns amount of funds available to consume by rent mechanism. -/// -/// Rent mechanism cannot consume more than `rent_allowance` set by the contract and it cannot make -/// the balance lower than [`subsistence_threshold`]. -/// -/// In case the balance is below the subsistence threshold, this function returns `None`. -fn rent_budget( - balance: &BalanceOf, - contract: &AliveContractInfo, -) -> Option> { - let subsistence_threshold = subsistence_threshold::(); - if *balance < subsistence_threshold { - return None; - } - - let rent_allowed_to_charge = *balance - subsistence_threshold; - Some(>::min( - contract.rent_allowance, - rent_allowed_to_charge, - )) -} - -/// Consider the case for rent payment of the given account and returns a `Verdict`. -/// -/// Use `handicap` in case you want to change the reference block number. (To get more details see -/// `snitch_contract_should_be_evicted` ). -fn consider_case( - account: &T::AccountId, - current_block_number: T::BlockNumber, - handicap: T::BlockNumber, - contract: &AliveContractInfo, -) -> Verdict { - // How much block has passed since the last deduction for the contract. - let blocks_passed = { - // Calculate an effective block number, i.e. after adjusting for handicap. - let effective_block_number = current_block_number.saturating_sub(handicap); - effective_block_number.saturating_sub(contract.deduct_block) - }; - if blocks_passed.is_zero() { - // Rent has already been paid - return Verdict::Exempt; - } - - let balance = T::Currency::free_balance(account); - - // An amount of funds to charge per block for storage taken up by the contract. - let fee_per_block = compute_fee_per_block::(&balance, contract); - if fee_per_block.is_zero() { - // The rent deposit offset reduced the fee to 0. This means that the contract - // gets the rent for free. - return Verdict::Exempt; - } - - let rent_budget = match rent_budget::(&balance, contract) { - Some(rent_budget) => rent_budget, - None => { - // The contract's balance is already below subsistence threshold. That indicates that - // the contract cannot afford to leave a tombstone. - // - // So cleanly wipe the contract. - return Verdict::Kill; - } - }; - - let dues = fee_per_block - .checked_mul(&blocks_passed.saturated_into::().into()) - .unwrap_or(>::max_value()); - let insufficient_rent = rent_budget < dues; - - // If the rent payment cannot be withdrawn due to locks on the account balance, then evict the - // account. - // - // NOTE: This seems problematic because it provides a way to tombstone an account while - // avoiding the last rent payment. In effect, someone could retroactively set rent_allowance - // for their contract to 0. - let dues_limited = dues.min(rent_budget); - let can_withdraw_rent = T::Currency::ensure_can_withdraw( - account, - dues_limited, - WithdrawReason::Fee.into(), - balance.saturating_sub(dues_limited), - ) - .is_ok(); - - if insufficient_rent || !can_withdraw_rent { - // The contract cannot afford the rent payment and has a balance above the subsistence - // threshold, so it leaves a tombstone. - let amount = if can_withdraw_rent { - Some(OutstandingAmount::new(dues_limited)) - } else { - None - }; - return Verdict::Evict { amount }; - } - - return Verdict::Charge { - // We choose to use `dues_limited` here instead of `dues` just to err on the safer side. - amount: OutstandingAmount::new(dues_limited), - }; -} - -/// Enacts the given verdict and returns the updated `ContractInfo`. -/// -/// `alive_contract_info` should be from the same address as `account`. -fn enact_verdict( - account: &T::AccountId, - alive_contract_info: AliveContractInfo, - current_block_number: T::BlockNumber, - verdict: Verdict, -) -> Option> { - match verdict { - Verdict::Exempt => return Some(ContractInfo::Alive(alive_contract_info)), - Verdict::Kill => { - >::remove(account); - storage::kill_prefix(&alive_contract_info.trie_id); - >::deposit_event(RawEvent::Evicted(account.clone(), false)); - None - } - Verdict::Evict { amount } => { - if let Some(amount) = amount { - amount.withdraw(account); - } - - // Use a dummy storage root because restoration is currentlyy unsupported - // for parachains anyways. - let tombstone = - >::new(&[0u8; 32], alive_contract_info.code_hash); - let tombstone_info = ContractInfo::Tombstone(tombstone); - >::insert(account, &tombstone_info); - - storage::kill_prefix(&alive_contract_info.trie_id); - - >::deposit_event(RawEvent::Evicted(account.clone(), true)); - Some(tombstone_info) - } - Verdict::Charge { amount } => { - let contract_info = ContractInfo::Alive(AliveContractInfo:: { - rent_allowance: alive_contract_info.rent_allowance - amount.peek(), - deduct_block: current_block_number, - ..alive_contract_info - }); - >::insert(account, &contract_info); - - amount.withdraw(account); - Some(contract_info) - } - } -} - -/// Make account paying the rent for the current block number -/// -/// NOTE this function performs eviction eagerly. All changes are read and written directly to -/// storage. -pub fn collect_rent(account: &T::AccountId) -> Option> { - let contract_info = >::get(account); - let alive_contract_info = match contract_info { - None | Some(ContractInfo::Tombstone(_)) => return contract_info, - Some(ContractInfo::Alive(contract)) => contract, - }; - - let current_block_number = >::block_number(); - let verdict = consider_case::( - account, - current_block_number, - Zero::zero(), - &alive_contract_info, - ); - enact_verdict(account, alive_contract_info, current_block_number, verdict) -} - -/// Process a report that a contract under the given address should be evicted. -/// -/// Enact the eviction right away if the contract should be evicted and return true. -/// Otherwise, **do nothing** and return false. -/// -/// The `handicap` parameter gives a way to check the rent to a moment in the past instead -/// of current block. E.g. if the contract is going to be evicted at the current block, -/// `handicap = 1` can defer the eviction for 1 block. This is useful to handicap certain snitchers -/// relative to others. -/// -/// NOTE this function performs eviction eagerly. All changes are read and written directly to -/// storage. -pub fn snitch_contract_should_be_evicted( - account: &T::AccountId, - handicap: T::BlockNumber, -) -> bool { - let contract_info = >::get(account); - let alive_contract_info = match contract_info { - None | Some(ContractInfo::Tombstone(_)) => return false, - Some(ContractInfo::Alive(contract)) => contract, - }; - let current_block_number = >::block_number(); - let verdict = consider_case::( - account, - current_block_number, - handicap, - &alive_contract_info, - ); - - // Enact the verdict only if the contract gets removed. - match verdict { - Verdict::Kill | Verdict::Evict { .. } => { - enact_verdict(account, alive_contract_info, current_block_number, verdict); - true - } - _ => false, - } -} - -/// Returns the projected time a given contract will be able to sustain paying its rent. The -/// returned projection is relevant for the current block, i.e. it is as if the contract was -/// accessed at the beginning of the current block. Returns `None` in case if the contract was -/// evicted before or as a result of the rent collection. -/// -/// The returned value is only an estimation. It doesn't take into account any top ups, changing the -/// rent allowance, or any problems coming from withdrawing the dues. -/// -/// NOTE that this is not a side-effect free function! It will actually collect rent and then -/// compute the projection. This function is only used for implementation of an RPC method through -/// `RuntimeApi` meaning that the changes will be discarded anyway. -pub fn compute_rent_projection( - account: &T::AccountId, -) -> RentProjectionResult { - let contract_info = >::get(account); - let alive_contract_info = match contract_info { - None | Some(ContractInfo::Tombstone(_)) => return Err(ContractAccessError::IsTombstone), - Some(ContractInfo::Alive(contract)) => contract, - }; - let current_block_number = >::block_number(); - let verdict = consider_case::( - account, - current_block_number, - Zero::zero(), - &alive_contract_info, - ); - let new_contract_info = - enact_verdict(account, alive_contract_info, current_block_number, verdict); - - // Check what happened after enaction of the verdict. - let alive_contract_info = match new_contract_info { - None | Some(ContractInfo::Tombstone(_)) => return Err(ContractAccessError::IsTombstone), - Some(ContractInfo::Alive(contract)) => contract, - }; - - // Compute how much would the fee per block be with the *updated* balance. - let balance = T::Currency::free_balance(account); - let fee_per_block = compute_fee_per_block::(&balance, &alive_contract_info); - if fee_per_block.is_zero() { - return Ok(RentProjection::NoEviction); - } - - // Then compute how much the contract will sustain under these circumstances. - let rent_budget = rent_budget::(&balance, &alive_contract_info).expect( - "the contract exists and in the alive state; - the updated balance must be greater than subsistence deposit; - this function doesn't return `None`; - qed - ", - ); - let blocks_left = match rent_budget.checked_div(&fee_per_block) { - Some(blocks_left) => blocks_left, - None => { - // `fee_per_block` is not zero here, so `checked_div` can return `None` if - // there is an overflow. This cannot happen with integers though. Return - // `NoEviction` here just in case. - return Ok(RentProjection::NoEviction); - } - }; - - let blocks_left = blocks_left.saturated_into::().into(); - Ok(RentProjection::EvictionAt( - current_block_number + blocks_left, - )) -} diff --git a/rococo-parachains/pallets/contracts/src/tests.rs b/rococo-parachains/pallets/contracts/src/tests.rs deleted file mode 100644 index 954e05a003..0000000000 --- a/rococo-parachains/pallets/contracts/src/tests.rs +++ /dev/null @@ -1,1997 +0,0 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -use crate::{ - account_db::{AccountDb, DirectAccountDb, OverlayAccountDb}, - gas::Gas, - BalanceOf, ContractAddressFor, ContractInfo, ContractInfoOf, GenesisConfig, Module, - RawAliveContractInfo, RawEvent, Schedule, Trait, TrieId, TrieIdGenerator, -}; -use assert_matches::assert_matches; -use codec::Encode; -use frame_support::{ - assert_err_ignore_postinfo, assert_ok, impl_outer_dispatch, impl_outer_event, - impl_outer_origin, parameter_types, - traits::{Currency, Get}, - weights::{PostDispatchInfo, Weight}, - StorageMap, StorageValue, -}; -use frame_system::{self as system, EventRecord, Phase}; -use hex_literal::*; -use sp_runtime::{ - testing::{Header, H256}, - traits::{BlakeTwo256, Convert, Hash, IdentityLookup}, - Perbill, -}; -use std::cell::RefCell; - -mod contracts { - // Re-export contents of the root. This basically - // needs to give a name for the current crate. - // This hack is required for `impl_outer_event!`. - pub use super::super::*; - pub use frame_support::impl_outer_event; -} - -use pallet_balances as balances; - -impl_outer_event! { - pub enum MetaEvent for Test { - system, - balances, - contracts, - } -} -impl_outer_origin! { - pub enum Origin for Test where system = frame_system { } -} -impl_outer_dispatch! { - pub enum Call for Test where origin: Origin { - balances::Balances, - contracts::Contracts, - } -} - -thread_local! { - static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); -} - -pub struct ExistentialDeposit; -impl Get for ExistentialDeposit { - fn get() -> u64 { - EXISTENTIAL_DEPOSIT.with(|v| *v.borrow()) - } -} - -#[derive(Clone, Eq, PartialEq, Debug)] -pub struct Test; -parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); -} -impl frame_system::Trait for Test { - type BaseCallFilter = (); - type Origin = Origin; - type Index = u64; - type BlockNumber = u64; - type Hash = H256; - type Call = Call; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Header = Header; - type Event = MetaEvent; - type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; - type Version = (); - type ModuleToIndex = (); - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); -} -impl pallet_balances::Trait for Test { - type Balance = u64; - type Event = MetaEvent; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = (); -} -parameter_types! { - pub const MinimumPeriod: u64 = 1; -} -impl pallet_timestamp::Trait for Test { - type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = MinimumPeriod; - type WeightInfo = (); -} -parameter_types! { - pub const SignedClaimHandicap: u64 = 2; - pub const TombstoneDeposit: u64 = 16; - pub const StorageSizeOffset: u32 = 8; - pub const RentByteFee: u64 = 4; - pub const RentDepositOffset: u64 = 10_000; - pub const SurchargeReward: u64 = 150; - pub const MaxDepth: u32 = 100; - pub const MaxValueSize: u32 = 16_384; -} - -parameter_types! { - pub const TransactionByteFee: u64 = 0; -} - -impl Convert> for Test { - fn convert(w: Weight) -> BalanceOf { - w - } -} - -impl Trait for Test { - type Time = Timestamp; - type Randomness = Randomness; - type Currency = Balances; - type Call = Call; - type DetermineContractAddress = DummyContractAddressFor; - type Event = MetaEvent; - type TrieIdGenerator = DummyTrieIdGenerator; - type RentPayment = (); - type SignedClaimHandicap = SignedClaimHandicap; - type TombstoneDeposit = TombstoneDeposit; - type StorageSizeOffset = StorageSizeOffset; - type RentByteFee = RentByteFee; - type RentDepositOffset = RentDepositOffset; - type SurchargeReward = SurchargeReward; - type MaxDepth = MaxDepth; - type MaxValueSize = MaxValueSize; - type WeightPrice = Self; -} - -type Balances = pallet_balances::Module; -type Timestamp = pallet_timestamp::Module; -type Contracts = Module; -type System = frame_system::Module; -type Randomness = pallet_randomness_collective_flip::Module; - -pub struct DummyContractAddressFor; -impl ContractAddressFor for DummyContractAddressFor { - fn contract_address_for(_code_hash: &H256, _data: &[u8], origin: &u64) -> u64 { - *origin + 1 - } -} - -pub struct DummyTrieIdGenerator; -impl TrieIdGenerator for DummyTrieIdGenerator { - fn trie_id(account_id: &u64) -> TrieId { - let new_seed = super::AccountCounter::mutate(|v| { - *v = v.wrapping_add(1); - *v - }); - - let mut res = vec![]; - res.extend_from_slice(&new_seed.to_le_bytes()); - res.extend_from_slice(&account_id.to_le_bytes()); - res - } -} - -const ALICE: u64 = 1; -const BOB: u64 = 2; -const CHARLIE: u64 = 3; -const DJANGO: u64 = 4; - -const GAS_LIMIT: Gas = 10_000_000_000; - -pub struct ExtBuilder { - existential_deposit: u64, -} -impl Default for ExtBuilder { - fn default() -> Self { - Self { - existential_deposit: 1, - } - } -} -impl ExtBuilder { - pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { - self.existential_deposit = existential_deposit; - self - } - pub fn set_associated_consts(&self) { - EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); - } - pub fn build(self) -> sp_io::TestExternalities { - self.set_associated_consts(); - let mut t = frame_system::GenesisConfig::default() - .build_storage::() - .unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![] } - .assimilate_storage(&mut t) - .unwrap(); - GenesisConfig { - current_schedule: Schedule { - enable_println: true, - ..Default::default() - }, - } - .assimilate_storage(&mut t) - .unwrap(); - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext - } -} - -/// Load a given wasm module represented by a .wat file and returns a wasm binary contents along -/// with it's hash. -/// -/// The fixture files are located under the `fixtures/` directory. -fn compile_module( - fixture_name: &str, -) -> Result<(Vec, ::Output), wabt::Error> -where - T: frame_system::Trait, -{ - use std::fs; - - let fixture_path = ["fixtures/", fixture_name, ".wat"].concat(); - let module_wat_source = fs::read_to_string(&fixture_path) - .expect(&format!("Unable to find {} fixture", fixture_name)); - let wasm_binary = wabt::wat2wasm(module_wat_source)?; - let code_hash = T::Hashing::hash(&wasm_binary); - Ok((wasm_binary, code_hash)) -} - -// Perform a simple transfer to a non-existent account. -// Then we check that only the base costs are returned as actual costs. -#[test] -fn returns_base_call_cost() { - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 100_000_000); - - assert_eq!( - Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, Vec::new()), - Ok(PostDispatchInfo { - actual_weight: Some(67500000), - pays_fee: Default::default(), - }) - ); - }); -} - -#[test] -fn account_removal_does_not_remove_storage() { - ExtBuilder::default() - .existential_deposit(100) - .build() - .execute_with(|| { - let trie_id1 = ::TrieIdGenerator::trie_id(&1); - let trie_id2 = ::TrieIdGenerator::trie_id(&2); - let key1 = &[1; 32]; - let key2 = &[2; 32]; - - // Set up two accounts with free balance above the existential threshold. - { - let _ = Balances::deposit_creating(&1, 110); - ContractInfoOf::::insert( - 1, - &ContractInfo::Alive(RawAliveContractInfo { - trie_id: trie_id1.clone(), - storage_size: 0, - empty_pair_count: 0, - total_pair_count: 0, - deduct_block: System::block_number(), - code_hash: H256::repeat_byte(1), - rent_allowance: 40, - last_write: None, - }), - ); - - let mut overlay = OverlayAccountDb::::new(&DirectAccountDb); - overlay.set_storage(&1, key1.clone(), Some(b"1".to_vec())); - overlay.set_storage(&1, key2.clone(), Some(b"2".to_vec())); - DirectAccountDb.commit(overlay.into_change_set()); - - let _ = Balances::deposit_creating(&2, 110); - ContractInfoOf::::insert( - 2, - &ContractInfo::Alive(RawAliveContractInfo { - trie_id: trie_id2.clone(), - storage_size: 0, - empty_pair_count: 0, - total_pair_count: 0, - deduct_block: System::block_number(), - code_hash: H256::repeat_byte(2), - rent_allowance: 40, - last_write: None, - }), - ); - - let mut overlay = OverlayAccountDb::::new(&DirectAccountDb); - overlay.set_storage(&2, key1.clone(), Some(b"3".to_vec())); - overlay.set_storage(&2, key2.clone(), Some(b"4".to_vec())); - DirectAccountDb.commit(overlay.into_change_set()); - } - - // Transfer funds from account 1 of such amount that after this transfer - // the balance of account 1 will be below the existential threshold. - // - // This does not remove the contract storage as we are not notified about a - // account removal. This cannot happen in reality because a contract can only - // remove itself by `ext_terminate`. There is no external event that can remove - // the account appart from that. - assert_ok!(Balances::transfer(Origin::signed(1), 2, 20)); - - // Verify that no entries are removed. - { - assert_eq!( - >::get_storage(&DirectAccountDb, &1, Some(&trie_id1), key1), - Some(b"1".to_vec()) - ); - assert_eq!( - >::get_storage(&DirectAccountDb, &1, Some(&trie_id1), key2), - Some(b"2".to_vec()) - ); - - assert_eq!( - >::get_storage(&DirectAccountDb, &2, Some(&trie_id2), key1), - Some(b"3".to_vec()) - ); - assert_eq!( - >::get_storage(&DirectAccountDb, &2, Some(&trie_id2), key2), - Some(b"4".to_vec()) - ); - } - }); -} - -#[test] -fn instantiate_and_call_and_deposit_event() { - let (wasm, code_hash) = compile_module::("return_from_start_fn").unwrap(); - - ExtBuilder::default() - .existential_deposit(100) - .build() - .execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - - // Check at the end to get hash on error easily - let creation = Contracts::instantiate( - Origin::signed(ALICE), - 100, - GAS_LIMIT, - code_hash.into(), - vec![], - ); - - assert_eq!( - System::events(), - vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed( - 1, 1_000_000 - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(BOB)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(BOB, 100)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Transfer(ALICE, BOB, 100)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::ContractExecution( - BOB, - vec![1, 2, 3, 4] - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Instantiated(ALICE, BOB)), - topics: vec![], - } - ] - ); - - assert_ok!(creation); - assert!(ContractInfoOf::::contains_key(BOB)); - }); -} - -#[test] -fn dispatch_call() { - // This test can fail due to the encoding changes. In case it becomes too annoying - // let's rewrite so as we use this module controlled call or we serialize it in runtime. - let encoded = Encode::encode(&Call::Balances(pallet_balances::Call::transfer( - CHARLIE, 50, - ))); - assert_eq!(&encoded[..], &hex!("00000300000000000000C8")[..]); - - let (wasm, code_hash) = compile_module::("dispatch_call").unwrap(); - - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - - // Let's keep this assert even though it's redundant. If you ever need to update the - // wasm source this test will fail and will show you the actual hash. - assert_eq!( - System::events(), - vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed( - 1, 1_000_000 - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - ] - ); - - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100, - GAS_LIMIT, - code_hash.into(), - vec![], - )); - - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, // newly created account - 0, - GAS_LIMIT, - vec![], - )); - - assert_eq!( - System::events(), - vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed( - 1, 1_000_000 - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(BOB)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(BOB, 100)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Transfer(ALICE, BOB, 100)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Instantiated(ALICE, BOB)), - topics: vec![], - }, - // Dispatching the call. - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(CHARLIE)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(CHARLIE, 50)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Transfer( - BOB, CHARLIE, 50 - )), - topics: vec![], - }, - // Event emitted as a result of dispatch. - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Dispatched(BOB, true)), - topics: vec![], - } - ] - ); - }); -} - -#[test] -fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { - // This test can fail due to the encoding changes. In case it becomes too annoying - // let's rewrite so as we use this module controlled call or we serialize it in runtime. - let encoded = Encode::encode(&Call::Balances(pallet_balances::Call::transfer( - CHARLIE, 50, - ))); - assert_eq!(&encoded[..], &hex!("00000300000000000000C8")[..]); - - let (wasm, code_hash) = compile_module::("dispatch_call_then_trap").unwrap(); - - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - - // Let's keep this assert even though it's redundant. If you ever need to update the - // wasm source this test will fail and will show you the actual hash. - assert_eq!( - System::events(), - vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed( - 1, 1_000_000 - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - ] - ); - - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100, - GAS_LIMIT, - code_hash.into(), - vec![], - )); - - // Call the newly instantiated contract. The contract is expected to dispatch a call - // and then trap. - assert_err_ignore_postinfo!( - Contracts::call( - Origin::signed(ALICE), - BOB, // newly created account - 0, - GAS_LIMIT, - vec![], - ), - "contract trapped during execution" - ); - assert_eq!( - System::events(), - vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed( - 1, 1_000_000 - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(BOB)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(BOB, 100)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Transfer(ALICE, BOB, 100)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Instantiated(ALICE, BOB)), - topics: vec![], - }, - // ABSENCE of events which would be caused by dispatched Balances::transfer call - ] - ); - }); -} - -#[test] -fn run_out_of_gas() { - let (wasm, code_hash) = compile_module::("run_out_of_gas").unwrap(); - - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100, - GAS_LIMIT, - code_hash.into(), - vec![], - )); - - // Call the contract with a fixed gas limit. It must run out of gas because it just - // loops forever. - assert_err_ignore_postinfo!( - Contracts::call( - Origin::signed(ALICE), - BOB, // newly created account - 0, - 67_500_000, - vec![], - ), - "ran out of gas during contract execution" - ); - }); -} - -/// Input data for each call in set_rent code -mod call { - pub fn set_storage_4_byte() -> Vec { - vec![] - } - pub fn remove_storage_4_byte() -> Vec { - vec![0] - } - pub fn transfer() -> Vec { - vec![0, 0] - } - pub fn null() -> Vec { - vec![0, 0, 0] - } -} - -/// Test correspondence of set_rent code and its hash. -/// Also test that encoded extrinsic in code correspond to the correct transfer -#[test] -fn test_set_rent_code_and_hash() { - // This test can fail due to the encoding changes. In case it becomes too annoying - // let's rewrite so as we use this module controlled call or we serialize it in runtime. - let encoded = Encode::encode(&Call::Balances(pallet_balances::Call::transfer( - CHARLIE, 50, - ))); - assert_eq!(&encoded[..], &hex!("00000300000000000000C8")[..]); - - let (wasm, code_hash) = compile_module::("set_rent").unwrap(); - - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - - // If you ever need to update the wasm source this test will fail - // and will show you the actual hash. - assert_eq!( - System::events(), - vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed( - 1, 1_000_000 - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - ] - ); - }); -} - -#[test] -fn storage_size() { - let (wasm, code_hash) = compile_module::("set_rent").unwrap(); - - // Storage size - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, - code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - let bob_contract = ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap(); - assert_eq!(bob_contract.storage_size, 4); - assert_eq!(bob_contract.total_pair_count, 1,); - assert_eq!(bob_contract.empty_pair_count, 0,); - - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - call::set_storage_4_byte() - )); - let bob_contract = ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap(); - assert_eq!(bob_contract.storage_size, 4 + 4); - assert_eq!(bob_contract.total_pair_count, 2,); - assert_eq!(bob_contract.empty_pair_count, 0,); - - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - call::remove_storage_4_byte() - )); - let bob_contract = ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap(); - assert_eq!(bob_contract.storage_size, 4); - assert_eq!(bob_contract.total_pair_count, 1,); - assert_eq!(bob_contract.empty_pair_count, 0,); - }); -} - -#[test] -fn empty_kv_pairs() { - let (wasm, code_hash) = compile_module::("set_empty_storage").unwrap(); - - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, - code_hash.into(), - vec![], - )); - let bob_contract = ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap(); - - assert_eq!(bob_contract.storage_size, 0,); - assert_eq!(bob_contract.total_pair_count, 1,); - assert_eq!(bob_contract.empty_pair_count, 1,); - }); -} - -fn initialize_block(number: u64) { - System::initialize( - &number, - &[0u8; 32].into(), - &[0u8; 32].into(), - &Default::default(), - Default::default(), - ); -} - -#[test] -fn deduct_blocks() { - let (wasm, code_hash) = compile_module::("set_rent").unwrap(); - - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, - code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - // Check creation - let bob_contract = ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap(); - assert_eq!(bob_contract.rent_allowance, 1_000); - - // Advance 4 blocks - initialize_block(5); - - // Trigger rent through call - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - call::null() - )); - - // Check result - let rent = (8 + 4 - 3) // storage size = size_offset + deploy_set_storage - deposit_offset - * 4 // rent byte price - * 4; // blocks to rent - let bob_contract = ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap(); - assert_eq!(bob_contract.rent_allowance, 1_000 - rent); - assert_eq!(bob_contract.deduct_block, 5); - assert_eq!(Balances::free_balance(BOB), 30_000 - rent); - - // Advance 7 blocks more - initialize_block(12); - - // Trigger rent through call - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - call::null() - )); - - // Check result - let rent_2 = (8 + 4 - 2) // storage size = size_offset + deploy_set_storage - deposit_offset - * 4 // rent byte price - * 7; // blocks to rent - let bob_contract = ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap(); - assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); - assert_eq!(bob_contract.deduct_block, 12); - assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); - - // Second call on same block should have no effect on rent - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - call::null() - )); - - let bob_contract = ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap(); - assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); - assert_eq!(bob_contract.deduct_block, 12); - assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); - }); -} - -#[test] -fn call_contract_removals() { - removals(|| { - // Call on already-removed account might fail, and this is fine. - let _ = Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null()); - true - }); -} - -#[test] -fn inherent_claim_surcharge_contract_removals() { - removals(|| Contracts::claim_surcharge(Origin::none(), BOB, Some(ALICE)).is_ok()); -} - -#[test] -fn signed_claim_surcharge_contract_removals() { - removals(|| Contracts::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok()); -} - -#[test] -fn claim_surcharge_malus() { - // Test surcharge malus for inherent - claim_surcharge( - 4, - || Contracts::claim_surcharge(Origin::none(), BOB, Some(ALICE)).is_ok(), - true, - ); - claim_surcharge( - 3, - || Contracts::claim_surcharge(Origin::none(), BOB, Some(ALICE)).is_ok(), - true, - ); - claim_surcharge( - 2, - || Contracts::claim_surcharge(Origin::none(), BOB, Some(ALICE)).is_ok(), - true, - ); - claim_surcharge( - 1, - || Contracts::claim_surcharge(Origin::none(), BOB, Some(ALICE)).is_ok(), - false, - ); - - // Test surcharge malus for signed - claim_surcharge( - 4, - || Contracts::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), - true, - ); - claim_surcharge( - 3, - || Contracts::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), - false, - ); - claim_surcharge( - 2, - || Contracts::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), - false, - ); - claim_surcharge( - 1, - || Contracts::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), - false, - ); -} - -/// Claim surcharge with the given trigger_call at the given blocks. -/// If `removes` is true then assert that the contract is a tombstone. -fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool) { - let (wasm, code_hash) = compile_module::("set_rent").unwrap(); - - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100, - GAS_LIMIT, - code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - // Advance blocks - initialize_block(blocks); - - // Trigger rent through call - assert!(trigger_call()); - - if removes { - assert!(ContractInfoOf::::get(BOB) - .unwrap() - .get_tombstone() - .is_some()); - } else { - assert!(ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .is_some()); - } - }); -} - -/// Test for all kind of removals for the given trigger: -/// * if balance is reached and balance > subsistence threshold -/// * if allowance is exceeded -/// * if balance is reached and balance < subsistence threshold -fn removals(trigger_call: impl Fn() -> bool) { - let (wasm, code_hash) = compile_module::("set_rent").unwrap(); - - // Balance reached and superior to subsistence threshold - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm.clone())); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100, - GAS_LIMIT, - code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - let subsistence_threshold = 50 /*existential_deposit*/ + 16 /*tombstone_deposit*/; - - // Trigger rent must have no effect - assert!(trigger_call()); - assert_eq!( - ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap() - .rent_allowance, - 1_000 - ); - assert_eq!(Balances::free_balance(BOB), 100); - - // Advance blocks - initialize_block(10); - - // Trigger rent through call - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB) - .unwrap() - .get_tombstone() - .is_some()); - assert_eq!(Balances::free_balance(BOB), subsistence_threshold); - - // Advance blocks - initialize_block(20); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB) - .unwrap() - .get_tombstone() - .is_some()); - assert_eq!(Balances::free_balance(BOB), subsistence_threshold); - }); - - // Allowance exceeded - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm.clone())); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 1_000, - GAS_LIMIT, - code_hash.into(), - ::Balance::from(100u32).encode() // rent allowance - )); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert_eq!( - ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap() - .rent_allowance, - 100 - ); - assert_eq!(Balances::free_balance(BOB), 1_000); - - // Advance blocks - initialize_block(10); - - // Trigger rent through call - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB) - .unwrap() - .get_tombstone() - .is_some()); - // Balance should be initial balance - initial rent_allowance - assert_eq!(Balances::free_balance(BOB), 900); - - // Advance blocks - initialize_block(20); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB) - .unwrap() - .get_tombstone() - .is_some()); - assert_eq!(Balances::free_balance(BOB), 900); - }); - - // Balance reached and inferior to subsistence threshold - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm.clone())); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 50 + Balances::minimum_balance(), - GAS_LIMIT, - code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert_eq!( - ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap() - .rent_allowance, - 1_000 - ); - assert_eq!( - Balances::free_balance(BOB), - 50 + Balances::minimum_balance() - ); - - // Transfer funds - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - call::transfer() - )); - assert_eq!( - ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap() - .rent_allowance, - 1_000 - ); - assert_eq!(Balances::free_balance(BOB), Balances::minimum_balance()); - - // Advance blocks - initialize_block(10); - - // Trigger rent through call - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).is_none()); - assert_eq!(Balances::free_balance(BOB), Balances::minimum_balance()); - - // Advance blocks - initialize_block(20); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).is_none()); - assert_eq!(Balances::free_balance(BOB), Balances::minimum_balance()); - }); -} - -#[test] -fn call_removed_contract() { - let (wasm, code_hash) = compile_module::("set_rent").unwrap(); - - // Balance reached and superior to subsistence threshold - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm.clone())); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100, - GAS_LIMIT, - code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - // Calling contract should succeed. - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - call::null() - )); - - // Advance blocks - initialize_block(10); - - // Calling contract should remove contract and fail. - assert_err_ignore_postinfo!( - Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null()), - "contract has been evicted" - ); - // Calling a contract that is about to evict shall emit an event. - assert_eq!( - System::events(), - vec![EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Evicted(BOB, true)), - topics: vec![], - },] - ); - - // Subsequent contract calls should also fail. - assert_err_ignore_postinfo!( - Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null()), - "contract has been evicted" - ); - }) -} - -#[test] -fn default_rent_allowance_on_instantiate() { - let (wasm, code_hash) = compile_module::("check_default_rent_allowance").unwrap(); - - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, - code_hash.into(), - vec![], - )); - - // Check creation - let bob_contract = ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap(); - assert_eq!(bob_contract.rent_allowance, >::max_value()); - - // Advance blocks - initialize_block(5); - - // Trigger rent through call - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - call::null() - )); - - // Check contract is still alive - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive(); - assert!(bob_contract.is_some()) - }); -} - -#[test] -fn restorations_dirty_storage_and_different_storage() { - restoration(true, true); -} - -#[test] -fn restorations_dirty_storage() { - restoration(false, true); -} - -#[test] -fn restoration_different_storage() { - restoration(true, false); -} - -// Restoration unsupported for parachains -#[test] -#[ignore] -fn restoration_success() { - restoration(false, false); -} - -fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: bool) { - let (set_rent_wasm, set_rent_code_hash) = compile_module::("set_rent").unwrap(); - let (restoration_wasm, restoration_code_hash) = compile_module::("restoration").unwrap(); - - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), restoration_wasm)); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), set_rent_wasm)); - - // If you ever need to update the wasm source this test will fail - // and will show you the actual hash. - assert_eq!( - System::events(), - vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed( - 1, 1_000_000 - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::CodeStored( - restoration_code_hash.into() - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::CodeStored( - set_rent_code_hash.into() - )), - topics: vec![], - }, - ] - ); - - // Create an account with address `BOB` with code `CODE_SET_RENT`. - // The input parameter sets the rent allowance to 0. - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, - set_rent_code_hash.into(), - ::Balance::from(0u32).encode() - )); - - // Check if `BOB` was created successfully and that the rent allowance is - // set to 0. - let bob_contract = ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap(); - assert_eq!(bob_contract.rent_allowance, 0); - - if test_different_storage { - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - call::set_storage_4_byte() - )); - } - - // Advance 4 blocks, to the 5th. - initialize_block(5); - - // Preserve `BOB`'s code hash for later introspection. - let bob_code_hash = ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap() - .code_hash; - // Call `BOB`, which makes it pay rent. Since the rent allowance is set to 0 - // we expect that it will get removed leaving tombstone. - assert_err_ignore_postinfo!( - Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null()), - "contract has been evicted" - ); - assert!(ContractInfoOf::::get(BOB) - .unwrap() - .get_tombstone() - .is_some()); - assert_eq!( - System::events(), - vec![EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Evicted(BOB.clone(), true)), - topics: vec![], - },] - ); - - // Create another account with the address `DJANGO` with `CODE_RESTORATION`. - // - // Note that we can't use `ALICE` for creating `DJANGO` so we create yet another - // account `CHARLIE` and create `DJANGO` with it. - let _ = Balances::deposit_creating(&CHARLIE, 1_000_000); - assert_ok!(Contracts::instantiate( - Origin::signed(CHARLIE), - 30_000, - GAS_LIMIT, - restoration_code_hash.into(), - ::Balance::from(0u32).encode() - )); - - // Before performing a call to `DJANGO` save its original trie id. - let django_trie_id = ContractInfoOf::::get(DJANGO) - .unwrap() - .get_alive() - .unwrap() - .trie_id; - - if !test_restore_to_with_dirty_storage { - // Advance 1 block, to the 6th. - initialize_block(6); - } - - // Perform a call to `DJANGO`. This should either perform restoration successfully or - // fail depending on the test parameters. - assert_ok!(Contracts::call( - Origin::signed(ALICE), - DJANGO, - 0, - GAS_LIMIT, - vec![], - )); - - if test_different_storage || test_restore_to_with_dirty_storage { - // Parametrization of the test imply restoration failure. Check that `DJANGO` aka - // restoration contract is still in place and also that `BOB` doesn't exist. - assert!(ContractInfoOf::::get(BOB) - .unwrap() - .get_tombstone() - .is_some()); - let django_contract = ContractInfoOf::::get(DJANGO) - .unwrap() - .get_alive() - .unwrap(); - assert_eq!(django_contract.storage_size, 8); - assert_eq!(django_contract.trie_id, django_trie_id); - assert_eq!(django_contract.deduct_block, System::block_number()); - match (test_different_storage, test_restore_to_with_dirty_storage) { - (true, false) => { - assert_eq!( - System::events(), - vec![EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Restored( - DJANGO, - BOB, - bob_code_hash, - 50, - false - )), - topics: vec![], - },] - ); - } - (_, true) => { - assert_eq!( - System::events(), - vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Evicted(BOB, true)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount( - CHARLIE - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed( - CHARLIE, 1_000_000 - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount( - DJANGO - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed( - DJANGO, 30_000 - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Transfer( - CHARLIE, DJANGO, 30_000 - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Instantiated( - CHARLIE, DJANGO - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Restored( - DJANGO, - BOB, - bob_code_hash, - 50, - false, - )), - topics: vec![], - }, - ] - ); - } - _ => unreachable!(), - } - } else { - // Here we expect that the restoration is succeeded. Check that the restoration - // contract `DJANGO` ceased to exist and that `BOB` returned back. - println!("{:?}", ContractInfoOf::::get(BOB)); - let bob_contract = ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap(); - assert_eq!(bob_contract.rent_allowance, 50); - assert_eq!(bob_contract.storage_size, 4); - assert_eq!(bob_contract.trie_id, django_trie_id); - assert_eq!(bob_contract.deduct_block, System::block_number()); - assert!(ContractInfoOf::::get(DJANGO).is_none()); - assert_eq!( - System::events(), - vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(system::RawEvent::KilledAccount(DJANGO)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Restored( - DJANGO, - BOB, - bob_contract.code_hash, - 50, - true - )), - topics: vec![], - }, - ] - ); - } - }); -} - -#[test] -fn storage_max_value_limit() { - let (wasm, code_hash) = compile_module::("storage_size").unwrap(); - - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, - code_hash.into(), - vec![], - )); - - // Check creation - let bob_contract = ContractInfoOf::::get(BOB) - .unwrap() - .get_alive() - .unwrap(); - assert_eq!(bob_contract.rent_allowance, >::max_value()); - - // Call contract with allowed storage value. - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - Encode::encode(&self::MaxValueSize::get()), - )); - - // Call contract with too large a storage value. - assert_err_ignore_postinfo!( - Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - Encode::encode(&(self::MaxValueSize::get() + 1)), - ), - "contract trapped during execution" - ); - }); -} - -#[test] -fn deploy_and_call_other_contract() { - let (callee_wasm, callee_code_hash) = compile_module::("return_with_data").unwrap(); - let (caller_wasm, caller_code_hash) = compile_module::("caller_contract").unwrap(); - - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), callee_wasm)); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), caller_wasm)); - - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100_000, - GAS_LIMIT, - caller_code_hash.into(), - vec![], - )); - - // Call BOB contract, which attempts to instantiate and call the callee contract and - // makes various assertions on the results from those calls. - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - callee_code_hash.as_ref().to_vec(), - )); - }); -} - -#[test] -fn cannot_self_destruct_through_draning() { - let (wasm, code_hash) = compile_module::("drain").unwrap(); - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - - // Instantiate the BOB contract. - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100_000, - GAS_LIMIT, - code_hash.into(), - vec![], - )); - - // Check that the BOB contract has been instantiated. - assert_matches!( - ContractInfoOf::::get(BOB), - Some(ContractInfo::Alive(_)) - ); - - // Call BOB with no input data, forcing it to run until out-of-balance - // and eventually trapping because below existential deposit. - assert_err_ignore_postinfo!( - Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, vec![],), - "contract trapped during execution" - ); - }); -} - -#[test] -fn cannot_self_destruct_while_live() { - let (wasm, code_hash) = compile_module::("self_destruct").unwrap(); - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - - // Instantiate the BOB contract. - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100_000, - GAS_LIMIT, - code_hash.into(), - vec![], - )); - - // Check that the BOB contract has been instantiated. - assert_matches!( - ContractInfoOf::::get(BOB), - Some(ContractInfo::Alive(_)) - ); - - // Call BOB with input data, forcing it make a recursive call to itself to - // self-destruct, resulting in a trap. - assert_err_ignore_postinfo!( - Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, vec![0],), - "contract trapped during execution" - ); - - // Check that BOB is still alive. - assert_matches!( - ContractInfoOf::::get(BOB), - Some(ContractInfo::Alive(_)) - ); - }); -} - -#[test] -fn self_destruct_works() { - let (wasm, code_hash) = compile_module::("self_destruct").unwrap(); - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - - // Instantiate the BOB contract. - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100_000, - GAS_LIMIT, - code_hash.into(), - vec![], - )); - - // Check that the BOB contract has been instantiated. - assert_matches!( - ContractInfoOf::::get(BOB), - Some(ContractInfo::Alive(_)) - ); - - // Call BOB without input data which triggers termination. - assert_matches!( - Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, vec![],), - Ok(_) - ); - - // Check that account is gone - assert!(ContractInfoOf::::get(BOB).is_none()); - - // check that the beneficiary (django) got remaining balance - assert_eq!(Balances::free_balance(DJANGO), 100_000); - }); -} - -// This tests that one contract cannot prevent another from self-destructing by sending it -// additional funds after it has been drained. -#[test] -fn destroy_contract_and_transfer_funds() { - let (callee_wasm, callee_code_hash) = compile_module::("self_destruct").unwrap(); - let (caller_wasm, caller_code_hash) = compile_module::("destroy_and_transfer").unwrap(); - - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), callee_wasm)); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), caller_wasm)); - - // This deploys the BOB contract, which in turn deploys the CHARLIE contract during - // construction. - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 200_000, - GAS_LIMIT, - caller_code_hash.into(), - callee_code_hash.as_ref().to_vec(), - )); - - // Check that the CHARLIE contract has been instantiated. - assert_matches!( - ContractInfoOf::::get(CHARLIE), - Some(ContractInfo::Alive(_)) - ); - - // Call BOB, which calls CHARLIE, forcing CHARLIE to self-destruct. - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - CHARLIE.encode(), - )); - - // Check that CHARLIE has moved on to the great beyond (ie. died). - assert!(ContractInfoOf::::get(CHARLIE).is_none()); - }); -} - -#[test] -fn cannot_self_destruct_in_constructor() { - let (wasm, code_hash) = compile_module::("self_destructing_constructor").unwrap(); - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - - // Fail to instantiate the BOB because the call that is issued in the deploy - // function exhausts all balances which puts it below the existential deposit. - assert_err_ignore_postinfo!( - Contracts::instantiate( - Origin::signed(ALICE), - 100_000, - GAS_LIMIT, - code_hash.into(), - vec![], - ), - "contract trapped during execution" - ); - }); -} - -#[test] -fn get_runtime_storage() { - let (wasm, code_hash) = compile_module::("get_runtime_storage").unwrap(); - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - - frame_support::storage::unhashed::put_raw( - &[1, 2, 3, 4], - 0x14144020u32.to_le_bytes().to_vec().as_ref(), - ); - - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100, - GAS_LIMIT, - code_hash.into(), - vec![], - )); - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - vec![], - )); - }); -} - -#[test] -fn crypto_hashes() { - let (wasm, code_hash) = compile_module::("crypto_hashes").unwrap(); - - ExtBuilder::default() - .existential_deposit(50) - .build() - .execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - - // Instantiate the CRYPTO_HASHES contract. - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100_000, - GAS_LIMIT, - code_hash.into(), - vec![], - )); - // Perform the call. - let input = b"_DEAD_BEEF"; - use sp_io::hashing::*; - // Wraps a hash function into a more dynamic form usable for testing. - macro_rules! dyn_hash_fn { - ($name:ident) => { - Box::new(|input| $name(input).as_ref().to_vec().into_boxed_slice()) - }; - } - // All hash functions and their associated output byte lengths. - let test_cases: &[(Box Box<[u8]>>, usize)] = &[ - (dyn_hash_fn!(sha2_256), 32), - (dyn_hash_fn!(keccak_256), 32), - (dyn_hash_fn!(blake2_256), 32), - (dyn_hash_fn!(blake2_128), 16), - ]; - // Test the given hash functions for the input: "_DEAD_BEEF" - for (n, (hash_fn, expected_size)) in test_cases.iter().enumerate() { - // We offset data in the contract tables by 1. - let mut params = vec![(n + 1) as u8]; - params.extend_from_slice(input); - let result = >::bare_call(ALICE, BOB, 0, GAS_LIMIT, params) - .0 - .unwrap(); - assert_eq!(result.status, 0); - let expected = hash_fn(input.as_ref()); - assert_eq!(&result.data[..*expected_size], &*expected); - } - }) -} diff --git a/rococo-parachains/pallets/contracts/src/wasm/code_cache.rs b/rococo-parachains/pallets/contracts/src/wasm/code_cache.rs deleted file mode 100644 index 6514ff1656..0000000000 --- a/rococo-parachains/pallets/contracts/src/wasm/code_cache.rs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! A module that implements instrumented code cache. -//! -//! - In order to run contract code we need to instrument it with gas metering. -//! To do that we need to provide the schedule which will supply exact gas costs values. -//! We cache this code in the storage saving the schedule version. -//! - Before running contract code we check if the cached code has the schedule version that -//! is equal to the current saved schedule. -//! If it is equal then run the code, if it isn't reinstrument with the current schedule. -//! - When we update the schedule we want it to have strictly greater version than the current saved one: -//! this guarantees that every instrumented contract code in cache cannot have the version equal to the current one. -//! Thus, before executing a contract it should be reinstrument with new schedule. - -use crate::{ - wasm::{prepare, runtime::Env, PrefabWasmModule}, - CodeHash, CodeStorage, PristineCode, Schedule, Trait, -}; -use frame_support::StorageMap; -use sp_runtime::traits::Hash; -use sp_std::prelude::*; - -/// Put code in the storage. The hash of code is used as a key and is returned -/// as a result of this function. -/// -/// This function instruments the given code and caches it in the storage. -pub fn save( - original_code: Vec, - schedule: &Schedule, -) -> Result, &'static str> { - let prefab_module = prepare::prepare_contract::(&original_code, schedule)?; - let code_hash = T::Hashing::hash(&original_code); - - >::insert(code_hash, prefab_module); - >::insert(code_hash, original_code); - - Ok(code_hash) -} - -/// Load code with the given code hash. -/// -/// If the module was instrumented with a lower version of schedule than -/// the current one given as an argument, then this function will perform -/// re-instrumentation and update the cache in the storage. -pub fn load( - code_hash: &CodeHash, - schedule: &Schedule, -) -> Result { - let mut prefab_module = >::get(code_hash).ok_or_else(|| "code is not found")?; - - if prefab_module.schedule_version < schedule.version { - // The current schedule version is greater than the version of the one cached - // in the storage. - // - // We need to re-instrument the code with the latest schedule here. - let original_code = - >::get(code_hash).ok_or_else(|| "pristine code is not found")?; - prefab_module = prepare::prepare_contract::(&original_code, schedule)?; - >::insert(&code_hash, &prefab_module); - } - Ok(prefab_module) -} diff --git a/rococo-parachains/pallets/contracts/src/wasm/env_def/macros.rs b/rococo-parachains/pallets/contracts/src/wasm/env_def/macros.rs deleted file mode 100644 index 88ef68ec75..0000000000 --- a/rococo-parachains/pallets/contracts/src/wasm/env_def/macros.rs +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Definition of macros that hides boilerplate of defining external environment -//! for a wasm module. -//! -//! Most likely you should use `define_env` macro. - -#[macro_export] -macro_rules! convert_args { - () => (vec![]); - ( $( $t:ty ),* ) => ( vec![ $( { use $crate::wasm::env_def::ConvertibleToWasm; <$t>::VALUE_TYPE }, )* ] ); -} - -#[macro_export] -macro_rules! gen_signature { - ( ( $( $params: ty ),* ) ) => ( - { - parity_wasm::elements::FunctionType::new(convert_args!($($params),*), None) - } - ); - - ( ( $( $params: ty ),* ) -> $returns: ty ) => ( - { - parity_wasm::elements::FunctionType::new(convert_args!($($params),*), Some({ - use $crate::wasm::env_def::ConvertibleToWasm; <$returns>::VALUE_TYPE - })) - } - ); -} - -#[macro_export] -macro_rules! gen_signature_dispatch { - ( - $needle_name:ident, - $needle_sig:ident ; - $name:ident - ( $ctx:ident $( , $names:ident : $params:ty )* ) $( -> $returns:ty )* , $($rest:tt)* ) => { - if stringify!($name).as_bytes() == $needle_name { - let signature = gen_signature!( ( $( $params ),* ) $( -> $returns )* ); - if $needle_sig == &signature { - return true; - } - } else { - gen_signature_dispatch!($needle_name, $needle_sig ; $($rest)*); - } - }; - ( $needle_name:ident, $needle_sig:ident ; ) => { - }; -} - -/// Unmarshall arguments and then execute `body` expression and return its result. -macro_rules! unmarshall_then_body { - ( $body:tt, $ctx:ident, $args_iter:ident, $( $names:ident : $params:ty ),* ) => ({ - $( - let $names : <$params as $crate::wasm::env_def::ConvertibleToWasm>::NativeType = - $args_iter.next() - .and_then(|v| <$params as $crate::wasm::env_def::ConvertibleToWasm> - ::from_typed_value(v.clone())) - .expect( - "precondition: all imports should be checked against the signatures of corresponding - functions defined by `define_env!` macro by the user of the macro; - signatures of these functions defined by `$params`; - calls always made with arguments types of which are defined by the corresponding imports; - thus types of arguments should be equal to type list in `$params` and - length of argument list and $params should be equal; - thus this can never be `None`; - qed; - " - ); - )* - $body - }) -} - -/// Since we can't specify the type of closure directly at binding site: -/// -/// ```nocompile -/// let f: FnOnce() -> Result<::NativeType, _> = || { /* ... */ }; -/// ``` -/// -/// we use this function to constrain the type of the closure. -#[inline(always)] -pub fn constrain_closure(f: F) -> F -where - F: FnOnce() -> Result, -{ - f -} - -#[macro_export] -macro_rules! unmarshall_then_body_then_marshall { - ( $args_iter:ident, $ctx:ident, ( $( $names:ident : $params:ty ),* ) -> $returns:ty => $body:tt ) => ({ - let body = $crate::wasm::env_def::macros::constrain_closure::< - <$returns as $crate::wasm::env_def::ConvertibleToWasm>::NativeType, _ - >(|| { - unmarshall_then_body!($body, $ctx, $args_iter, $( $names : $params ),*) - }); - let r = body()?; - return Ok(sp_sandbox::ReturnValue::Value({ use $crate::wasm::env_def::ConvertibleToWasm; r.to_typed_value() })) - }); - ( $args_iter:ident, $ctx:ident, ( $( $names:ident : $params:ty ),* ) => $body:tt ) => ({ - let body = $crate::wasm::env_def::macros::constrain_closure::<(), _>(|| { - unmarshall_then_body!($body, $ctx, $args_iter, $( $names : $params ),*) - }); - body()?; - return Ok(sp_sandbox::ReturnValue::Unit) - }) -} - -#[macro_export] -macro_rules! define_func { - ( < E: $ext_ty:tt > $name:ident ( $ctx: ident $(, $names:ident : $params:ty)*) $(-> $returns:ty)* => $body:tt ) => { - fn $name< E: $ext_ty >( - $ctx: &mut $crate::wasm::Runtime, - args: &[sp_sandbox::Value], - ) -> Result { - #[allow(unused)] - let mut args = args.iter(); - - unmarshall_then_body_then_marshall!( - args, - $ctx, - ( $( $names : $params ),* ) $( -> $returns )* => $body - ) - } - }; -} - -#[macro_export] -macro_rules! register_func { - ( $reg_cb:ident, < E: $ext_ty:tt > ; ) => {}; - - ( $reg_cb:ident, < E: $ext_ty:tt > ; - $name:ident ( $ctx:ident $( , $names:ident : $params:ty )* ) - $( -> $returns:ty )* => $body:tt $($rest:tt)* - ) => { - $reg_cb( - stringify!($name).as_bytes(), - { - define_func!( - < E: $ext_ty > $name ( $ctx $(, $names : $params )* ) $( -> $returns )* => $body - ); - $name:: - } - ); - register_func!( $reg_cb, < E: $ext_ty > ; $($rest)* ); - }; -} - -/// Define a function set that can be imported by executing wasm code. -/// -/// **NB**: Be advised that all functions defined by this macro -/// will panic if called with unexpected arguments. -/// -/// It's up to the user of this macro to check signatures of wasm code to be executed -/// and reject the code if any imported function has a mismatched signature. -macro_rules! define_env { - ( $init_name:ident , < E: $ext_ty:tt > , - $( $name:ident ( $ctx:ident $( , $names:ident : $params:ty )* ) - $( -> $returns:ty )* => $body:tt , )* - ) => { - pub struct $init_name; - - impl $crate::wasm::env_def::ImportSatisfyCheck for $init_name { - fn can_satisfy(name: &[u8], func_type: &parity_wasm::elements::FunctionType) -> bool { - gen_signature_dispatch!( name, func_type ; $( $name ( $ctx $(, $names : $params )* ) $( -> $returns )* , )* ); - - return false; - } - } - - impl $crate::wasm::env_def::FunctionImplProvider for $init_name { - fn impls)>(f: &mut F) { - register_func!(f, < E: $ext_ty > ; $( $name ( $ctx $( , $names : $params )* ) $( -> $returns)* => $body )* ); - } - } - }; -} - -#[cfg(test)] -mod tests { - use crate::{ - exec::Ext, - gas::Gas, - wasm::{tests::MockExt, Runtime}, - }; - use parity_wasm::elements::{FunctionType, ValueType}; - use sp_runtime::traits::Zero; - use sp_sandbox::{ReturnValue, Value}; - - #[test] - fn macro_unmarshall_then_body_then_marshall_value_or_trap() { - fn test_value( - _ctx: &mut u32, - args: &[sp_sandbox::Value], - ) -> Result { - let mut args = args.iter(); - unmarshall_then_body_then_marshall!( - args, - _ctx, - (a: u32, b: u32) -> u32 => { - if b == 0 { - Err(sp_sandbox::HostError) - } else { - Ok(a / b) - } - } - ) - } - - let ctx = &mut 0; - assert_eq!( - test_value(ctx, &[Value::I32(15), Value::I32(3)]).unwrap(), - ReturnValue::Value(Value::I32(5)), - ); - assert!(test_value(ctx, &[Value::I32(15), Value::I32(0)]).is_err()); - } - - #[test] - fn macro_unmarshall_then_body_then_marshall_unit() { - fn test_unit( - ctx: &mut u32, - args: &[sp_sandbox::Value], - ) -> Result { - let mut args = args.iter(); - unmarshall_then_body_then_marshall!( - args, - ctx, - (a: u32, b: u32) => { - *ctx = a + b; - Ok(()) - } - ) - } - - let ctx = &mut 0; - let result = test_unit(ctx, &[Value::I32(2), Value::I32(3)]).unwrap(); - assert_eq!(result, ReturnValue::Unit); - assert_eq!(*ctx, 5); - } - - #[test] - fn macro_define_func() { - define_func!( ext_gas (_ctx, amount: u32) => { - let amount = Gas::from(amount); - if !amount.is_zero() { - Ok(()) - } else { - Err(sp_sandbox::HostError) - } - }); - let _f: fn( - &mut Runtime, - &[sp_sandbox::Value], - ) -> Result = ext_gas::; - } - - #[test] - fn macro_gen_signature() { - assert_eq!( - gen_signature!((i32)), - FunctionType::new(vec![ValueType::I32], None), - ); - - assert_eq!( - gen_signature!( (i32, u32) -> u32 ), - FunctionType::new(vec![ValueType::I32, ValueType::I32], Some(ValueType::I32)), - ); - } - - #[test] - fn macro_unmarshall_then_body() { - let args = vec![Value::I32(5), Value::I32(3)]; - let mut args = args.iter(); - - let ctx: &mut u32 = &mut 0; - - let r = unmarshall_then_body!( - { - *ctx = a + b; - a * b - }, - ctx, - args, - a: u32, - b: u32 - ); - - assert_eq!(*ctx, 8); - assert_eq!(r, 15); - } - - #[test] - fn macro_define_env() { - use crate::wasm::env_def::ImportSatisfyCheck; - - define_env!(Env, , - ext_gas( _ctx, amount: u32 ) => { - let amount = Gas::from(amount); - if !amount.is_zero() { - Ok(()) - } else { - Err(sp_sandbox::HostError) - } - }, - ); - - assert!(Env::can_satisfy( - b"ext_gas", - &FunctionType::new(vec![ValueType::I32], None) - )); - assert!(!Env::can_satisfy( - b"not_exists", - &FunctionType::new(vec![], None) - )); - } -} diff --git a/rococo-parachains/pallets/contracts/src/wasm/env_def/mod.rs b/rococo-parachains/pallets/contracts/src/wasm/env_def/mod.rs deleted file mode 100644 index 4bb7660aeb..0000000000 --- a/rococo-parachains/pallets/contracts/src/wasm/env_def/mod.rs +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -use super::Runtime; -use crate::exec::Ext; - -use parity_wasm::elements::{FunctionType, ValueType}; -use sp_sandbox::Value; - -#[macro_use] -pub(crate) mod macros; - -pub trait ConvertibleToWasm: Sized { - const VALUE_TYPE: ValueType; - type NativeType; - fn to_typed_value(self) -> Value; - fn from_typed_value(_: Value) -> Option; -} -impl ConvertibleToWasm for i32 { - type NativeType = i32; - const VALUE_TYPE: ValueType = ValueType::I32; - fn to_typed_value(self) -> Value { - Value::I32(self) - } - fn from_typed_value(v: Value) -> Option { - v.as_i32() - } -} -impl ConvertibleToWasm for u32 { - type NativeType = u32; - const VALUE_TYPE: ValueType = ValueType::I32; - fn to_typed_value(self) -> Value { - Value::I32(self as i32) - } - fn from_typed_value(v: Value) -> Option { - match v { - Value::I32(v) => Some(v as u32), - _ => None, - } - } -} -impl ConvertibleToWasm for u64 { - type NativeType = u64; - const VALUE_TYPE: ValueType = ValueType::I64; - fn to_typed_value(self) -> Value { - Value::I64(self as i64) - } - fn from_typed_value(v: Value) -> Option { - match v { - Value::I64(v) => Some(v as u64), - _ => None, - } - } -} - -pub(crate) type HostFunc = fn( - &mut Runtime, - &[sp_sandbox::Value], -) -> Result; - -pub(crate) trait FunctionImplProvider { - fn impls)>(f: &mut F); -} - -/// This trait can be used to check whether the host environment can satisfy -/// a requested function import. -pub trait ImportSatisfyCheck { - /// Returns `true` if the host environment contains a function with - /// the specified name and its type matches to the given type, or `false` - /// otherwise. - fn can_satisfy(name: &[u8], func_type: &FunctionType) -> bool; -} diff --git a/rococo-parachains/pallets/contracts/src/wasm/mod.rs b/rococo-parachains/pallets/contracts/src/wasm/mod.rs deleted file mode 100644 index 2c81467fbe..0000000000 --- a/rococo-parachains/pallets/contracts/src/wasm/mod.rs +++ /dev/null @@ -1,2016 +0,0 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! This module provides a means for executing contracts -//! represented in wasm. - -use crate::{ - exec::{ExecResult, Ext}, - gas::GasMeter, - wasm::env_def::FunctionImplProvider, - CodeHash, Schedule, Trait, -}; - -use codec::{Decode, Encode}; -use sp_sandbox; -use sp_std::prelude::*; - -#[macro_use] -mod env_def; -mod code_cache; -mod prepare; -mod runtime; - -use self::{ - code_cache::load as load_code, - runtime::{to_execution_result, Runtime}, -}; - -pub use self::code_cache::save as save_code; - -/// A prepared wasm module ready for execution. -#[derive(Clone, Encode, Decode)] -pub struct PrefabWasmModule { - /// Version of the schedule with which the code was instrumented. - #[codec(compact)] - schedule_version: u32, - #[codec(compact)] - initial: u32, - #[codec(compact)] - maximum: u32, - /// This field is reserved for future evolution of format. - /// - /// Basically, for now this field will be serialized as `None`. In the future - /// we would be able to extend this structure with. - _reserved: Option<()>, - /// Code instrumented with the latest schedule. - code: Vec, -} - -/// Wasm executable loaded by `WasmLoader` and executed by `WasmVm`. -pub struct WasmExecutable { - entrypoint_name: &'static str, - prefab_module: PrefabWasmModule, -} - -/// Loader which fetches `WasmExecutable` from the code cache. -pub struct WasmLoader<'a> { - schedule: &'a Schedule, -} - -impl<'a> WasmLoader<'a> { - pub fn new(schedule: &'a Schedule) -> Self { - WasmLoader { schedule } - } -} - -impl<'a, T: Trait> crate::exec::Loader for WasmLoader<'a> { - type Executable = WasmExecutable; - - fn load_init(&self, code_hash: &CodeHash) -> Result { - let prefab_module = load_code::(code_hash, self.schedule)?; - Ok(WasmExecutable { - entrypoint_name: "deploy", - prefab_module, - }) - } - fn load_main(&self, code_hash: &CodeHash) -> Result { - let prefab_module = load_code::(code_hash, self.schedule)?; - Ok(WasmExecutable { - entrypoint_name: "call", - prefab_module, - }) - } -} - -/// Implementation of `Vm` that takes `WasmExecutable` and executes it. -pub struct WasmVm<'a> { - schedule: &'a Schedule, -} - -impl<'a> WasmVm<'a> { - pub fn new(schedule: &'a Schedule) -> Self { - WasmVm { schedule } - } -} - -impl<'a, T: Trait> crate::exec::Vm for WasmVm<'a> { - type Executable = WasmExecutable; - - fn execute>( - &self, - exec: &WasmExecutable, - mut ext: E, - input_data: Vec, - gas_meter: &mut GasMeter, - ) -> ExecResult { - let memory = - sp_sandbox::Memory::new(exec.prefab_module.initial, Some(exec.prefab_module.maximum)) - .unwrap_or_else(|_| { - // unlike `.expect`, explicit panic preserves the source location. - // Needed as we can't use `RUST_BACKTRACE` in here. - panic!( - "exec.prefab_module.initial can't be greater than exec.prefab_module.maximum; - thus Memory::new must not fail; - qed" - ) - }); - - let mut imports = sp_sandbox::EnvironmentDefinitionBuilder::new(); - imports.add_memory("env", "memory", memory.clone()); - runtime::Env::impls(&mut |name, func_ptr| { - imports.add_host_func("env", name, func_ptr); - }); - - let mut runtime = Runtime::new(&mut ext, input_data, &self.schedule, memory, gas_meter); - - // Instantiate the instance from the instrumented module code and invoke the contract - // entrypoint. - let result = sp_sandbox::Instance::new(&exec.prefab_module.code, &imports, &mut runtime) - .and_then(|mut instance| instance.invoke(exec.entrypoint_name, &[], &mut runtime)); - to_execution_result(runtime, result) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{ - exec::{ExecError, ExecReturnValue, Ext, StorageKey, STATUS_SUCCESS}, - gas::{Gas, GasMeter}, - tests::{Call, Test}, - wasm::prepare::prepare_contract, - BalanceOf, CodeHash, - }; - use assert_matches::assert_matches; - use frame_support::weights::Weight; - use hex_literal::hex; - use sp_core::H256; - use sp_runtime::DispatchError; - use std::{cell::RefCell, collections::HashMap}; - use wabt; - - const GAS_LIMIT: Gas = 10_000_000_000; - - #[derive(Debug, PartialEq, Eq)] - struct DispatchEntry(Call); - - #[derive(Debug, PartialEq, Eq)] - struct RestoreEntry { - dest: u64, - code_hash: H256, - rent_allowance: u64, - delta: Vec, - } - - #[derive(Debug, PartialEq, Eq)] - struct InstantiateEntry { - code_hash: H256, - endowment: u64, - data: Vec, - gas_left: u64, - } - - #[derive(Debug, PartialEq, Eq)] - struct TerminationEntry { - beneficiary: u64, - gas_left: u64, - } - - #[derive(Debug, PartialEq, Eq)] - struct TransferEntry { - to: u64, - value: u64, - data: Vec, - gas_left: u64, - } - - #[derive(Default)] - pub struct MockExt { - storage: HashMap>, - rent_allowance: u64, - instantiates: Vec, - terminations: Vec, - transfers: Vec, - dispatches: Vec, - restores: Vec, - // (topics, data) - events: Vec<(Vec, Vec)>, - next_account_id: u64, - - /// Runtime storage keys works the following way. - /// - /// - If the test code requests a value and it doesn't exist in this storage map then a - /// panic happens. - /// - If the value does exist it is returned and then removed from the map. So a panic - /// happens if the same value is requested for the second time. - /// - /// This behavior is used to prevent mixing up an access to unexpected location and empty - /// cell. - runtime_storage_keys: RefCell, Option>>>, - } - - impl Ext for MockExt { - type T = Test; - - fn get_storage(&self, key: &StorageKey) -> Option> { - self.storage.get(key).cloned() - } - fn set_storage( - &mut self, - key: StorageKey, - value: Option>, - ) -> Result<(), &'static str> { - *self.storage.entry(key).or_insert(Vec::new()) = value.unwrap_or(Vec::new()); - Ok(()) - } - fn instantiate( - &mut self, - code_hash: &CodeHash, - endowment: u64, - gas_meter: &mut GasMeter, - data: Vec, - ) -> Result<(u64, ExecReturnValue), ExecError> { - self.instantiates.push(InstantiateEntry { - code_hash: code_hash.clone(), - endowment, - data: data.to_vec(), - gas_left: gas_meter.gas_left(), - }); - let address = self.next_account_id; - self.next_account_id += 1; - - Ok(( - address, - ExecReturnValue { - status: STATUS_SUCCESS, - data: Vec::new(), - }, - )) - } - fn transfer( - &mut self, - to: &u64, - value: u64, - gas_meter: &mut GasMeter, - ) -> Result<(), DispatchError> { - self.transfers.push(TransferEntry { - to: *to, - value, - data: Vec::new(), - gas_left: gas_meter.gas_left(), - }); - Ok(()) - } - fn call( - &mut self, - to: &u64, - value: u64, - gas_meter: &mut GasMeter, - data: Vec, - ) -> ExecResult { - self.transfers.push(TransferEntry { - to: *to, - value, - data: data, - gas_left: gas_meter.gas_left(), - }); - // Assume for now that it was just a plain transfer. - // TODO: Add tests for different call outcomes. - Ok(ExecReturnValue { - status: STATUS_SUCCESS, - data: Vec::new(), - }) - } - fn terminate( - &mut self, - beneficiary: &u64, - gas_meter: &mut GasMeter, - ) -> Result<(), DispatchError> { - self.terminations.push(TerminationEntry { - beneficiary: *beneficiary, - gas_left: gas_meter.gas_left(), - }); - Ok(()) - } - fn note_dispatch_call(&mut self, call: Call) { - self.dispatches.push(DispatchEntry(call)); - } - fn note_restore_to( - &mut self, - dest: u64, - code_hash: H256, - rent_allowance: u64, - delta: Vec, - ) { - self.restores.push(RestoreEntry { - dest, - code_hash, - rent_allowance, - delta, - }); - } - fn caller(&self) -> &u64 { - &42 - } - fn address(&self) -> &u64 { - &69 - } - fn balance(&self) -> u64 { - 228 - } - fn value_transferred(&self) -> u64 { - 1337 - } - - fn now(&self) -> &u64 { - &1111 - } - - fn minimum_balance(&self) -> u64 { - 666 - } - - fn tombstone_deposit(&self) -> u64 { - 16 - } - - fn random(&self, subject: &[u8]) -> H256 { - H256::from_slice(subject) - } - - fn deposit_event(&mut self, topics: Vec, data: Vec) { - self.events.push((topics, data)) - } - - fn set_rent_allowance(&mut self, rent_allowance: u64) { - self.rent_allowance = rent_allowance; - } - - fn rent_allowance(&self) -> u64 { - self.rent_allowance - } - - fn block_number(&self) -> u64 { - 121 - } - - fn max_value_size(&self) -> u32 { - 16_384 - } - - fn get_runtime_storage(&self, key: &[u8]) -> Option> { - let opt_value = self.runtime_storage_keys.borrow_mut().remove(key); - opt_value.unwrap_or_else(|| { - panic!( - "{:?} doesn't exist. values that do exist {:?}", - key, self.runtime_storage_keys - ) - }) - } - fn get_weight_price(&self, weight: Weight) -> BalanceOf { - BalanceOf::::from(1312_u32).saturating_mul(weight.into()) - } - } - - impl Ext for &mut MockExt { - type T = ::T; - - fn get_storage(&self, key: &[u8; 32]) -> Option> { - (**self).get_storage(key) - } - fn set_storage( - &mut self, - key: [u8; 32], - value: Option>, - ) -> Result<(), &'static str> { - (**self).set_storage(key, value) - } - fn instantiate( - &mut self, - code: &CodeHash, - value: u64, - gas_meter: &mut GasMeter, - input_data: Vec, - ) -> Result<(u64, ExecReturnValue), ExecError> { - (**self).instantiate(code, value, gas_meter, input_data) - } - fn transfer( - &mut self, - to: &u64, - value: u64, - gas_meter: &mut GasMeter, - ) -> Result<(), DispatchError> { - (**self).transfer(to, value, gas_meter) - } - fn terminate( - &mut self, - beneficiary: &u64, - gas_meter: &mut GasMeter, - ) -> Result<(), DispatchError> { - (**self).terminate(beneficiary, gas_meter) - } - fn call( - &mut self, - to: &u64, - value: u64, - gas_meter: &mut GasMeter, - input_data: Vec, - ) -> ExecResult { - (**self).call(to, value, gas_meter, input_data) - } - fn note_dispatch_call(&mut self, call: Call) { - (**self).note_dispatch_call(call) - } - fn note_restore_to( - &mut self, - dest: u64, - code_hash: H256, - rent_allowance: u64, - delta: Vec, - ) { - (**self).note_restore_to(dest, code_hash, rent_allowance, delta) - } - fn caller(&self) -> &u64 { - (**self).caller() - } - fn address(&self) -> &u64 { - (**self).address() - } - fn balance(&self) -> u64 { - (**self).balance() - } - fn value_transferred(&self) -> u64 { - (**self).value_transferred() - } - fn now(&self) -> &u64 { - (**self).now() - } - fn minimum_balance(&self) -> u64 { - (**self).minimum_balance() - } - fn tombstone_deposit(&self) -> u64 { - (**self).tombstone_deposit() - } - fn random(&self, subject: &[u8]) -> H256 { - (**self).random(subject) - } - fn deposit_event(&mut self, topics: Vec, data: Vec) { - (**self).deposit_event(topics, data) - } - fn set_rent_allowance(&mut self, rent_allowance: u64) { - (**self).set_rent_allowance(rent_allowance) - } - fn rent_allowance(&self) -> u64 { - (**self).rent_allowance() - } - fn block_number(&self) -> u64 { - (**self).block_number() - } - fn max_value_size(&self) -> u32 { - (**self).max_value_size() - } - fn get_runtime_storage(&self, key: &[u8]) -> Option> { - (**self).get_runtime_storage(key) - } - fn get_weight_price(&self, weight: Weight) -> BalanceOf { - (**self).get_weight_price(weight) - } - } - - fn execute( - wat: &str, - input_data: Vec, - ext: E, - gas_meter: &mut GasMeter, - ) -> ExecResult { - use crate::exec::Vm; - - let wasm = wabt::wat2wasm(wat).unwrap(); - let schedule = crate::Schedule::default(); - let prefab_module = prepare_contract::(&wasm, &schedule).unwrap(); - - let exec = WasmExecutable { - // Use a "call" convention. - entrypoint_name: "call", - prefab_module, - }; - - let cfg = Default::default(); - let vm = WasmVm::new(&cfg); - - vm.execute(&exec, ext, input_data, gas_meter) - } - - const CODE_TRANSFER: &str = r#" -(module - ;; ext_transfer( - ;; account_ptr: u32, - ;; account_len: u32, - ;; value_ptr: u32, - ;; value_len: u32, - ;;) -> u32 - (import "env" "ext_transfer" (func $ext_transfer (param i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - (func (export "call") - (drop - (call $ext_transfer - (i32.const 4) ;; Pointer to "account" address. - (i32.const 8) ;; Length of "account" address. - (i32.const 12) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - ) - ) - ) - (func (export "deploy")) - - ;; Destination AccountId to transfer the funds. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 4) "\07\00\00\00\00\00\00\00") - - ;; Amount of value to transfer. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 12) "\99\00\00\00\00\00\00\00") -) -"#; - - #[test] - fn contract_transfer() { - let mut mock_ext = MockExt::default(); - let _ = execute( - CODE_TRANSFER, - vec![], - &mut mock_ext, - &mut GasMeter::new(GAS_LIMIT), - ) - .unwrap(); - - assert_eq!( - &mock_ext.transfers, - &[TransferEntry { - to: 7, - value: 153, - data: Vec::new(), - gas_left: 9989000000, - }] - ); - } - - const CODE_CALL: &str = r#" -(module - ;; ext_call( - ;; callee_ptr: u32, - ;; callee_len: u32, - ;; gas: u64, - ;; value_ptr: u32, - ;; value_len: u32, - ;; input_data_ptr: u32, - ;; input_data_len: u32 - ;;) -> u32 - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - (func (export "call") - (drop - (call $ext_call - (i32.const 4) ;; Pointer to "callee" address. - (i32.const 8) ;; Length of "callee" address. - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 12) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 20) ;; Pointer to input data buffer address - (i32.const 4) ;; Length of input data buffer - ) - ) - ) - (func (export "deploy")) - - ;; Destination AccountId to transfer the funds. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 4) "\09\00\00\00\00\00\00\00") - ;; Amount of value to transfer. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 12) "\06\00\00\00\00\00\00\00") - - (data (i32.const 20) "\01\02\03\04") -) -"#; - - #[test] - fn contract_call() { - let mut mock_ext = MockExt::default(); - let _ = execute( - CODE_CALL, - vec![], - &mut mock_ext, - &mut GasMeter::new(GAS_LIMIT), - ) - .unwrap(); - - assert_eq!( - &mock_ext.transfers, - &[TransferEntry { - to: 9, - value: 6, - data: vec![1, 2, 3, 4], - gas_left: 9985500000, - }] - ); - } - - const CODE_INSTANTIATE: &str = r#" -(module - ;; ext_instantiate( - ;; code_ptr: u32, - ;; code_len: u32, - ;; gas: u64, - ;; value_ptr: u32, - ;; value_len: u32, - ;; input_data_ptr: u32, - ;; input_data_len: u32, - ;; ) -> u32 - (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - (func (export "call") - (drop - (call $ext_instantiate - (i32.const 16) ;; Pointer to `code_hash` - (i32.const 32) ;; Length of `code_hash` - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 4) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 12) ;; Pointer to input data buffer address - (i32.const 4) ;; Length of input data buffer - ) - ) - ) - (func (export "deploy")) - - ;; Amount of value to transfer. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 4) "\03\00\00\00\00\00\00\00") - ;; Input data to pass to the contract being instantiated. - (data (i32.const 12) "\01\02\03\04") - ;; Hash of code. - (data (i32.const 16) - "\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11" - "\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11" - ) -) -"#; - - #[test] - fn contract_instantiate() { - let mut mock_ext = MockExt::default(); - let _ = execute( - CODE_INSTANTIATE, - vec![], - &mut mock_ext, - &mut GasMeter::new(GAS_LIMIT), - ) - .unwrap(); - - assert_eq!( - &mock_ext.instantiates, - &[InstantiateEntry { - code_hash: [0x11; 32].into(), - endowment: 3, - data: vec![1, 2, 3, 4], - gas_left: 9973500000, - }] - ); - } - - const CODE_TERMINATE: &str = r#" -(module - ;; ext_terminate( - ;; beneficiary_ptr: u32, - ;; beneficiary_len: u32, - ;; ) - (import "env" "ext_terminate" (func $ext_terminate (param i32 i32))) - (import "env" "memory" (memory 1 1)) - (func (export "call") - (call $ext_terminate - (i32.const 4) ;; Pointer to "beneficiary" address. - (i32.const 8) ;; Length of "beneficiary" address. - ) - ) - (func (export "deploy")) - - ;; Beneficiary AccountId to transfer the funds. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 4) "\09\00\00\00\00\00\00\00") -) -"#; - - #[test] - fn contract_terminate() { - let mut mock_ext = MockExt::default(); - execute( - CODE_TERMINATE, - vec![], - &mut mock_ext, - &mut GasMeter::new(GAS_LIMIT), - ) - .unwrap(); - - assert_eq!( - &mock_ext.terminations, - &[TerminationEntry { - beneficiary: 0x09, - gas_left: 9994500000, - }] - ); - } - - const CODE_TRANSFER_LIMITED_GAS: &str = r#" -(module - ;; ext_call( - ;; callee_ptr: u32, - ;; callee_len: u32, - ;; gas: u64, - ;; value_ptr: u32, - ;; value_len: u32, - ;; input_data_ptr: u32, - ;; input_data_len: u32 - ;;) -> u32 - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - (func (export "call") - (drop - (call $ext_call - (i32.const 4) ;; Pointer to "callee" address. - (i32.const 8) ;; Length of "callee" address. - (i64.const 228) ;; How much gas to devote for the execution. - (i32.const 12) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 20) ;; Pointer to input data buffer address - (i32.const 4) ;; Length of input data buffer - ) - ) - ) - (func (export "deploy")) - - ;; Destination AccountId to transfer the funds. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 4) "\09\00\00\00\00\00\00\00") - ;; Amount of value to transfer. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 12) "\06\00\00\00\00\00\00\00") - - (data (i32.const 20) "\01\02\03\04") -) -"#; - - #[test] - fn contract_call_limited_gas() { - let mut mock_ext = MockExt::default(); - let _ = execute( - &CODE_TRANSFER_LIMITED_GAS, - vec![], - &mut mock_ext, - &mut GasMeter::new(GAS_LIMIT), - ) - .unwrap(); - - assert_eq!( - &mock_ext.transfers, - &[TransferEntry { - to: 9, - value: 6, - data: vec![1, 2, 3, 4], - gas_left: 228, - }] - ); - } - - const CODE_GET_STORAGE: &str = r#" -(module - (import "env" "ext_get_storage" (func $ext_get_storage (param i32) (result i32))) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_return" (func $ext_return (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - (local $buf_size i32) - - - ;; Load a storage value into the scratch buf. - (call $assert - (i32.eq - (call $ext_get_storage - (i32.const 4) ;; The pointer to the storage key to fetch - ) - - ;; Return value 0 means that the value is found and there were - ;; no errors. - (i32.const 0) - ) - ) - - ;; Find out the size of the scratch buffer - (set_local $buf_size - (call $ext_scratch_size) - ) - - ;; Copy scratch buffer into this contract memory. - (call $ext_scratch_read - (i32.const 36) ;; The pointer where to store the scratch buffer contents, - ;; 36 = 4 + 32 - (i32.const 0) ;; Offset from the start of the scratch buffer. - (get_local ;; Count of bytes to copy. - $buf_size - ) - ) - - ;; Return the contents of the buffer - (call $ext_return - (i32.const 36) - (get_local $buf_size) - ) - - ;; env:ext_return doesn't return, so this is effectively unreachable. - (unreachable) - ) - - (func (export "deploy")) - - (data (i32.const 4) - "\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11" - "\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11" - ) -) -"#; - - #[test] - fn get_storage_puts_data_into_scratch_buf() { - let mut mock_ext = MockExt::default(); - mock_ext.storage.insert([0x11; 32], [0x22; 32].to_vec()); - - let output = execute( - CODE_GET_STORAGE, - vec![], - mock_ext, - &mut GasMeter::new(GAS_LIMIT), - ) - .unwrap(); - - assert_eq!( - output, - ExecReturnValue { - status: STATUS_SUCCESS, - data: [0x22; 32].to_vec() - } - ); - } - - /// calls `ext_caller`, loads the address from the scratch buffer and - /// compares it with the constant 42. - const CODE_CALLER: &str = r#" -(module - (import "env" "ext_caller" (func $ext_caller)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; fill the scratch buffer with the caller. - (call $ext_caller) - - ;; assert $ext_scratch_size == 8 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to the i64 value of 42. - (call $assert - (i64.eq - (i64.load - (i32.const 8) - ) - (i64.const 42) - ) - ) - ) - - (func (export "deploy")) -) -"#; - - #[test] - fn caller() { - let _ = execute( - CODE_CALLER, - vec![], - MockExt::default(), - &mut GasMeter::new(GAS_LIMIT), - ) - .unwrap(); - } - - /// calls `ext_address`, loads the address from the scratch buffer and - /// compares it with the constant 69. - const CODE_ADDRESS: &str = r#" -(module - (import "env" "ext_address" (func $ext_address)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; fill the scratch buffer with the self address. - (call $ext_address) - - ;; assert $ext_scratch_size == 8 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to the i64 value of 69. - (call $assert - (i64.eq - (i64.load - (i32.const 8) - ) - (i64.const 69) - ) - ) - ) - - (func (export "deploy")) -) -"#; - - #[test] - fn address() { - let _ = execute( - CODE_ADDRESS, - vec![], - MockExt::default(), - &mut GasMeter::new(GAS_LIMIT), - ) - .unwrap(); - } - - const CODE_BALANCE: &str = r#" -(module - (import "env" "ext_balance" (func $ext_balance)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; This stores the balance in the scratch buffer - (call $ext_balance) - - ;; assert $ext_scratch_size == 8 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to the i64 value of 228. - (call $assert - (i64.eq - (i64.load - (i32.const 8) - ) - (i64.const 228) - ) - ) - ) - (func (export "deploy")) -) -"#; - - #[test] - fn balance() { - let mut gas_meter = GasMeter::new(GAS_LIMIT); - let _ = execute(CODE_BALANCE, vec![], MockExt::default(), &mut gas_meter).unwrap(); - } - - const CODE_GAS_PRICE: &str = r#" -(module - (import "env" "ext_gas_price" (func $ext_gas_price (param i64))) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; This stores the gas price in the scratch buffer - (call $ext_gas_price (i64.const 1)) - - ;; assert $ext_scratch_size == 8 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to the i64 value of 1312. - (call $assert - (i64.eq - (i64.load - (i32.const 8) - ) - (i64.const 1312) - ) - ) - ) - (func (export "deploy")) -) -"#; - - #[test] - fn gas_price() { - let mut gas_meter = GasMeter::new(GAS_LIMIT); - let _ = execute(CODE_GAS_PRICE, vec![], MockExt::default(), &mut gas_meter).unwrap(); - } - - const CODE_GAS_LEFT: &str = r#" -(module - (import "env" "ext_gas_left" (func $ext_gas_left)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_return" (func $ext_return (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; This stores the gas left in the scratch buffer - (call $ext_gas_left) - - ;; assert $ext_scratch_size == 8 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - (call $ext_return - (i32.const 8) - (i32.const 8) - ) - - (unreachable) - ) - (func (export "deploy")) -) -"#; - - #[test] - fn gas_left() { - let mut gas_meter = GasMeter::new(GAS_LIMIT); - - let output = execute(CODE_GAS_LEFT, vec![], MockExt::default(), &mut gas_meter).unwrap(); - - let gas_left = Gas::decode(&mut output.data.as_slice()).unwrap(); - assert!(gas_left < GAS_LIMIT, "gas_left must be less than initial"); - assert!( - gas_left > gas_meter.gas_left(), - "gas_left must be greater than final" - ); - } - - const CODE_VALUE_TRANSFERRED: &str = r#" -(module - (import "env" "ext_value_transferred" (func $ext_value_transferred)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; This stores the value transferred in the scratch buffer - (call $ext_value_transferred) - - ;; assert $ext_scratch_size == 8 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to the i64 value of 1337. - (call $assert - (i64.eq - (i64.load - (i32.const 8) - ) - (i64.const 1337) - ) - ) - ) - (func (export "deploy")) -) -"#; - - #[test] - fn value_transferred() { - let mut gas_meter = GasMeter::new(GAS_LIMIT); - let _ = execute( - CODE_VALUE_TRANSFERRED, - vec![], - MockExt::default(), - &mut gas_meter, - ) - .unwrap(); - } - - const CODE_DISPATCH_CALL: &str = r#" -(module - (import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "call") - (call $ext_dispatch_call - (i32.const 8) ;; Pointer to the start of encoded call buffer - (i32.const 13) ;; Length of the buffer - ) - ) - (func (export "deploy")) - - (data (i32.const 8) "\00\01\2A\00\00\00\00\00\00\00\E5\14\00") -) -"#; - - #[test] - fn dispatch_call() { - // This test can fail due to the encoding changes. In case it becomes too annoying - // let's rewrite so as we use this module controlled call or we serialize it in runtime. - - let mut mock_ext = MockExt::default(); - let _ = execute( - CODE_DISPATCH_CALL, - vec![], - &mut mock_ext, - &mut GasMeter::new(GAS_LIMIT), - ) - .unwrap(); - - assert_eq!( - &mock_ext.dispatches, - &[DispatchEntry(Call::Balances( - pallet_balances::Call::set_balance(42, 1337, 0) - ),)] - ); - } - - const CODE_RETURN_FROM_START_FN: &str = r#" -(module - (import "env" "ext_return" (func $ext_return (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (start $start) - (func $start - (call $ext_return - (i32.const 8) - (i32.const 4) - ) - (unreachable) - ) - - (func (export "call") - (unreachable) - ) - (func (export "deploy")) - - (data (i32.const 8) "\01\02\03\04") -) -"#; - - #[test] - fn return_from_start_fn() { - let output = execute( - CODE_RETURN_FROM_START_FN, - vec![], - MockExt::default(), - &mut GasMeter::new(GAS_LIMIT), - ) - .unwrap(); - - assert_eq!( - output, - ExecReturnValue { - status: STATUS_SUCCESS, - data: vec![1, 2, 3, 4] - } - ); - } - - const CODE_TIMESTAMP_NOW: &str = r#" -(module - (import "env" "ext_now" (func $ext_now)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; This stores the block timestamp in the scratch buffer - (call $ext_now) - - ;; assert $ext_scratch_size == 8 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to the i64 value of 1111. - (call $assert - (i64.eq - (i64.load - (i32.const 8) - ) - (i64.const 1111) - ) - ) - ) - (func (export "deploy")) -) -"#; - - #[test] - fn now() { - let mut gas_meter = GasMeter::new(GAS_LIMIT); - let _ = execute( - CODE_TIMESTAMP_NOW, - vec![], - MockExt::default(), - &mut gas_meter, - ) - .unwrap(); - } - - const CODE_MINIMUM_BALANCE: &str = r#" -(module - (import "env" "ext_minimum_balance" (func $ext_minimum_balance)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - (call $ext_minimum_balance) - - ;; assert $ext_scratch_size == 8 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to the i64 value of 666. - (call $assert - (i64.eq - (i64.load - (i32.const 8) - ) - (i64.const 666) - ) - ) - ) - (func (export "deploy")) -) -"#; - - #[test] - fn minimum_balance() { - let mut gas_meter = GasMeter::new(GAS_LIMIT); - let _ = execute( - CODE_MINIMUM_BALANCE, - vec![], - MockExt::default(), - &mut gas_meter, - ) - .unwrap(); - } - - const CODE_TOMBSTONE_DEPOSIT: &str = r#" -(module - (import "env" "ext_tombstone_deposit" (func $ext_tombstone_deposit)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - (call $ext_tombstone_deposit) - - ;; assert $ext_scratch_size == 8 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to the i64 value of 16. - (call $assert - (i64.eq - (i64.load - (i32.const 8) - ) - (i64.const 16) - ) - ) - ) - (func (export "deploy")) -) -"#; - - #[test] - fn tombstone_deposit() { - let mut gas_meter = GasMeter::new(GAS_LIMIT); - let _ = execute( - CODE_TOMBSTONE_DEPOSIT, - vec![], - MockExt::default(), - &mut gas_meter, - ) - .unwrap(); - } - - const CODE_RANDOM: &str = r#" -(module - (import "env" "ext_random" (func $ext_random (param i32 i32))) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_return" (func $ext_return (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; This stores the block random seed in the scratch buffer - (call $ext_random - (i32.const 40) ;; Pointer in memory to the start of the subject buffer - (i32.const 32) ;; The subject buffer's length - ) - - ;; assert $ext_scratch_size == 32 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 32) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 32) ;; Count of bytes to copy. - ) - - ;; return the data from the contract - (call $ext_return - (i32.const 8) - (i32.const 32) - ) - ) - (func (export "deploy")) - - ;; [8,40) is reserved for the result of PRNG. - - ;; the subject used for the PRNG. [40,72) - (data (i32.const 40) - "\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F" - "\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F" - ) -) -"#; - - #[test] - fn random() { - let mut gas_meter = GasMeter::new(GAS_LIMIT); - - let output = execute(CODE_RANDOM, vec![], MockExt::default(), &mut gas_meter).unwrap(); - - // The mock ext just returns the same data that was passed as the subject. - assert_eq!( - output, - ExecReturnValue { - status: STATUS_SUCCESS, - data: hex!("000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F") - .to_vec(), - }, - ); - } - - const CODE_DEPOSIT_EVENT: &str = r#" -(module - (import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "call") - (call $ext_deposit_event - (i32.const 32) ;; Pointer to the start of topics buffer - (i32.const 33) ;; The length of the topics buffer. - (i32.const 8) ;; Pointer to the start of the data buffer - (i32.const 13) ;; Length of the buffer - ) - ) - (func (export "deploy")) - - (data (i32.const 8) "\00\01\2A\00\00\00\00\00\00\00\E5\14\00") - - ;; Encoded Vec>, the buffer has length of 33 bytes. - (data (i32.const 32) "\04\33\33\33\33\33\33\33\33\33\33\33\33\33\33\33\33\33\33\33\33\33\33\33" - "\33\33\33\33\33\33\33\33\33") -) -"#; - - #[test] - fn deposit_event() { - let mut mock_ext = MockExt::default(); - let mut gas_meter = GasMeter::new(GAS_LIMIT); - let _ = execute(CODE_DEPOSIT_EVENT, vec![], &mut mock_ext, &mut gas_meter).unwrap(); - - assert_eq!( - mock_ext.events, - vec![( - vec![H256::repeat_byte(0x33)], - vec![0x00, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x14, 0x00] - )] - ); - - assert_eq!(gas_meter.gas_left(), 9967000000); - } - - const CODE_DEPOSIT_EVENT_MAX_TOPICS: &str = r#" -(module - (import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "call") - (call $ext_deposit_event - (i32.const 32) ;; Pointer to the start of topics buffer - (i32.const 161) ;; The length of the topics buffer. - (i32.const 8) ;; Pointer to the start of the data buffer - (i32.const 13) ;; Length of the buffer - ) - ) - (func (export "deploy")) - - (data (i32.const 8) "\00\01\2A\00\00\00\00\00\00\00\E5\14\00") - - ;; Encoded Vec>, the buffer has length of 161 bytes. - (data (i32.const 32) "\14" -"\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01" -"\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02" -"\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03" -"\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04" -"\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05") -) -"#; - - #[test] - fn deposit_event_max_topics() { - // Checks that the runtime traps if there are more than `max_topic_events` topics. - let mut gas_meter = GasMeter::new(GAS_LIMIT); - - assert_matches!( - execute( - CODE_DEPOSIT_EVENT_MAX_TOPICS, - vec![], - MockExt::default(), - &mut gas_meter - ), - Err(ExecError { - reason: DispatchError::Other("contract trapped during execution"), - buffer: _, - }) - ); - } - - const CODE_DEPOSIT_EVENT_DUPLICATES: &str = r#" -(module - (import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "call") - (call $ext_deposit_event - (i32.const 32) ;; Pointer to the start of topics buffer - (i32.const 129) ;; The length of the topics buffer. - (i32.const 8) ;; Pointer to the start of the data buffer - (i32.const 13) ;; Length of the buffer - ) - ) - (func (export "deploy")) - - (data (i32.const 8) "\00\01\2A\00\00\00\00\00\00\00\E5\14\00") - - ;; Encoded Vec>, the buffer has length of 129 bytes. - (data (i32.const 32) "\10" -"\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01" -"\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02" -"\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01" -"\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04") -) -"#; - - #[test] - fn deposit_event_duplicates() { - // Checks that the runtime traps if there are duplicates. - let mut gas_meter = GasMeter::new(GAS_LIMIT); - - assert_matches!( - execute( - CODE_DEPOSIT_EVENT_DUPLICATES, - vec![], - MockExt::default(), - &mut gas_meter - ), - Err(ExecError { - reason: DispatchError::Other("contract trapped during execution"), - buffer: _, - }) - ); - } - - /// calls `ext_block_number`, loads the current block number from the scratch buffer and - /// compares it with the constant 121. - const CODE_BLOCK_NUMBER: &str = r#" -(module - (import "env" "ext_block_number" (func $ext_block_number)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; This stores the block height in the scratch buffer - (call $ext_block_number) - - ;; assert $ext_scratch_size == 8 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to the i64 value of 121. - (call $assert - (i64.eq - (i64.load - (i32.const 8) - ) - (i64.const 121) - ) - ) - ) - - (func (export "deploy")) -) -"#; - - #[test] - fn block_number() { - let _ = execute( - CODE_BLOCK_NUMBER, - vec![], - MockExt::default(), - &mut GasMeter::new(GAS_LIMIT), - ) - .unwrap(); - } - - // asserts that the size of the input data is 4. - const CODE_SIMPLE_ASSERT: &str = r#" -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "deploy")) - - (func (export "call") - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 4) - ) - ) - ) -) -"#; - - #[test] - fn output_buffer_capacity_preserved_on_success() { - let mut input_data = Vec::with_capacity(1_234); - input_data.extend_from_slice(&[1, 2, 3, 4][..]); - - let output = execute( - CODE_SIMPLE_ASSERT, - input_data, - MockExt::default(), - &mut GasMeter::new(GAS_LIMIT), - ) - .unwrap(); - - assert_eq!(output.data.len(), 0); - assert_eq!(output.data.capacity(), 1_234); - } - - #[test] - fn output_buffer_capacity_preserved_on_failure() { - let mut input_data = Vec::with_capacity(1_234); - input_data.extend_from_slice(&[1, 2, 3, 4, 5][..]); - - let error = execute( - CODE_SIMPLE_ASSERT, - input_data, - MockExt::default(), - &mut GasMeter::new(GAS_LIMIT), - ) - .err() - .unwrap(); - - assert_eq!(error.buffer.capacity(), 1_234); - } - - const CODE_RETURN_WITH_DATA: &str = r#" -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; Deploy routine is the same as call. - (func (export "deploy") (result i32) - (call $call) - ) - - ;; Call reads the first 4 bytes (LE) as the exit status and returns the rest as output data. - (func $call (export "call") (result i32) - (local $buf_size i32) - (local $exit_status i32) - - ;; Find out the size of the scratch buffer - (set_local $buf_size (call $ext_scratch_size)) - - ;; Copy scratch buffer into this contract memory. - (call $ext_scratch_read - (i32.const 0) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (get_local $buf_size) ;; Count of bytes to copy. - ) - - ;; Copy all but the first 4 bytes of the input data as the output data. - (call $ext_scratch_write - (i32.const 4) ;; Offset from the start of the scratch buffer. - (i32.sub ;; Count of bytes to copy. - (get_local $buf_size) - (i32.const 4) - ) - ) - - ;; Return the first 4 bytes of the input data as the exit status. - (i32.load (i32.const 0)) - ) -) -"#; - - #[test] - fn return_with_success_status() { - let output = execute( - CODE_RETURN_WITH_DATA, - hex!("00112233445566778899").to_vec(), - MockExt::default(), - &mut GasMeter::new(GAS_LIMIT), - ) - .unwrap(); - - assert_eq!( - output, - ExecReturnValue { - status: 0, - data: hex!("445566778899").to_vec() - } - ); - assert!(output.is_success()); - } - - #[test] - fn return_with_failure_status() { - let output = execute( - CODE_RETURN_WITH_DATA, - hex!("112233445566778899").to_vec(), - MockExt::default(), - &mut GasMeter::new(GAS_LIMIT), - ) - .unwrap(); - - assert_eq!( - output, - ExecReturnValue { - status: 17, - data: hex!("5566778899").to_vec() - } - ); - assert!(!output.is_success()); - } - - const CODE_GET_RUNTIME_STORAGE: &str = r#" -(module - (import "env" "ext_get_runtime_storage" - (func $ext_get_runtime_storage (param i32 i32) (result i32)) - ) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "deploy")) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func $call (export "call") - ;; Load runtime storage for the first key and assert that it exists. - (call $assert - (i32.eq - (call $ext_get_runtime_storage - (i32.const 16) - (i32.const 4) - ) - (i32.const 0) - ) - ) - - ;; assert $ext_scratch_size == 4 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 4) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 4) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 4) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to the i32 value of 0x14144020. - (call $assert - (i32.eq - (i32.load - (i32.const 4) - ) - (i32.const 0x14144020) - ) - ) - - ;; Load the second key and assert that it doesn't exist. - (call $assert - (i32.eq - (call $ext_get_runtime_storage - (i32.const 20) - (i32.const 4) - ) - (i32.const 1) - ) - ) - ) - - ;; The first key, 4 bytes long. - (data (i32.const 16) "\01\02\03\04") - ;; The second key, 4 bytes long. - (data (i32.const 20) "\02\03\04\05") -) -"#; - - #[test] - fn get_runtime_storage() { - let mut gas_meter = GasMeter::new(GAS_LIMIT); - let mock_ext = MockExt::default(); - - // "\01\02\03\04" - Some(0x14144020) - // "\02\03\04\05" - None - *mock_ext.runtime_storage_keys.borrow_mut() = [ - ( - [1, 2, 3, 4].to_vec(), - Some(0x14144020u32.to_le_bytes().to_vec()), - ), - ([2, 3, 4, 5].to_vec().to_vec(), None), - ] - .iter() - .cloned() - .collect(); - let _ = execute(CODE_GET_RUNTIME_STORAGE, vec![], mock_ext, &mut gas_meter).unwrap(); - } -} diff --git a/rococo-parachains/pallets/contracts/src/wasm/prepare.rs b/rococo-parachains/pallets/contracts/src/wasm/prepare.rs deleted file mode 100644 index a20088b3b9..0000000000 --- a/rococo-parachains/pallets/contracts/src/wasm/prepare.rs +++ /dev/null @@ -1,871 +0,0 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! This module takes care of loading, checking and preprocessing of a -//! wasm module before execution. It also extracts some essential information -//! from a module. - -use crate::{ - wasm::{env_def::ImportSatisfyCheck, PrefabWasmModule}, - Schedule, -}; - -use parity_wasm::elements::{self, External, Internal, MemoryType, Type, ValueType}; -use pwasm_utils::{self, rules}; -use sp_runtime::traits::SaturatedConversion; -use sp_std::prelude::*; - -struct ContractModule<'a> { - /// A deserialized module. The module is valid (this is Guaranteed by `new` method). - module: elements::Module, - schedule: &'a Schedule, -} - -impl<'a> ContractModule<'a> { - /// Creates a new instance of `ContractModule`. - /// - /// Returns `Err` if the `original_code` couldn't be decoded or - /// if it contains an invalid module. - fn new(original_code: &[u8], schedule: &'a Schedule) -> Result { - use wasmi_validation::{validate_module, PlainValidator}; - - let module = - elements::deserialize_buffer(original_code).map_err(|_| "Can't decode wasm code")?; - - // Make sure that the module is valid. - validate_module::(&module).map_err(|_| "Module is not valid")?; - - // Return a `ContractModule` instance with - // __valid__ module. - Ok(ContractModule { module, schedule }) - } - - /// Ensures that module doesn't declare internal memories. - /// - /// In this runtime we only allow wasm module to import memory from the environment. - /// Memory section contains declarations of internal linear memories, so if we find one - /// we reject such a module. - fn ensure_no_internal_memory(&self) -> Result<(), &'static str> { - if self - .module - .memory_section() - .map_or(false, |ms| ms.entries().len() > 0) - { - return Err("module declares internal memory"); - } - Ok(()) - } - - /// Ensures that tables declared in the module are not too big. - fn ensure_table_size_limit(&self, limit: u32) -> Result<(), &'static str> { - if let Some(table_section) = self.module.table_section() { - // In Wasm MVP spec, there may be at most one table declared. Double check this - // explicitly just in case the Wasm version changes. - if table_section.entries().len() > 1 { - return Err("multiple tables declared"); - } - if let Some(table_type) = table_section.entries().first() { - // Check the table's initial size as there is no instruction or environment function - // capable of growing the table. - if table_type.limits().initial() > limit { - return Err("table exceeds maximum size allowed"); - } - } - } - Ok(()) - } - - /// Ensures that no floating point types are in use. - fn ensure_no_floating_types(&self) -> Result<(), &'static str> { - if let Some(global_section) = self.module.global_section() { - for global in global_section.entries() { - match global.global_type().content_type() { - ValueType::F32 | ValueType::F64 => { - return Err("use of floating point type in globals is forbidden") - } - _ => {} - } - } - } - - if let Some(code_section) = self.module.code_section() { - for func_body in code_section.bodies() { - for local in func_body.locals() { - match local.value_type() { - ValueType::F32 | ValueType::F64 => { - return Err("use of floating point type in locals is forbidden") - } - _ => {} - } - } - } - } - - if let Some(type_section) = self.module.type_section() { - for wasm_type in type_section.types() { - match wasm_type { - Type::Function(func_type) => { - let return_type = func_type.return_type(); - for value_type in func_type.params().iter().chain(return_type.iter()) { - match value_type { - ValueType::F32 | ValueType::F64 => { - return Err( - "use of floating point type in function types is forbidden", - ) - } - _ => {} - } - } - } - } - } - } - - Ok(()) - } - - fn inject_gas_metering(self) -> Result { - let gas_rules = rules::Set::new( - self.schedule.regular_op_cost.clone().saturated_into(), - Default::default(), - ) - .with_grow_cost(self.schedule.grow_mem_cost.clone().saturated_into()) - .with_forbidden_floats(); - - let contract_module = pwasm_utils::inject_gas_counter(self.module, &gas_rules) - .map_err(|_| "gas instrumentation failed")?; - Ok(ContractModule { - module: contract_module, - schedule: self.schedule, - }) - } - - fn inject_stack_height_metering(self) -> Result { - let contract_module = - pwasm_utils::stack_height::inject_limiter(self.module, self.schedule.max_stack_height) - .map_err(|_| "stack height instrumentation failed")?; - Ok(ContractModule { - module: contract_module, - schedule: self.schedule, - }) - } - - /// Check that the module has required exported functions. For now - /// these are just entrypoints: - /// - /// - 'call' - /// - 'deploy' - /// - /// Any other exports are not allowed. - fn scan_exports(&self) -> Result<(), &'static str> { - let mut deploy_found = false; - let mut call_found = false; - - let module = &self.module; - - let types = module.type_section().map(|ts| ts.types()).unwrap_or(&[]); - let export_entries = module - .export_section() - .map(|is| is.entries()) - .unwrap_or(&[]); - let func_entries = module - .function_section() - .map(|fs| fs.entries()) - .unwrap_or(&[]); - - // Function index space consists of imported function following by - // declared functions. Calculate the total number of imported functions so - // we can use it to convert indexes from function space to declared function space. - let fn_space_offset = module - .import_section() - .map(|is| is.entries()) - .unwrap_or(&[]) - .iter() - .filter(|entry| match *entry.external() { - External::Function(_) => true, - _ => false, - }) - .count(); - - for export in export_entries { - match export.field() { - "call" => call_found = true, - "deploy" => deploy_found = true, - _ => return Err("unknown export: expecting only deploy and call functions"), - } - - // Then check the export kind. "call" and "deploy" are - // functions. - let fn_idx = match export.internal() { - Internal::Function(ref fn_idx) => *fn_idx, - _ => return Err("expected a function"), - }; - - // convert index from function index space to declared index space. - let fn_idx = match fn_idx.checked_sub(fn_space_offset as u32) { - Some(fn_idx) => fn_idx, - None => { - // Underflow here means fn_idx points to imported function which we don't allow! - return Err("entry point points to an imported function"); - } - }; - - // Then check the signature. - // Both "call" and "deploy" has a [] -> [] or [] -> [i32] function type. - // - // The [] -> [] signature predates the [] -> [i32] signature and is supported for - // backwards compatibility. This will likely be removed once ink! is updated to - // generate modules with the new function signatures. - let func_ty_idx = func_entries - .get(fn_idx as usize) - .ok_or_else(|| "export refers to non-existent function")? - .type_ref(); - let Type::Function(ref func_ty) = types - .get(func_ty_idx as usize) - .ok_or_else(|| "function has a non-existent type")?; - if !func_ty.params().is_empty() - || !(func_ty.return_type().is_none() - || func_ty.return_type() == Some(ValueType::I32)) - { - return Err("entry point has wrong signature"); - } - } - - if !deploy_found { - return Err("deploy function isn't exported"); - } - if !call_found { - return Err("call function isn't exported"); - } - - Ok(()) - } - - /// Scan an import section if any. - /// - /// This accomplishes two tasks: - /// - /// - checks any imported function against defined host functions set, incl. - /// their signatures. - /// - if there is a memory import, returns it's descriptor - fn scan_imports(&self) -> Result, &'static str> { - let module = &self.module; - - let types = module.type_section().map(|ts| ts.types()).unwrap_or(&[]); - let import_entries = module - .import_section() - .map(|is| is.entries()) - .unwrap_or(&[]); - - let mut imported_mem_type = None; - - for import in import_entries { - if import.module() != "env" { - // This import tries to import something from non-"env" module, - // but all imports are located in "env" at the moment. - return Err("module has imports from a non-'env' namespace"); - } - - let type_idx = match import.external() { - &External::Table(_) => return Err("Cannot import tables"), - &External::Global(_) => return Err("Cannot import globals"), - &External::Function(ref type_idx) => type_idx, - &External::Memory(ref memory_type) => { - if import.field() != "memory" { - return Err("Memory import must have the field name 'memory'"); - } - if imported_mem_type.is_some() { - return Err("Multiple memory imports defined"); - } - imported_mem_type = Some(memory_type); - continue; - } - }; - - let Type::Function(ref func_ty) = types - .get(*type_idx as usize) - .ok_or_else(|| "validation: import entry points to a non-existent type")?; - - // We disallow importing `ext_println` unless debug features are enabled, - // which should only be allowed on a dev chain - if !self.schedule.enable_println && import.field().as_bytes() == b"ext_println" { - return Err("module imports `ext_println` but debug features disabled"); - } - - // We disallow importing `gas` function here since it is treated as implementation detail. - if import.field().as_bytes() == b"gas" - || !C::can_satisfy(import.field().as_bytes(), func_ty) - { - return Err("module imports a non-existent function"); - } - } - Ok(imported_mem_type) - } - - fn into_wasm_code(self) -> Result, &'static str> { - elements::serialize(self.module).map_err(|_| "error serializing instrumented module") - } -} - -/// Loads the given module given in `original_code`, performs some checks on it and -/// does some preprocessing. -/// -/// The checks are: -/// -/// - provided code is a valid wasm module. -/// - the module doesn't define an internal memory instance, -/// - imported memory (if any) doesn't reserve more memory than permitted by the `schedule`, -/// - all imported functions from the external environment matches defined by `env` module, -/// -/// The preprocessing includes injecting code for gas metering and metering the height of stack. -pub fn prepare_contract( - original_code: &[u8], - schedule: &Schedule, -) -> Result { - let mut contract_module = ContractModule::new(original_code, schedule)?; - contract_module.scan_exports()?; - contract_module.ensure_no_internal_memory()?; - contract_module.ensure_table_size_limit(schedule.max_table_size)?; - contract_module.ensure_no_floating_types()?; - - struct MemoryDefinition { - initial: u32, - maximum: u32, - } - - let memory_def = if let Some(memory_type) = contract_module.scan_imports::()? { - // Inspect the module to extract the initial and maximum page count. - let limits = memory_type.limits(); - match (limits.initial(), limits.maximum()) { - (initial, Some(maximum)) if initial > maximum => { - return Err( - "Requested initial number of pages should not exceed the requested maximum", - ); - } - (_, Some(maximum)) if maximum > schedule.max_memory_pages => { - return Err("Maximum number of pages should not exceed the configured maximum."); - } - (initial, Some(maximum)) => MemoryDefinition { initial, maximum }, - (_, None) => { - // Maximum number of pages should be always declared. - // This isn't a hard requirement and can be treated as a maximum set - // to configured maximum. - return Err("Maximum number of pages should be always declared."); - } - } - } else { - // If none memory imported then just crate an empty placeholder. - // Any access to it will lead to out of bounds trap. - MemoryDefinition { - initial: 0, - maximum: 0, - } - }; - - contract_module = contract_module - .inject_gas_metering()? - .inject_stack_height_metering()?; - - Ok(PrefabWasmModule { - schedule_version: schedule.version, - initial: memory_def.initial, - maximum: memory_def.maximum, - _reserved: None, - code: contract_module.into_wasm_code()?, - }) -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::exec::Ext; - use assert_matches::assert_matches; - use std::fmt; - use wabt; - - impl fmt::Debug for PrefabWasmModule { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "PreparedContract {{ .. }}") - } - } - - // Define test environment for tests. We need ImportSatisfyCheck - // implementation from it. So actual implementations doesn't matter. - define_env!(TestEnv, , - panic(_ctx) => { unreachable!(); }, - - // gas is an implementation defined function and a contract can't import it. - gas(_ctx, _amount: u32) => { unreachable!(); }, - - nop(_ctx, _unused: u64) => { unreachable!(); }, - - ext_println(_ctx, _ptr: u32, _len: u32) => { unreachable!(); }, - ); - - macro_rules! prepare_test { - ($name:ident, $wat:expr, $($expected:tt)*) => { - #[test] - fn $name() { - let wasm = wabt::Wat2Wasm::new().validate(false).convert($wat).unwrap(); - let schedule = Schedule::default(); - let r = prepare_contract::(wasm.as_ref(), &schedule); - assert_matches!(r, $($expected)*); - } - }; - } - - prepare_test!( - no_floats, - r#" - (module - (func (export "call") - (drop - (f32.add - (f32.const 0) - (f32.const 1) - ) - ) - ) - (func (export "deploy")) - )"#, - Err("gas instrumentation failed") - ); - - mod memories { - use super::*; - - // Tests below assumes that maximum page number is configured to a certain number. - #[test] - fn assume_memory_size() { - assert_eq!(Schedule::default().max_memory_pages, 16); - } - - prepare_test!( - memory_with_one_page, - r#" - (module - (import "env" "memory" (memory 1 1)) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - Ok(_) - ); - - prepare_test!( - internal_memory_declaration, - r#" - (module - (memory 1 1) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("module declares internal memory") - ); - - prepare_test!( - no_memory_import, - r#" - (module - ;; no memory imported - - (func (export "call")) - (func (export "deploy")) - )"#, - Ok(_) - ); - - prepare_test!( - initial_exceeds_maximum, - r#" - (module - (import "env" "memory" (memory 16 1)) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("Module is not valid") - ); - - prepare_test!( - no_maximum, - r#" - (module - (import "env" "memory" (memory 1)) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("Maximum number of pages should be always declared.") - ); - - prepare_test!( - requested_maximum_exceeds_configured_maximum, - r#" - (module - (import "env" "memory" (memory 1 17)) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("Maximum number of pages should not exceed the configured maximum.") - ); - - prepare_test!( - field_name_not_memory, - r#" - (module - (import "env" "forgetit" (memory 1 1)) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("Memory import must have the field name 'memory'") - ); - - prepare_test!( - multiple_memory_imports, - r#" - (module - (import "env" "memory" (memory 1 1)) - (import "env" "memory" (memory 1 1)) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("Module is not valid") - ); - - prepare_test!( - table_import, - r#" - (module - (import "env" "table" (table 1 anyfunc)) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("Cannot import tables") - ); - - prepare_test!( - global_import, - r#" - (module - (global $g (import "env" "global") i32) - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("Cannot import globals") - ); - } - - mod tables { - use super::*; - - // Tests below assumes that maximum table size is configured to a certain number. - #[test] - fn assume_table_size() { - assert_eq!(Schedule::default().max_table_size, 16384); - } - - prepare_test!( - no_tables, - r#" - (module - (func (export "call")) - (func (export "deploy")) - ) - "#, - Ok(_) - ); - - prepare_test!( - table_valid_size, - r#" - (module - (table 10000 funcref) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - Ok(_) - ); - - prepare_test!( - table_too_big, - r#" - (module - (table 20000 funcref) - - (func (export "call")) - (func (export "deploy")) - )"#, - Err("table exceeds maximum size allowed") - ); - } - - mod imports { - use super::*; - - prepare_test!( - can_import_legit_function, - r#" - (module - (import "env" "nop" (func (param i64))) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - Ok(_) - ); - - // even though gas is defined the contract can't import it since - // it is an implementation defined. - prepare_test!( - can_not_import_gas_function, - r#" - (module - (import "env" "gas" (func (param i32))) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("module imports a non-existent function") - ); - - // nothing can be imported from non-"env" module for now. - prepare_test!( - non_env_import, - r#" - (module - (import "another_module" "memory" (memory 1 1)) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("module has imports from a non-'env' namespace") - ); - - // wrong signature - prepare_test!( - wrong_signature, - r#" - (module - (import "env" "gas" (func (param i64))) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("module imports a non-existent function") - ); - - prepare_test!( - unknown_func_name, - r#" - (module - (import "env" "unknown_func" (func)) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("module imports a non-existent function") - ); - - prepare_test!( - ext_println_debug_disabled, - r#" - (module - (import "env" "ext_println" (func $ext_println (param i32 i32))) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("module imports `ext_println` but debug features disabled") - ); - - #[test] - fn ext_println_debug_enabled() { - let wasm = wabt::Wat2Wasm::new() - .validate(false) - .convert( - r#" - (module - (import "env" "ext_println" (func $ext_println (param i32 i32))) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - ) - .unwrap(); - let mut schedule = Schedule::default(); - schedule.enable_println = true; - let r = prepare_contract::(wasm.as_ref(), &schedule); - assert_matches!(r, Ok(_)); - } - } - - mod entrypoints { - use super::*; - - prepare_test!( - it_works, - r#" - (module - (func (export "call")) - (func (export "deploy")) - ) - "#, - Ok(_) - ); - - prepare_test!( - omit_deploy, - r#" - (module - (func (export "call")) - ) - "#, - Err("deploy function isn't exported") - ); - - prepare_test!( - omit_call, - r#" - (module - (func (export "deploy")) - ) - "#, - Err("call function isn't exported") - ); - - // Try to use imported function as an entry point. - prepare_test!( - try_sneak_export_as_entrypoint, - r#" - (module - (import "env" "panic" (func)) - - (func (export "deploy")) - - (export "call" (func 0)) - ) - "#, - Err("entry point points to an imported function") - ); - - // Try to use imported function as an entry point. - prepare_test!( - try_sneak_export_as_global, - r#" - (module - (func (export "deploy")) - (global (export "call") i32 (i32.const 0)) - ) - "#, - Err("expected a function") - ); - - prepare_test!( - wrong_signature, - r#" - (module - (func (export "deploy")) - (func (export "call") (param i32)) - ) - "#, - Err("entry point has wrong signature") - ); - - prepare_test!( - unknown_exports, - r#" - (module - (func (export "call")) - (func (export "deploy")) - (func (export "whatevs")) - ) - "#, - Err("unknown export: expecting only deploy and call functions") - ); - - prepare_test!( - global_float, - r#" - (module - (global $x f32 (f32.const 0)) - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("use of floating point type in globals is forbidden") - ); - - prepare_test!( - local_float, - r#" - (module - (func $foo (local f32)) - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("use of floating point type in locals is forbidden") - ); - - prepare_test!( - param_float, - r#" - (module - (func $foo (param f32)) - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("use of floating point type in function types is forbidden") - ); - - prepare_test!( - result_float, - r#" - (module - (func $foo (result f32) (f32.const 0)) - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("use of floating point type in function types is forbidden") - ); - } -} diff --git a/rococo-parachains/pallets/contracts/src/wasm/runtime.rs b/rococo-parachains/pallets/contracts/src/wasm/runtime.rs deleted file mode 100644 index 490621ba94..0000000000 --- a/rococo-parachains/pallets/contracts/src/wasm/runtime.rs +++ /dev/null @@ -1,1185 +0,0 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Environment definition of the wasm smart-contract runtime. - -use crate::{ - exec::{ExecError, ExecResult, ExecReturnValue, Ext, StorageKey, TopicOf, STATUS_SUCCESS}, - gas::{Gas, GasMeter, GasMeterResult, Token}, - BalanceOf, CodeHash, Schedule, Trait, -}; -use codec::{Decode, Encode}; -use frame_support::weights::GetDispatchInfo; -use frame_system; -use sp_io::hashing::{blake2_128, blake2_256, keccak_256, sha2_256}; -use sp_runtime::traits::{Bounded, SaturatedConversion}; -use sp_sandbox; -use sp_std::{convert::TryInto, mem, prelude::*}; - -/// The value returned from ext_call and ext_instantiate contract external functions if the call or -/// instantiation traps. This value is chosen as if the execution does not trap, the return value -/// will always be an 8-bit integer, so 0x0100 is the smallest value that could not be returned. -const TRAP_RETURN_CODE: u32 = 0x0100; - -/// Enumerates all possible *special* trap conditions. -/// -/// In this runtime traps used not only for signaling about errors but also -/// to just terminate quickly in some cases. -enum SpecialTrap { - /// Signals that trap was generated in response to call `ext_return` host function. - Return(Vec), - /// Signals that trap was generated because the contract exhausted its gas limit. - OutOfGas, - /// Signals that a trap was generated in response to a succesful call to the - /// `ext_terminate` host function. - Termination, -} - -/// Can only be used for one call. -pub(crate) struct Runtime<'a, E: Ext + 'a> { - ext: &'a mut E, - scratch_buf: Vec, - schedule: &'a Schedule, - memory: sp_sandbox::Memory, - gas_meter: &'a mut GasMeter, - special_trap: Option, -} -impl<'a, E: Ext + 'a> Runtime<'a, E> { - pub(crate) fn new( - ext: &'a mut E, - input_data: Vec, - schedule: &'a Schedule, - memory: sp_sandbox::Memory, - gas_meter: &'a mut GasMeter, - ) -> Self { - Runtime { - ext, - // Put the input data into the scratch buffer immediately. - scratch_buf: input_data, - schedule, - memory, - gas_meter, - special_trap: None, - } - } -} - -pub(crate) fn to_execution_result( - runtime: Runtime, - sandbox_result: Result, -) -> ExecResult { - match runtime.special_trap { - // The trap was the result of the execution `return` host function. - Some(SpecialTrap::Return(data)) => { - return Ok(ExecReturnValue { - status: STATUS_SUCCESS, - data, - }) - } - Some(SpecialTrap::Termination) => { - return Ok(ExecReturnValue { - status: STATUS_SUCCESS, - data: Vec::new(), - }) - } - Some(SpecialTrap::OutOfGas) => { - return Err(ExecError { - reason: "ran out of gas during contract execution".into(), - buffer: runtime.scratch_buf, - }) - } - None => (), - } - - // Check the exact type of the error. - match sandbox_result { - // No traps were generated. Proceed normally. - Ok(sp_sandbox::ReturnValue::Unit) => { - let mut buffer = runtime.scratch_buf; - buffer.clear(); - Ok(ExecReturnValue { - status: STATUS_SUCCESS, - data: buffer, - }) - } - Ok(sp_sandbox::ReturnValue::Value(sp_sandbox::Value::I32(exit_code))) => { - let status = (exit_code & 0xFF) - .try_into() - .expect("exit_code is masked into the range of a u8; qed"); - Ok(ExecReturnValue { - status, - data: runtime.scratch_buf, - }) - } - // This should never happen as the return type of exported functions should have been - // validated by the code preparation process. However, because panics are really - // undesirable in the runtime code, we treat this as a trap for now. Eventually, we might - // want to revisit this. - Ok(_) => Err(ExecError { - reason: "return type error".into(), - buffer: runtime.scratch_buf, - }), - // `Error::Module` is returned only if instantiation or linking failed (i.e. - // wasm binary tried to import a function that is not provided by the host). - // This shouldn't happen because validation process ought to reject such binaries. - // - // Because panics are really undesirable in the runtime code, we treat this as - // a trap for now. Eventually, we might want to revisit this. - Err(sp_sandbox::Error::Module) => Err(ExecError { - reason: "validation error".into(), - buffer: runtime.scratch_buf, - }), - // Any other kind of a trap should result in a failure. - Err(sp_sandbox::Error::Execution) | Err(sp_sandbox::Error::OutOfBounds) => Err(ExecError { - reason: "contract trapped during execution".into(), - buffer: runtime.scratch_buf, - }), - } -} - -#[cfg_attr(test, derive(Debug, PartialEq, Eq))] -#[derive(Copy, Clone)] -pub enum RuntimeToken { - /// Explicit call to the `gas` function. Charge the gas meter - /// with the value provided. - Explicit(u32), - /// The given number of bytes is read from the sandbox memory. - ReadMemory(u32), - /// The given number of bytes is written to the sandbox memory. - WriteMemory(u32), - /// The given number of bytes is read from the sandbox memory and - /// is returned as the return data buffer of the call. - ReturnData(u32), - /// Dispatched a call with the given weight. - DispatchWithWeight(Gas), - /// (topic_count, data_bytes): A buffer of the given size is posted as an event indexed with the - /// given number of topics. - DepositEvent(u32, u32), -} - -impl Token for RuntimeToken { - type Metadata = Schedule; - - fn calculate_amount(&self, metadata: &Schedule) -> Gas { - use self::RuntimeToken::*; - let value = match *self { - Explicit(amount) => Some(amount.into()), - ReadMemory(byte_count) => metadata - .sandbox_data_read_cost - .checked_mul(byte_count.into()), - WriteMemory(byte_count) => metadata - .sandbox_data_write_cost - .checked_mul(byte_count.into()), - ReturnData(byte_count) => metadata - .return_data_per_byte_cost - .checked_mul(byte_count.into()), - DepositEvent(topic_count, data_byte_count) => { - let data_cost = metadata - .event_data_per_byte_cost - .checked_mul(data_byte_count.into()); - - let topics_cost = metadata - .event_per_topic_cost - .checked_mul(topic_count.into()); - - data_cost - .and_then(|data_cost| { - topics_cost.and_then(|topics_cost| data_cost.checked_add(topics_cost)) - }) - .and_then(|data_and_topics_cost| { - data_and_topics_cost.checked_add(metadata.event_base_cost) - }) - } - DispatchWithWeight(gas) => gas.checked_add(metadata.dispatch_base_cost), - }; - - value.unwrap_or_else(|| Bounded::max_value()) - } -} - -/// Charge the gas meter with the specified token. -/// -/// Returns `Err(HostError)` if there is not enough gas. -fn charge_gas>( - gas_meter: &mut GasMeter, - metadata: &Tok::Metadata, - special_trap: &mut Option, - token: Tok, -) -> Result<(), sp_sandbox::HostError> { - match gas_meter.charge(metadata, token) { - GasMeterResult::Proceed => Ok(()), - GasMeterResult::OutOfGas => { - *special_trap = Some(SpecialTrap::OutOfGas); - Err(sp_sandbox::HostError) - } - } -} - -/// Read designated chunk from the sandbox memory, consuming an appropriate amount of -/// gas. -/// -/// Returns `Err` if one of the following conditions occurs: -/// -/// - calculating the gas cost resulted in overflow. -/// - out of gas -/// - requested buffer is not within the bounds of the sandbox memory. -fn read_sandbox_memory( - ctx: &mut Runtime, - ptr: u32, - len: u32, -) -> Result, sp_sandbox::HostError> { - charge_gas( - ctx.gas_meter, - ctx.schedule, - &mut ctx.special_trap, - RuntimeToken::ReadMemory(len), - )?; - - let mut buf = vec![0u8; len as usize]; - ctx.memory - .get(ptr, buf.as_mut_slice()) - .map_err(|_| sp_sandbox::HostError)?; - Ok(buf) -} - -/// Read designated chunk from the sandbox memory into the scratch buffer, consuming an -/// appropriate amount of gas. Resizes the scratch buffer to the specified length on success. -/// -/// Returns `Err` if one of the following conditions occurs: -/// -/// - calculating the gas cost resulted in overflow. -/// - out of gas -/// - requested buffer is not within the bounds of the sandbox memory. -fn read_sandbox_memory_into_scratch( - ctx: &mut Runtime, - ptr: u32, - len: u32, -) -> Result<(), sp_sandbox::HostError> { - charge_gas( - ctx.gas_meter, - ctx.schedule, - &mut ctx.special_trap, - RuntimeToken::ReadMemory(len), - )?; - - ctx.scratch_buf.resize(len as usize, 0); - ctx.memory - .get(ptr, ctx.scratch_buf.as_mut_slice()) - .map_err(|_| sp_sandbox::HostError)?; - Ok(()) -} - -/// Read designated chunk from the sandbox memory into the supplied buffer, consuming -/// an appropriate amount of gas. -/// -/// Returns `Err` if one of the following conditions occurs: -/// -/// - calculating the gas cost resulted in overflow. -/// - out of gas -/// - requested buffer is not within the bounds of the sandbox memory. -fn read_sandbox_memory_into_buf( - ctx: &mut Runtime, - ptr: u32, - buf: &mut [u8], -) -> Result<(), sp_sandbox::HostError> { - charge_gas( - ctx.gas_meter, - ctx.schedule, - &mut ctx.special_trap, - RuntimeToken::ReadMemory(buf.len() as u32), - )?; - - ctx.memory.get(ptr, buf).map_err(Into::into) -} - -/// Read designated chunk from the sandbox memory, consuming an appropriate amount of -/// gas, and attempt to decode into the specified type. -/// -/// Returns `Err` if one of the following conditions occurs: -/// -/// - calculating the gas cost resulted in overflow. -/// - out of gas -/// - requested buffer is not within the bounds of the sandbox memory. -/// - the buffer contents cannot be decoded as the required type. -fn read_sandbox_memory_as( - ctx: &mut Runtime, - ptr: u32, - len: u32, -) -> Result { - let buf = read_sandbox_memory(ctx, ptr, len)?; - D::decode(&mut &buf[..]).map_err(|_| sp_sandbox::HostError) -} - -/// Write the given buffer to the designated location in the sandbox memory, consuming -/// an appropriate amount of gas. -/// -/// Returns `Err` if one of the following conditions occurs: -/// -/// - calculating the gas cost resulted in overflow. -/// - out of gas -/// - designated area is not within the bounds of the sandbox memory. -fn write_sandbox_memory( - schedule: &Schedule, - special_trap: &mut Option, - gas_meter: &mut GasMeter, - memory: &sp_sandbox::Memory, - ptr: u32, - buf: &[u8], -) -> Result<(), sp_sandbox::HostError> { - charge_gas( - gas_meter, - schedule, - special_trap, - RuntimeToken::WriteMemory(buf.len() as u32), - )?; - - memory.set(ptr, buf)?; - - Ok(()) -} - -// *********************************************************** -// * AFTER MAKING A CHANGE MAKE SURE TO UPDATE COMPLEXITY.MD * -// *********************************************************** - -// Define a function `fn init_env() -> HostFunctionSet` that returns -// a function set which can be imported by an executed contract. -define_env!(Env, , - - // Account for used gas. Traps if gas used is greater than gas limit. - // - // NOTE: This is a implementation defined call and is NOT a part of the public API. - // This call is supposed to be called only by instrumentation injected code. - // - // - amount: How much gas is used. - gas(ctx, amount: u32) => { - charge_gas( - &mut ctx.gas_meter, - ctx.schedule, - &mut ctx.special_trap, - RuntimeToken::Explicit(amount) - )?; - Ok(()) - }, - - // Set the value at the given key in the contract storage. - // - // The value length must not exceed the maximum defined by the contracts module parameters. - // Storing an empty value is disallowed. - // - // # Parameters - // - // - `key_ptr`: pointer into the linear memory where the location to store the value is placed. - // - `value_ptr`: pointer into the linear memory where the value to set is placed. - // - `value_len`: the length of the value in bytes. - // - // # Errors - // - // - If value length exceeds the configured maximum value length of a storage entry. - // - Upon trying to set an empty storage entry (value length is 0). - ext_set_storage(ctx, key_ptr: u32, value_ptr: u32, value_len: u32) => { - if value_len > ctx.ext.max_value_size() { - // Bail out if value length exceeds the set maximum value size. - return Err(sp_sandbox::HostError); - } - let mut key: StorageKey = [0; 32]; - read_sandbox_memory_into_buf(ctx, key_ptr, &mut key)?; - let value = Some(read_sandbox_memory(ctx, value_ptr, value_len)?); - ctx.ext.set_storage(key, value).map_err(|_| sp_sandbox::HostError)?; - Ok(()) - }, - - // Clear the value at the given key in the contract storage. - // - // # Parameters - // - // - `key_ptr`: pointer into the linear memory where the location to clear the value is placed. - ext_clear_storage(ctx, key_ptr: u32) => { - let mut key: StorageKey = [0; 32]; - read_sandbox_memory_into_buf(ctx, key_ptr, &mut key)?; - ctx.ext.set_storage(key, None).map_err(|_| sp_sandbox::HostError)?; - Ok(()) - }, - - // Retrieve the value under the given key from the storage and return 0. - // If there is no entry under the given key then this function will return 1 and - // clear the scratch buffer. - // - // - key_ptr: pointer into the linear memory where the key - // of the requested value is placed. - ext_get_storage(ctx, key_ptr: u32) -> u32 => { - let mut key: StorageKey = [0; 32]; - read_sandbox_memory_into_buf(ctx, key_ptr, &mut key)?; - if let Some(value) = ctx.ext.get_storage(&key) { - ctx.scratch_buf = value; - Ok(0) - } else { - ctx.scratch_buf.clear(); - Ok(1) - } - }, - - // Transfer some value to another account. - // - // If the value transfer was succesful zero is returned. Otherwise one is returned. - // The scratch buffer is not touched. The receiver can be a plain account or - // a contract. - // - // - account_ptr: a pointer to the address of the beneficiary account - // Should be decodable as an `T::AccountId`. Traps otherwise. - // - account_len: length of the address buffer. - // - value_ptr: a pointer to the buffer with value, how much value to send. - // Should be decodable as a `T::Balance`. Traps otherwise. - // - value_len: length of the value buffer. - ext_transfer( - ctx, - account_ptr: u32, - account_len: u32, - value_ptr: u32, - value_len: u32 - ) -> u32 => { - let callee: <::T as frame_system::Trait>::AccountId = - read_sandbox_memory_as(ctx, account_ptr, account_len)?; - let value: BalanceOf<::T> = - read_sandbox_memory_as(ctx, value_ptr, value_len)?; - - match ctx.ext.transfer(&callee, value, ctx.gas_meter) { - Ok(_) => Ok(0), - Err(_) => Ok(1), - } - }, - - // Make a call to another contract. - // - // If the called contract runs to completion, then this returns the status code the callee - // returns on exit in the bottom 8 bits of the return value. The top 24 bits are 0s. A status - // code of 0 indicates success, and any other code indicates a failure. On failure, any state - // changes made by the called contract are reverted. The scratch buffer is filled with the - // output data returned by the called contract, even in the case of a failure status. - // - // This call fails if it would bring the calling contract below the existential deposit. - // In order to destroy a contract `ext_terminate` must be used. - // - // If the contract traps during execution or otherwise fails to complete successfully, then - // this function clears the scratch buffer and returns 0x0100. As with a failure status, any - // state changes made by the called contract are reverted. - // - // - callee_ptr: a pointer to the address of the callee contract. - // Should be decodable as an `T::AccountId`. Traps otherwise. - // - callee_len: length of the address buffer. - // - gas: how much gas to devote to the execution. - // - value_ptr: a pointer to the buffer with value, how much value to send. - // Should be decodable as a `T::Balance`. Traps otherwise. - // - value_len: length of the value buffer. - // - input_data_ptr: a pointer to a buffer to be used as input data to the callee. - // - input_data_len: length of the input data buffer. - ext_call( - ctx, - callee_ptr: u32, - callee_len: u32, - gas: u64, - value_ptr: u32, - value_len: u32, - input_data_ptr: u32, - input_data_len: u32 - ) -> u32 => { - let callee: <::T as frame_system::Trait>::AccountId = - read_sandbox_memory_as(ctx, callee_ptr, callee_len)?; - let value: BalanceOf<::T> = - read_sandbox_memory_as(ctx, value_ptr, value_len)?; - - // Read input data into the scratch buffer, then take ownership of it. - read_sandbox_memory_into_scratch(ctx, input_data_ptr, input_data_len)?; - let input_data = mem::replace(&mut ctx.scratch_buf, Vec::new()); - - let nested_gas_limit = if gas == 0 { - ctx.gas_meter.gas_left() - } else { - gas.saturated_into() - }; - let ext = &mut ctx.ext; - let call_outcome = ctx.gas_meter.with_nested(nested_gas_limit, |nested_meter| { - match nested_meter { - Some(nested_meter) => { - ext.call( - &callee, - value, - nested_meter, - input_data, - ) - .map_err(|err| err.buffer) - } - // there is not enough gas to allocate for the nested call. - None => Err(input_data), - } - }); - - match call_outcome { - Ok(output) => { - ctx.scratch_buf = output.data; - Ok(output.status.into()) - }, - Err(buffer) => { - ctx.scratch_buf = buffer; - ctx.scratch_buf.clear(); - Ok(TRAP_RETURN_CODE) - }, - } - }, - - // Instantiate a contract with the specified code hash. - // - // This function creates an account and executes the constructor defined in the code specified - // by the code hash. - // - // If the constructor runs to completion, then this returns the status code that the newly - // instantiated contract returns on exit in the bottom 8 bits of the return value. The top 24 - // bits are 0s. A status code of 0 indicates success, and any other code indicates a failure. - // On failure, any state changes made by the called contract are reverted and the contract is - // not instantiated. On a success status, the scratch buffer is filled with the encoded address - // of the newly instantiated contract. In the case of a failure status, the scratch buffer is - // cleared. - // - // This call fails if it would bring the calling contract below the existential deposit. - // In order to destroy a contract `ext_terminate` must be used. - // - // If the contract traps during execution or otherwise fails to complete successfully, then - // this function clears the scratch buffer and returns 0x0100. As with a failure status, any - // state changes made by the called contract are reverted. - - // This function creates an account and executes initializer code. After the execution, - // the returned buffer is saved as the code of the created account. - // - // Returns 0 on the successful contract instantiation and puts the address of the instantiated - // contract into the scratch buffer. Otherwise, returns non-zero value and clears the scratch - // buffer. - // - // - code_hash_ptr: a pointer to the buffer that contains the initializer code. - // - code_hash_len: length of the initializer code buffer. - // - gas: how much gas to devote to the execution of the initializer code. - // - value_ptr: a pointer to the buffer with value, how much value to send. - // Should be decodable as a `T::Balance`. Traps otherwise. - // - value_len: length of the value buffer. - // - input_data_ptr: a pointer to a buffer to be used as input data to the initializer code. - // - input_data_len: length of the input data buffer. - ext_instantiate( - ctx, - code_hash_ptr: u32, - code_hash_len: u32, - gas: u64, - value_ptr: u32, - value_len: u32, - input_data_ptr: u32, - input_data_len: u32 - ) -> u32 => { - let code_hash: CodeHash<::T> = - read_sandbox_memory_as(ctx, code_hash_ptr, code_hash_len)?; - let value: BalanceOf<::T> = - read_sandbox_memory_as(ctx, value_ptr, value_len)?; - - // Read input data into the scratch buffer, then take ownership of it. - read_sandbox_memory_into_scratch(ctx, input_data_ptr, input_data_len)?; - let input_data = mem::replace(&mut ctx.scratch_buf, Vec::new()); - - let nested_gas_limit = if gas == 0 { - ctx.gas_meter.gas_left() - } else { - gas.saturated_into() - }; - let ext = &mut ctx.ext; - let instantiate_outcome = ctx.gas_meter.with_nested(nested_gas_limit, |nested_meter| { - match nested_meter { - Some(nested_meter) => { - ext.instantiate( - &code_hash, - value, - nested_meter, - input_data - ) - .map_err(|err| err.buffer) - } - // there is not enough gas to allocate for the nested call. - None => Err(input_data), - } - }); - match instantiate_outcome { - Ok((address, output)) => { - let is_success = output.is_success(); - ctx.scratch_buf = output.data; - ctx.scratch_buf.clear(); - if is_success { - // Write the address to the scratch buffer. - address.encode_to(&mut ctx.scratch_buf); - } - Ok(output.status.into()) - }, - Err(buffer) => { - ctx.scratch_buf = buffer; - ctx.scratch_buf.clear(); - Ok(TRAP_RETURN_CODE) - }, - } - }, - - // Remove the calling account and transfer remaining balance. - // - // This function never returns. Either the termination was successful and the - // execution of the destroyed contract is halted. Or it failed during the termination - // which is considered fatal and results in a trap + rollback. - // - // - beneficiary_ptr: a pointer to the address of the beneficiary account where all - // where all remaining funds of the caller are transfered. - // Should be decodable as an `T::AccountId`. Traps otherwise. - // - beneficiary_len: length of the address buffer. - ext_terminate( - ctx, - beneficiary_ptr: u32, - beneficiary_len: u32 - ) => { - let beneficiary: <::T as frame_system::Trait>::AccountId = - read_sandbox_memory_as(ctx, beneficiary_ptr, beneficiary_len)?; - - if let Ok(_) = ctx.ext.terminate(&beneficiary, ctx.gas_meter) { - ctx.special_trap = Some(SpecialTrap::Termination); - } - Err(sp_sandbox::HostError) - }, - - // Save a data buffer as a result of the execution, terminate the execution and return a - // successful result to the caller. - // - // This is the only way to return a data buffer to the caller. - ext_return(ctx, data_ptr: u32, data_len: u32) => { - charge_gas( - ctx.gas_meter, - ctx.schedule, - &mut ctx.special_trap, - RuntimeToken::ReturnData(data_len) - )?; - - read_sandbox_memory_into_scratch(ctx, data_ptr, data_len)?; - let output_buf = mem::replace(&mut ctx.scratch_buf, Vec::new()); - - ctx.special_trap = Some(SpecialTrap::Return(output_buf)); - - // The trap mechanism is used to immediately terminate the execution. - // This trap should be handled appropriately before returning the result - // to the user of this crate. - Err(sp_sandbox::HostError) - }, - - // Stores the address of the caller into the scratch buffer. - // - // If this is a top-level call (i.e. initiated by an extrinsic) the origin address of the - // extrinsic will be returned. Otherwise, if this call is initiated by another contract then the - // address of the contract will be returned. - ext_caller(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.caller().encode_to(&mut ctx.scratch_buf); - Ok(()) - }, - - // Stores the address of the current contract into the scratch buffer. - ext_address(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.address().encode_to(&mut ctx.scratch_buf); - Ok(()) - }, - - // Stores the price for the specified amount of gas in scratch buffer. - // - // The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten. - // It is recommended to avoid specifying very small values for `gas` as the prices for a single - // gas can be smaller than one. - ext_gas_price(ctx, gas: u64) => { - ctx.scratch_buf.clear(); - ctx.ext.get_weight_price(gas).encode_to(&mut ctx.scratch_buf); - Ok(()) - }, - - // Stores the amount of gas left into the scratch buffer. - // - // The data is encoded as Gas. The current contents of the scratch buffer are overwritten. - ext_gas_left(ctx) => { - ctx.scratch_buf.clear(); - ctx.gas_meter.gas_left().encode_to(&mut ctx.scratch_buf); - Ok(()) - }, - - // Stores the balance of the current account into the scratch buffer. - // - // The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten. - ext_balance(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.balance().encode_to(&mut ctx.scratch_buf); - Ok(()) - }, - - // Stores the value transferred along with this call or as endowment into the scratch buffer. - // - // The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten. - ext_value_transferred(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.value_transferred().encode_to(&mut ctx.scratch_buf); - Ok(()) - }, - - // Stores the random number for the current block for the given subject into the scratch - // buffer. - // - // The data is encoded as T::Hash. The current contents of the scratch buffer are - // overwritten. - ext_random(ctx, subject_ptr: u32, subject_len: u32) => { - // The length of a subject can't exceed `max_subject_len`. - if subject_len > ctx.schedule.max_subject_len { - return Err(sp_sandbox::HostError); - } - - let subject_buf = read_sandbox_memory(ctx, subject_ptr, subject_len)?; - ctx.scratch_buf.clear(); - ctx.ext.random(&subject_buf).encode_to(&mut ctx.scratch_buf); - Ok(()) - }, - - // Load the latest block timestamp into the scratch buffer - ext_now(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.now().encode_to(&mut ctx.scratch_buf); - Ok(()) - }, - - // Stores the minimum balance (a.k.a. existential deposit) into the scratch buffer. - // - // The data is encoded as T::Balance. The current contents of the scratch buffer are - // overwritten. - ext_minimum_balance(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.minimum_balance().encode_to(&mut ctx.scratch_buf); - Ok(()) - }, - - // Stores the tombstone deposit into the scratch buffer. - // - // The data is encoded as T::Balance. The current contents of the scratch - // buffer are overwritten. - // - // # Note - // - // The tombstone deposit is on top of the existential deposit. So in order for - // a contract to leave a tombstone the balance of the contract must not go - // below the sum of existential deposit and the tombstone deposit. The sum - // is commonly referred as subsistence threshold in code. - ext_tombstone_deposit(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.tombstone_deposit().encode_to(&mut ctx.scratch_buf); - Ok(()) - }, - - // Decodes the given buffer as a `T::Call` and adds it to the list - // of to-be-dispatched calls. - // - // All calls made it to the top-level context will be dispatched before - // finishing the execution of the calling extrinsic. - ext_dispatch_call(ctx, call_ptr: u32, call_len: u32) => { - let call: <::T as Trait>::Call = - read_sandbox_memory_as(ctx, call_ptr, call_len)?; - - // We already deducted the len costs when reading from the sandbox. - // Bill on the actual weight of the dispatched call. - let info = call.get_dispatch_info(); - charge_gas( - &mut ctx.gas_meter, - ctx.schedule, - &mut ctx.special_trap, - RuntimeToken::DispatchWithWeight(info.weight) - )?; - - ctx.ext.note_dispatch_call(call); - - Ok(()) - }, - - // Record a request to restore the caller contract to the specified contract. - // - // At the finalization stage, i.e. when all changes from the extrinsic that invoked this - // contract are committed, this function will compute a tombstone hash from the caller's - // storage and the given code hash and if the hash matches the hash found in the tombstone at - // the specified address - kill the caller contract and restore the destination contract and set - // the specified `rent_allowance`. All caller's funds are transferred to the destination. - // - // This function doesn't perform restoration right away but defers it to the end of the - // transaction. If there is no tombstone in the destination address or if the hashes don't match - // then restoration is cancelled and no changes are made. - // - // `dest_ptr`, `dest_len` - the pointer and the length of a buffer that encodes `T::AccountId` - // with the address of the to be restored contract. - // `code_hash_ptr`, `code_hash_len` - the pointer and the length of a buffer that encodes - // a code hash of the to be restored contract. - // `rent_allowance_ptr`, `rent_allowance_len` - the pointer and the length of a buffer that - // encodes the rent allowance that must be set in the case of successful restoration. - // `delta_ptr` is the pointer to the start of a buffer that has `delta_count` storage keys - // laid out sequentially. - ext_restore_to( - ctx, - dest_ptr: u32, - dest_len: u32, - code_hash_ptr: u32, - code_hash_len: u32, - rent_allowance_ptr: u32, - rent_allowance_len: u32, - delta_ptr: u32, - delta_count: u32 - ) => { - let dest: <::T as frame_system::Trait>::AccountId = - read_sandbox_memory_as(ctx, dest_ptr, dest_len)?; - let code_hash: CodeHash<::T> = - read_sandbox_memory_as(ctx, code_hash_ptr, code_hash_len)?; - let rent_allowance: BalanceOf<::T> = - read_sandbox_memory_as(ctx, rent_allowance_ptr, rent_allowance_len)?; - let delta = { - // We don't use `with_capacity` here to not eagerly allocate the user specified amount - // of memory. - let mut delta = Vec::new(); - let mut key_ptr = delta_ptr; - - for _ in 0..delta_count { - const KEY_SIZE: usize = 32; - - // Read the delta into the provided buffer and collect it into the buffer. - let mut delta_key: StorageKey = [0; KEY_SIZE]; - read_sandbox_memory_into_buf(ctx, key_ptr, &mut delta_key)?; - delta.push(delta_key); - - // Offset key_ptr to the next element. - key_ptr = key_ptr.checked_add(KEY_SIZE as u32).ok_or_else(|| sp_sandbox::HostError)?; - } - - delta - }; - - ctx.ext.note_restore_to( - dest, - code_hash, - rent_allowance, - delta, - ); - - Ok(()) - }, - - // Returns the size of the scratch buffer. - // - // For more details on the scratch buffer see `ext_scratch_read`. - ext_scratch_size(ctx) -> u32 => { - Ok(ctx.scratch_buf.len() as u32) - }, - - // Copy data from the scratch buffer starting from `offset` with length `len` into the contract - // memory. The region at which the data should be put is specified by `dest_ptr`. - // - // In order to get size of the scratch buffer use `ext_scratch_size`. At the start of contract - // execution, the scratch buffer is filled with the input data. Whenever a contract calls - // function that uses the scratch buffer the contents of the scratch buffer are overwritten. - ext_scratch_read(ctx, dest_ptr: u32, offset: u32, len: u32) => { - let offset = offset as usize; - if offset > ctx.scratch_buf.len() { - // Offset can't be larger than scratch buffer length. - return Err(sp_sandbox::HostError); - } - - // This can't panic since `offset <= ctx.scratch_buf.len()`. - let src = &ctx.scratch_buf[offset..]; - if src.len() != len as usize { - return Err(sp_sandbox::HostError); - } - - // Finally, perform the write. - write_sandbox_memory( - ctx.schedule, - &mut ctx.special_trap, - ctx.gas_meter, - &ctx.memory, - dest_ptr, - src, - )?; - - Ok(()) - }, - - // Copy data from contract memory starting from `src_ptr` with length `len` into the scratch - // buffer. This overwrites the entire scratch buffer and resizes to `len`. Specifying a `len` - // of zero clears the scratch buffer. - // - // This should be used before exiting a call or instantiation in order to set the return data. - ext_scratch_write(ctx, src_ptr: u32, len: u32) => { - read_sandbox_memory_into_scratch(ctx, src_ptr, len) - }, - - // Deposit a contract event with the data buffer and optional list of topics. There is a limit - // on the maximum number of topics specified by `max_event_topics`. - // - // - topics_ptr - a pointer to the buffer of topics encoded as `Vec`. The value of this - // is ignored if `topics_len` is set to 0. The topics list can't contain duplicates. - // - topics_len - the length of the topics buffer. Pass 0 if you want to pass an empty vector. - // - data_ptr - a pointer to a raw data buffer which will saved along the event. - // - data_len - the length of the data buffer. - ext_deposit_event(ctx, topics_ptr: u32, topics_len: u32, data_ptr: u32, data_len: u32) => { - let mut topics: Vec::::T>> = match topics_len { - 0 => Vec::new(), - _ => read_sandbox_memory_as(ctx, topics_ptr, topics_len)?, - }; - - // If there are more than `max_event_topics`, then trap. - if topics.len() > ctx.schedule.max_event_topics as usize { - return Err(sp_sandbox::HostError); - } - - // Check for duplicate topics. If there are any, then trap. - if has_duplicates(&mut topics) { - return Err(sp_sandbox::HostError); - } - - let event_data = read_sandbox_memory(ctx, data_ptr, data_len)?; - - charge_gas( - ctx.gas_meter, - ctx.schedule, - &mut ctx.special_trap, - RuntimeToken::DepositEvent(topics.len() as u32, data_len) - )?; - ctx.ext.deposit_event(topics, event_data); - - Ok(()) - }, - - // Set rent allowance of the contract - // - // - value_ptr: a pointer to the buffer with value, how much to allow for rent - // Should be decodable as a `T::Balance`. Traps otherwise. - // - value_len: length of the value buffer. - ext_set_rent_allowance(ctx, value_ptr: u32, value_len: u32) => { - let value: BalanceOf<::T> = - read_sandbox_memory_as(ctx, value_ptr, value_len)?; - ctx.ext.set_rent_allowance(value); - - Ok(()) - }, - - // Stores the rent allowance into the scratch buffer. - // - // The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten. - ext_rent_allowance(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.rent_allowance().encode_to(&mut ctx.scratch_buf); - - Ok(()) - }, - - // Prints utf8 encoded string from the data buffer. - // Only available on `--dev` chains. - // This function may be removed at any time, superseded by a more general contract debugging feature. - ext_println(ctx, str_ptr: u32, str_len: u32) => { - let data = read_sandbox_memory(ctx, str_ptr, str_len)?; - if let Ok(utf8) = core::str::from_utf8(&data) { - sp_runtime::print(utf8); - } - Ok(()) - }, - - // Stores the current block number of the current contract into the scratch buffer. - ext_block_number(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.block_number().encode_to(&mut ctx.scratch_buf); - Ok(()) - }, - - // Retrieve the value under the given key from the **runtime** storage and return 0. - // If there is no entry under the given key then this function will return 1 and - // clear the scratch buffer. - // - // - key_ptr: the pointer into the linear memory where the requested value is placed. - // - key_len: the length of the key in bytes. - ext_get_runtime_storage(ctx, key_ptr: u32, key_len: u32) -> u32 => { - // Steal the scratch buffer so that we hopefully save an allocation for the `key_buf`. - read_sandbox_memory_into_scratch(ctx, key_ptr, key_len)?; - let key_buf = mem::replace(&mut ctx.scratch_buf, Vec::new()); - - match ctx.ext.get_runtime_storage(&key_buf) { - Some(value_buf) => { - // The given value exists. - ctx.scratch_buf = value_buf; - Ok(0) - } - None => { - // Put back the `key_buf` and allow its allocation to be reused. - ctx.scratch_buf = key_buf; - ctx.scratch_buf.clear(); - Ok(1) - } - } - }, - - // Computes the SHA2 256-bit hash on the given input buffer. - // - // Returns the result directly into the given output buffer. - // - // # Note - // - // - The `input` and `output` buffer may overlap. - // - The output buffer is expected to hold at least 32 bytes (256 bits). - // - It is the callers responsibility to provide an output buffer that - // is large enough to hold the expected amount of bytes returned by the - // chosen hash function. - // - // # Parameters - // - // - `input_ptr`: the pointer into the linear memory where the input - // data is placed. - // - `input_len`: the length of the input data in bytes. - // - `output_ptr`: the pointer into the linear memory where the output - // data is placed. The function will write the result - // directly into this buffer. - ext_hash_sha2_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { - compute_hash_on_intermediate_buffer(ctx, sha2_256, input_ptr, input_len, output_ptr) - }, - - // Computes the KECCAK 256-bit hash on the given input buffer. - // - // Returns the result directly into the given output buffer. - // - // # Note - // - // - The `input` and `output` buffer may overlap. - // - The output buffer is expected to hold at least 32 bytes (256 bits). - // - It is the callers responsibility to provide an output buffer that - // is large enough to hold the expected amount of bytes returned by the - // chosen hash function. - // - // # Parameters - // - // - `input_ptr`: the pointer into the linear memory where the input - // data is placed. - // - `input_len`: the length of the input data in bytes. - // - `output_ptr`: the pointer into the linear memory where the output - // data is placed. The function will write the result - // directly into this buffer. - ext_hash_keccak_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { - compute_hash_on_intermediate_buffer(ctx, keccak_256, input_ptr, input_len, output_ptr) - }, - - // Computes the BLAKE2 256-bit hash on the given input buffer. - // - // Returns the result directly into the given output buffer. - // - // # Note - // - // - The `input` and `output` buffer may overlap. - // - The output buffer is expected to hold at least 32 bytes (256 bits). - // - It is the callers responsibility to provide an output buffer that - // is large enough to hold the expected amount of bytes returned by the - // chosen hash function. - // - // # Parameters - // - // - `input_ptr`: the pointer into the linear memory where the input - // data is placed. - // - `input_len`: the length of the input data in bytes. - // - `output_ptr`: the pointer into the linear memory where the output - // data is placed. The function will write the result - // directly into this buffer. - ext_hash_blake2_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { - compute_hash_on_intermediate_buffer(ctx, blake2_256, input_ptr, input_len, output_ptr) - }, - - // Computes the BLAKE2 128-bit hash on the given input buffer. - // - // Returns the result directly into the given output buffer. - // - // # Note - // - // - The `input` and `output` buffer may overlap. - // - The output buffer is expected to hold at least 16 bytes (128 bits). - // - It is the callers responsibility to provide an output buffer that - // is large enough to hold the expected amount of bytes returned by the - // chosen hash function. - // - // # Parameters - // - // - `input_ptr`: the pointer into the linear memory where the input - // data is placed. - // - `input_len`: the length of the input data in bytes. - // - `output_ptr`: the pointer into the linear memory where the output - // data is placed. The function will write the result - // directly into this buffer. - ext_hash_blake2_128(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { - compute_hash_on_intermediate_buffer(ctx, blake2_128, input_ptr, input_len, output_ptr) - }, -); - -/// Computes the given hash function on the scratch buffer. -/// -/// Reads from the sandboxed input buffer into an intermediate buffer. -/// Returns the result directly to the output buffer of the sandboxed memory. -/// -/// It is the callers responsibility to provide an output buffer that -/// is large enough to hold the expected amount of bytes returned by the -/// chosen hash function. -/// -/// # Note -/// -/// The `input` and `output` buffers may overlap. -fn compute_hash_on_intermediate_buffer( - ctx: &mut Runtime, - hash_fn: F, - input_ptr: u32, - input_len: u32, - output_ptr: u32, -) -> Result<(), sp_sandbox::HostError> -where - E: Ext, - F: FnOnce(&[u8]) -> R, - R: AsRef<[u8]>, -{ - // Copy the input buffer directly into the scratch buffer to avoid - // heap allocations. - let input = read_sandbox_memory(ctx, input_ptr, input_len)?; - // Compute the hash on the scratch buffer using the given hash function. - let hash = hash_fn(&input); - // Write the resulting hash back into the sandboxed output buffer. - write_sandbox_memory( - ctx.schedule, - &mut ctx.special_trap, - ctx.gas_meter, - &ctx.memory, - output_ptr, - hash.as_ref(), - )?; - Ok(()) -} - -/// Finds duplicates in a given vector. -/// -/// This function has complexity of O(n log n) and no additional memory is required, although -/// the order of items is not preserved. -fn has_duplicates>(items: &mut Vec) -> bool { - // Sort the vector - items.sort_unstable_by(|a, b| Ord::cmp(a.as_ref(), b.as_ref())); - // And then find any two consecutive equal elements. - items.windows(2).any(|w| match w { - &[ref a, ref b] => a == b, - _ => false, - }) -} diff --git a/rococo-parachains/pallets/parachain-info/Cargo.toml b/rococo-parachains/pallets/parachain-info/Cargo.toml index c70c786d3b..e1ef2e823b 100644 --- a/rococo-parachains/pallets/parachain-info/Cargo.toml +++ b/rococo-parachains/pallets/parachain-info/Cargo.toml @@ -8,8 +8,8 @@ version = "0.1.0" codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } -frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } +frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } cumulus-primitives = { path = "../../../primitives", default-features = false } diff --git a/rococo-parachains/pallets/token-dealer/Cargo.toml b/rococo-parachains/pallets/token-dealer/Cargo.toml deleted file mode 100644 index 178bf1fadf..0000000000 --- a/rococo-parachains/pallets/token-dealer/Cargo.toml +++ /dev/null @@ -1,29 +0,0 @@ -[package] -authors = ["Parity Technologies "] -edition = "2018" -name = "cumulus-token-dealer" -version = "0.1.0" - -[dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } - -frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } - -# Cumulus dependencies -cumulus-upward-message = { path = "../../../upward-message", default-features = false } -cumulus-primitives = { path = "../../../primitives", default-features = false } - -# Polkadot dependencies -polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch", default-features = false } - -[features] -default = ["std"] -std = [ - "codec/std", - "cumulus-upward-message/std", - "cumulus-primitives/std", - "frame-support/std", - "frame-system/std", - "polkadot-parachain/std", -] diff --git a/rococo-parachains/pallets/token-dealer/src/lib.rs b/rococo-parachains/pallets/token-dealer/src/lib.rs deleted file mode 100644 index 6ffc6952f1..0000000000 --- a/rococo-parachains/pallets/token-dealer/src/lib.rs +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus 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. - -// Cumulus 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 Cumulus. If not, see . - -#![cfg_attr(not(feature = "std"), no_std)] - -use frame_support::{ - decl_event, decl_module, - dispatch::DispatchResult, - traits::{Currency, ExistenceRequirement, WithdrawReason}, -}; -use frame_system::ensure_signed; - -use codec::{Decode, Encode}; -use cumulus_primitives::{ - relay_chain::DownwardMessage, - xcmp::{XCMPMessageHandler, XCMPMessageSender}, - DownwardMessageHandler, ParaId, UpwardMessageOrigin, UpwardMessageSender, -}; -use cumulus_upward_message::BalancesMessage; -use polkadot_parachain::primitives::AccountIdConversion; - -#[derive(Encode, Decode)] -pub enum XCMPMessage { - /// Transfer tokens to the given account from the Parachain account. - TransferToken(XAccountId, XBalance), -} - -type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; - -/// Configuration trait of this pallet. -pub trait Trait: frame_system::Trait { - /// Event type used by the runtime. - type Event: From> + Into<::Event>; - - /// The sender of upward messages. - type UpwardMessageSender: UpwardMessageSender; - - /// The upward message type used by the Parachain runtime. - type UpwardMessage: codec::Codec + BalancesMessage>; - - /// Currency of the runtime. - type Currency: Currency; - - /// The sender of XCMP messages. - type XCMPMessageSender: XCMPMessageSender>>; -} - -decl_event! { - pub enum Event where - AccountId = ::AccountId, - Balance = BalanceOf - { - /// Transferred tokens to the account on the relay chain. - TransferredTokensToRelayChain(AccountId, Balance), - /// Transferred tokens to the account on request from the relay chain. - TransferredTokensFromRelayChain(AccountId, Balance), - /// Transferred tokens to the account from the given parachain account. - TransferredTokensViaXCMP(ParaId, AccountId, Balance, DispatchResult), - } -} - -decl_module! { - pub struct Module for enum Call where origin: T::Origin { - /// Transfer `amount` of tokens on the relay chain from the Parachain account to - /// the given `dest` account. - #[weight = 10] - fn transfer_tokens_to_relay_chain(origin, dest: T::AccountId, amount: BalanceOf) { - let who = ensure_signed(origin)?; - - let _ = T::Currency::withdraw( - &who, - amount, - WithdrawReason::Transfer.into(), - ExistenceRequirement::AllowDeath, - )?; - - let msg = ::UpwardMessage::transfer(dest.clone(), amount.clone()); - ::UpwardMessageSender::send_upward_message(&msg, UpwardMessageOrigin::Signed) - .expect("Should not fail; qed"); - - Self::deposit_event(Event::::TransferredTokensToRelayChain(dest, amount)); - } - - /// Transfer `amount` of tokens to another parachain. - #[weight = 10] - fn transfer_tokens_to_parachain_chain( - origin, - para_id: u32, - dest: T::AccountId, - amount: BalanceOf, - ) { - //TODO we don't make sure that the parachain has some tokens on the other parachain. - let who = ensure_signed(origin)?; - - let _ = T::Currency::withdraw( - &who, - amount, - WithdrawReason::Transfer.into(), - ExistenceRequirement::AllowDeath, - )?; - - T::XCMPMessageSender::send_xcmp_message( - para_id.into(), - &XCMPMessage::TransferToken(dest, amount), - ).expect("Should not fail; qed"); - } - - fn deposit_event() = default; - } -} - -/// This is a hack to convert from one generic type to another where we are sure that both are the -/// same type/use the same encoding. -fn convert_hack(input: &impl Encode) -> O { - input.using_encoded(|e| Decode::decode(&mut &e[..]).expect("Must be compatible; qed")) -} - -impl DownwardMessageHandler for Module { - fn handle_downward_message(msg: &DownwardMessage) { - match msg { - DownwardMessage::TransferInto(dest, amount, _) => { - let dest = convert_hack(&dest); - let amount: BalanceOf = convert_hack(amount); - - let _ = T::Currency::deposit_creating(&dest, amount.clone()); - - Self::deposit_event(Event::::TransferredTokensFromRelayChain(dest, amount)); - } - _ => {} - } - } -} - -impl XCMPMessageHandler>> for Module { - fn handle_xcmp_message(src: ParaId, msg: &XCMPMessage>) { - match msg { - XCMPMessage::TransferToken(dest, amount) => { - let para_account = src.clone().into_account(); - - let res = T::Currency::transfer( - ¶_account, - dest, - amount.clone(), - ExistenceRequirement::AllowDeath, - ); - - Self::deposit_event(Event::::TransferredTokensViaXCMP( - src, - dest.clone(), - amount.clone(), - res, - )); - } - } - } -} diff --git a/rococo-parachains/primitives/Cargo.toml b/rococo-parachains/primitives/Cargo.toml index c173f29ddb..4e18824ac9 100644 --- a/rococo-parachains/primitives/Cargo.toml +++ b/rococo-parachains/primitives/Cargo.toml @@ -6,8 +6,8 @@ edition = "2018" [dependencies] # Substrate dependencies -sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } +sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } [features] default = [ "std" ] diff --git a/rococo-parachains/runtime/Cargo.toml b/rococo-parachains/runtime/Cargo.toml index 860dd36bed..0bb2928082 100644 --- a/rococo-parachains/runtime/Cargo.toml +++ b/rococo-parachains/runtime/Cargo.toml @@ -8,44 +8,41 @@ edition = '2018' serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -cumulus-token-dealer = { path = "../pallets/token-dealer", default-features = false } parachain-info = { path = "../pallets/parachain-info", default-features = false } rococo-parachain-primitives = { path = "../primitives", default-features = false } # Substrate dependencies -sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-version = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-session = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-offchain = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-block-builder = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-transaction-pool = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-inherents = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } +sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-version = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-session = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-offchain = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-block-builder = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-transaction-pool = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-inherents = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } -frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -frame-executive = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-balances = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-sudo = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } +frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +frame-executive = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +pallet-balances = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +pallet-sudo = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } # Cumulus dependencies cumulus-runtime = { path = "../../runtime", default-features = false } cumulus-parachain-upgrade = { path = "../../parachain-upgrade", default-features = false } -cumulus-message-broker = { path = "../../message-broker", default-features = false } -cumulus-upward-message = { path = "../../upward-message", default-features = false } cumulus-primitives = { path = "../../primitives", default-features = false } # Polkadot dependencies -polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch", default-features = false } +polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false , branch = "bkchr-adder-collator-integration-test" } [build-dependencies] -wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.6" } +wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "2.0.0" } [features] default = [ "std" ] @@ -75,12 +72,5 @@ std = [ "rococo-parachain-primitives/std", "cumulus-runtime/std", "cumulus-parachain-upgrade/std", - "cumulus-message-broker/std", - "cumulus-upward-message/std", "cumulus-primitives/std", - "cumulus-token-dealer/std", -] -# Will be enabled by the `wasm-builder` when building the runtime for WASM. -runtime-wasm = [ - "cumulus-upward-message/runtime-wasm", ] diff --git a/rococo-parachains/runtime/src/lib.rs b/rococo-parachains/runtime/src/lib.rs index 462b3218b7..38bc092970 100644 --- a/rococo-parachains/runtime/src/lib.rs +++ b/rococo-parachains/runtime/src/lib.rs @@ -36,9 +36,6 @@ use sp_std::prelude::*; use sp_version::NativeVersion; use sp_version::RuntimeVersion; -/// Import the token dealer pallet. -pub use cumulus_token_dealer; - // A few exports that help ease life for downstream crates. pub use frame_support::{ construct_runtime, parameter_types, @@ -142,7 +139,7 @@ impl frame_system::Trait for Runtime { /// Runtime version. type Version = Version; /// Converts a module to an index of this module in the runtime. - type ModuleToIndex = ModuleToIndex; + type PalletInfo = PalletInfo; type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); @@ -171,6 +168,7 @@ parameter_types! { pub const TransferFee: u128 = 0; pub const CreationFee: u128 = 0; pub const TransactionByteFee: u128 = 1; + pub const MaxLocks: u32 = 50; } impl pallet_balances::Trait for Runtime { @@ -182,11 +180,11 @@ impl pallet_balances::Trait for Runtime { type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; type WeightInfo = (); + type MaxLocks = MaxLocks; } impl pallet_transaction_payment::Trait for Runtime { - type Currency = Balances; - type OnTransactionPayment = (); + type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; type TransactionByteFee = TransactionByteFee; type WeightToFee = IdentityFee; type FeeMultiplierUpdate = (); @@ -199,24 +197,7 @@ impl pallet_sudo::Trait for Runtime { impl cumulus_parachain_upgrade::Trait for Runtime { type Event = Event; - type OnValidationFunctionParams = (); -} - -impl cumulus_message_broker::Trait for Runtime { - type Event = Event; - type DownwardMessageHandlers = TokenDealer; - type UpwardMessage = cumulus_upward_message::RococoUpwardMessage; - type ParachainId = ParachainInfo; - type XCMPMessage = cumulus_token_dealer::XCMPMessage; - type XCMPMessageHandlers = TokenDealer; -} - -impl cumulus_token_dealer::Trait for Runtime { - type Event = Event; - type UpwardMessageSender = MessageBroker; - type UpwardMessage = cumulus_upward_message::RococoUpwardMessage; - type Currency = Balances; - type XCMPMessageSender = MessageBroker; + type OnValidationData = (); } impl parachain_info::Trait for Runtime {} @@ -233,8 +214,6 @@ construct_runtime! { Sudo: pallet_sudo::{Module, Call, Storage, Config, Event}, RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage}, ParachainUpgrade: cumulus_parachain_upgrade::{Module, Call, Storage, Inherent, Event}, - MessageBroker: cumulus_message_broker::{Module, Call, Inherent, Event}, - TokenDealer: cumulus_token_dealer::{Module, Call, Event}, TransactionPayment: pallet_transaction_payment::{Module, Storage}, ParachainInfo: parachain_info::{Module, Storage, Config}, } diff --git a/rococo-parachains/src/chain_spec.rs b/rococo-parachains/src/chain_spec.rs index 00e01eacd0..33ca40210f 100644 --- a/rococo-parachains/src/chain_spec.rs +++ b/rococo-parachains/src/chain_spec.rs @@ -26,10 +26,6 @@ use sp_runtime::traits::{IdentifyAccount, Verify}; /// Specialized `ChainSpec` for the normal parachain runtime. pub type ChainSpec = sc_service::GenericChainSpec; -/// Specialized `ChainSpec` for the contracts parachain runtime. -pub type ContractsChainSpec = - sc_service::GenericChainSpec; - /// Helper function to generate a crypto pair from seed pub fn get_from_seed(seed: &str) -> ::Public { TPublic::Pair::from_string(&format!("//{}", seed), None) @@ -100,42 +96,6 @@ pub fn get_chain_spec(id: ParaId) -> ChainSpec { ) } -pub fn get_contracts_chain_spec(id: ParaId) -> ContractsChainSpec { - ContractsChainSpec::from_genesis( - "Contracts Local Testnet", - "contracts_local_testnet", - ChainType::Local, - move || { - contracts_testnet_genesis( - get_account_id_from_seed::("Alice"), - vec![ - get_account_id_from_seed::("Alice"), - get_account_id_from_seed::("Bob"), - get_account_id_from_seed::("Charlie"), - get_account_id_from_seed::("Dave"), - get_account_id_from_seed::("Eve"), - get_account_id_from_seed::("Ferdie"), - get_account_id_from_seed::("Alice//stash"), - get_account_id_from_seed::("Bob//stash"), - get_account_id_from_seed::("Charlie//stash"), - get_account_id_from_seed::("Dave//stash"), - get_account_id_from_seed::("Eve//stash"), - get_account_id_from_seed::("Ferdie//stash"), - ], - id, - ) - }, - vec![], - None, - None, - None, - Extensions { - relay_chain: "westend-dev".into(), - para_id: id.into(), - }, - ) -} - pub fn staging_test_net(id: ParaId) -> ChainSpec { ChainSpec::from_genesis( "Staging Testnet", @@ -184,28 +144,3 @@ fn testnet_genesis( parachain_info: Some(parachain_runtime::ParachainInfoConfig { parachain_id: id }), } } - -fn contracts_testnet_genesis( - root_key: AccountId, - endowed_accounts: Vec, - id: ParaId, -) -> parachain_contracts_runtime::GenesisConfig { - parachain_contracts_runtime::GenesisConfig { - frame_system: Some(parachain_contracts_runtime::SystemConfig { - code: parachain_contracts_runtime::WASM_BINARY - .expect("WASM binary was not build, please build it!") - .to_vec(), - changes_trie_config: Default::default(), - }), - pallet_balances: Some(parachain_contracts_runtime::BalancesConfig { - balances: endowed_accounts - .iter() - .cloned() - .map(|k| (k, 1 << 60)) - .collect(), - }), - pallet_sudo: Some(parachain_contracts_runtime::SudoConfig { key: root_key }), - parachain_info: Some(parachain_contracts_runtime::ParachainInfoConfig { parachain_id: id }), - cumulus_pallet_contracts: None, - } -} diff --git a/rococo-parachains/src/cli.rs b/rococo-parachains/src/cli.rs index fd033baa4b..da42862715 100644 --- a/rococo-parachains/src/cli.rs +++ b/rococo-parachains/src/cli.rs @@ -22,9 +22,6 @@ use structopt::StructOpt; /// Sub-commands supported by the collator. #[derive(Debug, StructOpt)] pub enum Subcommand { - #[structopt(flatten)] - Base(sc_cli::Subcommand), - /// Export the genesis state of the parachain. #[structopt(name = "export-genesis-state")] ExportGenesisState(ExportGenesisStateCommand), @@ -32,6 +29,27 @@ pub enum Subcommand { /// Export the genesis wasm of the parachain. #[structopt(name = "export-genesis-wasm")] ExportGenesisWasm(ExportGenesisWasmCommand), + + /// Build a chain specification. + BuildSpec(sc_cli::BuildSpecCmd), + + /// Validate blocks. + CheckBlock(sc_cli::CheckBlockCmd), + + /// Export blocks. + ExportBlocks(sc_cli::ExportBlocksCmd), + + /// Export the state of a given block into a chain spec. + ExportState(sc_cli::ExportStateCmd), + + /// Import blocks. + ImportBlocks(sc_cli::ImportBlocksCmd), + + /// Remove the whole chain. + PurgeChain(sc_cli::PurgeChainCmd), + + /// Revert the chain to a previous state. + Revert(sc_cli::RevertCmd), } /// Command for exporting the genesis state of the parachain diff --git a/rococo-parachains/src/command.rs b/rococo-parachains/src/command.rs index ea5d293668..73ef0641c5 100644 --- a/rococo-parachains/src/command.rs +++ b/rococo-parachains/src/command.rs @@ -27,10 +27,13 @@ use sc_cli::{ ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams, NetworkParams, Result, RuntimeVersion, SharedParams, SubstrateCli, }; -use sc_service::config::{BasePath, PrometheusConfig}; +use sc_service::{ + config::{BasePath, PrometheusConfig}, + PartialComponents, +}; use sp_core::hexdisplay::HexDisplay; use sp_runtime::traits::Block as BlockT; -use std::{io::Write, net::SocketAddr, sync::Arc}; +use std::{io::Write, net::SocketAddr}; fn load_spec( id: &str, @@ -47,7 +50,6 @@ fn load_spec( "track" => Ok(Box::new(chain_spec::ChainSpec::from_json_bytes( &include_bytes!("../res/track.json")[..], )?)), - "contracts" => Ok(Box::new(chain_spec::get_contracts_chain_spec(para_id))), "" => Ok(Box::new(chain_spec::get_chain_spec(para_id))), path => Ok(Box::new(chain_spec::ChainSpec::from_json_file( path.into(), @@ -143,50 +145,79 @@ fn extract_genesis_wasm(chain_spec: &Box) -> Result) -> bool { - chain_spec.id().starts_with("trick") || chain_spec.id().starts_with("contracts") -} - /// Parse command line arguments into service configuration. pub fn run() -> Result<()> { let cli = Cli::from_args(); match &cli.subcommand { - Some(Subcommand::Base(subcommand)) => { - let runner = cli.create_runner(subcommand)?; - - if use_contracts_runtime(&runner.config().chain_spec) { - runner.run_subcommand(subcommand, |mut config| { - let params = crate::service::new_partial::< - parachain_contracts_runtime::RuntimeApi, - crate::service::ContractsRuntimeExecutor, - >(&mut config)?; - - Ok(( - params.client, - params.backend, - params.import_queue, - params.task_manager, - )) - }) - } else { - runner.run_subcommand(subcommand, |mut config| { - let params = crate::service::new_partial::< - parachain_runtime::RuntimeApi, - crate::service::RuntimeExecutor, - >(&mut config)?; - - Ok(( - params.client, - params.backend, - params.import_queue, - params.task_manager, - )) - }) - } + Some(Subcommand::BuildSpec(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.sync_run(|config| cmd.run(config.chain_spec, config.network)) + } + Some(Subcommand::CheckBlock(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + let PartialComponents { + client, + task_manager, + import_queue, + .. + } = crate::service::new_partial(&config)?; + Ok((cmd.run(client, import_queue), task_manager)) + }) + } + Some(Subcommand::ExportBlocks(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + let PartialComponents { + client, + task_manager, + .. + } = crate::service::new_partial(&config)?; + Ok((cmd.run(client, config.database), task_manager)) + }) + } + Some(Subcommand::ExportState(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + let PartialComponents { + client, + task_manager, + .. + } = crate::service::new_partial(&config)?; + Ok((cmd.run(client, config.chain_spec), task_manager)) + }) + } + Some(Subcommand::ImportBlocks(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + let PartialComponents { + client, + task_manager, + import_queue, + .. + } = crate::service::new_partial(&config)?; + Ok((cmd.run(client, import_queue), task_manager)) + }) + } + Some(Subcommand::PurgeChain(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.sync_run(|config| cmd.run(config.database)) + } + Some(Subcommand::Revert(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + let PartialComponents { + client, + task_manager, + backend, + .. + } = crate::service::new_partial(&config)?; + Ok((cmd.run(client, backend), task_manager)) + }) } Some(Subcommand::ExportGenesisState(params)) => { - sc_cli::init_logger(""); + sc_cli::init_logger("", sc_tracing::TracingReceiver::Log, None)?; let block: Block = generate_genesis_block(&load_spec( ¶ms.chain.clone().unwrap_or_default(), @@ -203,7 +234,7 @@ pub fn run() -> Result<()> { Ok(()) } Some(Subcommand::ExportGenesisWasm(params)) => { - sc_cli::init_logger(""); + sc_cli::init_logger("", sc_tracing::TracingReceiver::Log, None)?; let wasm_file = extract_genesis_wasm(&cli.load_spec(¶ms.chain.clone().unwrap_or_default())?)?; @@ -219,9 +250,9 @@ pub fn run() -> Result<()> { None => { let runner = cli.create_runner(&*cli.run)?; - runner.run_node_until_exit(|config| { + runner.run_node_until_exit(|config| async move { // TODO - let key = Arc::new(sp_core::Pair::generate().0); + let key = sp_core::Pair::generate().0; let extension = chain_spec::Extensions::try_get(&config.chain_spec); let relay_chain_id = extension.map(|e| e.relay_chain.clone()); @@ -253,29 +284,11 @@ pub fn run() -> Result<()> { info!("Parachain id: {:?}", id); info!("Parachain Account: {}", parachain_account); info!("Parachain genesis state: {}", genesis_state); - info!( - "Is collating: {}", - if collator { "yes" } else { "no" } - ); + info!("Is collating: {}", if collator { "yes" } else { "no" }); - if use_contracts_runtime(&config.chain_spec) { - crate::service::start_contracts_node( - config, - key, - polkadot_config, - id, - collator, - ) - } else { - crate::service::start_node( - config, - key, - polkadot_config, - id, - collator, - ) + crate::service::start_node(config, key, polkadot_config, id, collator) + .await .map(|r| r.0) - } }) } } diff --git a/rococo-parachains/src/service.rs b/rococo-parachains/src/service.rs index 3fc8fa43ce..9a5602ff47 100644 --- a/rococo-parachains/src/service.rs +++ b/rococo-parachains/src/service.rs @@ -14,42 +14,34 @@ // You should have received a copy of the GNU General Public License // along with Cumulus. If not, see . -use ansi_term::Color; -use cumulus_network::DelayedBlockAnnounceValidator; +use cumulus_network::build_block_announce_validator; use cumulus_service::{ prepare_node_config, start_collator, start_full_node, StartCollatorParams, StartFullNodeParams, }; +use parachain_runtime::RuntimeApi; use polkadot_primitives::v0::CollatorPair; use rococo_parachain_primitives::Block; use sc_executor::native_executor_instance; pub use sc_executor::NativeExecutor; -use sc_informant::OutputFormat; use sc_service::{Configuration, PartialComponents, Role, TFullBackend, TFullClient, TaskManager}; -use sp_api::ConstructRuntimeApi; +use sp_core::Pair; use sp_runtime::traits::BlakeTwo256; use sp_trie::PrefixedMemoryDB; use std::sync::Arc; // Native executor instance. native_executor_instance!( - pub RuntimeExecutor, + pub Executor, parachain_runtime::api::dispatch, parachain_runtime::native_version, ); -// Native executor instance for the contracts runtime. -native_executor_instance!( - pub ContractsRuntimeExecutor, - parachain_contracts_runtime::api::dispatch, - parachain_contracts_runtime::native_version, -); - /// Starts a `ServiceBuilder` for a full service. /// /// Use this macro if you don't actually need the full service, but just the builder in order to /// be able to perform chain operations. -pub fn new_partial( - config: &mut Configuration, +pub fn new_partial( + config: &Configuration, ) -> Result< PartialComponents< TFullClient, @@ -60,27 +52,10 @@ pub fn new_partial( (), >, sc_service::Error, -> -where - RuntimeApi: ConstructRuntimeApi> - + Send - + Sync - + 'static, - RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue - + sp_api::Metadata - + sp_session::SessionKeys - + sp_api::ApiExt< - Block, - Error = sp_blockchain::Error, - StateBackend = sc_client_api::StateBackendFor, Block>, - > + sp_offchain::OffchainWorkerApi - + sp_block_builder::BlockBuilder, - sc_client_api::StateBackendFor, Block>: sp_api::StateBackend, - Executor: sc_executor::NativeExecutionDispatch + 'static, -{ +> { let inherent_data_providers = sp_inherents::InherentDataProviders::new(); - let (client, backend, keystore, task_manager) = + let (client, backend, keystore_container, task_manager) = sc_service::new_full_parts::(&config)?; let client = Arc::new(client); @@ -105,7 +80,7 @@ where backend, client, import_queue, - keystore, + keystore_container, task_manager, transaction_pool, inherent_data_providers, @@ -119,30 +94,15 @@ where /// Start a node with the given parachain `Configuration` and relay chain `Configuration`. /// /// This is the actual implementation that is abstract over the executor and the runtime api. -fn start_node_impl( +async fn start_node_impl( parachain_config: Configuration, - collator_key: Arc, - mut polkadot_config: polkadot_collator::Configuration, + collator_key: CollatorPair, + polkadot_config: Configuration, id: polkadot_primitives::v0::Id, validator: bool, rpc_ext_builder: RB, ) -> sc_service::error::Result<(TaskManager, Arc>)> where - RuntimeApi: ConstructRuntimeApi> - + Send - + Sync - + 'static, - RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue - + sp_api::Metadata - + sp_session::SessionKeys - + sp_api::ApiExt< - Block, - Error = sp_blockchain::Error, - StateBackend = sc_client_api::StateBackendFor, Block>, - > + sp_offchain::OffchainWorkerApi - + sp_block_builder::BlockBuilder, - sc_client_api::StateBackendFor, Block>: sp_api::StateBackend, - Executor: sc_executor::NativeExecutionDispatch + 'static, RB: Fn( Arc>, ) -> jsonrpc_core::IoHandler @@ -153,18 +113,12 @@ where return Err("Light client not supported!".into()); } - let mut parachain_config = prepare_node_config(parachain_config); + let parachain_config = prepare_node_config(parachain_config); - parachain_config.informant_output_format = OutputFormat { - enable_color: true, - prefix: format!("[{}] ", Color::Yellow.bold().paint("Parachain")), - }; - polkadot_config.informant_output_format = OutputFormat { - enable_color: true, - prefix: format!("[{}] ", Color::Blue.bold().paint("Relaychain")), - }; + let polkadot_full_node = + cumulus_service::build_polkadot_full_node(polkadot_config, collator_key.public())?; - let params = new_partial::(&mut parachain_config)?; + let params = new_partial(¶chain_config)?; params .inherent_data_providers .register_provider(sp_timestamp::InherentDataProvider) @@ -172,11 +126,11 @@ where let client = params.client.clone(); let backend = params.backend.clone(); - let block_announce_validator = DelayedBlockAnnounceValidator::new(); - let block_announce_validator_builder = { - let block_announce_validator = block_announce_validator.clone(); - move |_| Box::new(block_announce_validator) as Box<_> - }; + let block_announce_validator = build_block_announce_validator( + polkadot_full_node.client.clone(), + id, + Box::new(polkadot_full_node.network.clone()), + ); let prometheus_registry = parachain_config.prometheus_registry().cloned(); let transaction_pool = params.transaction_pool.clone(); @@ -190,16 +144,13 @@ where spawn_handle: task_manager.spawn_handle(), import_queue, on_demand: None, - block_announce_validator_builder: Some(Box::new(block_announce_validator_builder)), + block_announce_validator_builder: Some(Box::new(|_| block_announce_validator)), finality_proof_request_builder: None, finality_proof_provider: None, })?; - let rpc_extensions_builder = { - let client = client.clone(); - - Box::new(move |_deny_unsafe| rpc_ext_builder(client.clone())) - }; + let rpc_client = client.clone(); + let rpc_extensions_builder = Box::new(move |_, _| rpc_ext_builder(rpc_client.clone())); sc_service::spawn_tasks(sc_service::SpawnTasksParams { on_demand: None, @@ -210,8 +161,8 @@ where task_manager: &mut task_manager, telemetry_connection_sinks: Default::default(), config: parachain_config, - keystore: params.keystore, - backend, + keystore: params.keystore_container.sync_keystore(), + backend: backend.clone(), network: network.clone(), network_status_sinks, system_rpc_tx, @@ -224,10 +175,12 @@ where if validator { let proposer_factory = sc_basic_authorship::ProposerFactory::new( + task_manager.spawn_handle(), client.clone(), transaction_pool, prometheus_registry.as_ref(), ); + let spawner = task_manager.spawn_handle(); let params = StartCollatorParams { para_id: id, @@ -237,22 +190,21 @@ where block_status: client.clone(), announce_block, client: client.clone(), - block_announce_validator, task_manager: &mut task_manager, - polkadot_config, collator_key, + polkadot_full_node, + spawner, + backend, }; - start_collator(params)?; + start_collator(params).await?; } else { let params = StartFullNodeParams { client: client.clone(), announce_block, - polkadot_config, - collator_key, - block_announce_validator, task_manager: &mut task_manager, para_id: id, + polkadot_full_node, }; start_full_node(params)?; @@ -264,17 +216,14 @@ where } /// Start a normal parachain node. -pub fn start_node( +pub async fn start_node( parachain_config: Configuration, - collator_key: Arc, - polkadot_config: polkadot_collator::Configuration, + collator_key: CollatorPair, + polkadot_config: Configuration, id: polkadot_primitives::v0::Id, validator: bool, -) -> sc_service::error::Result<( - TaskManager, - Arc>, -)> { - start_node_impl::( +) -> sc_service::error::Result<(TaskManager, Arc>)> { + start_node_impl( parachain_config, collator_key, polkadot_config, @@ -282,29 +231,5 @@ pub fn start_node( validator, |_| Default::default(), ) -} - -/// Start a contracts parachain node. -pub fn start_contracts_node( - parachain_config: Configuration, - collator_key: Arc, - polkadot_config: polkadot_collator::Configuration, - id: polkadot_primitives::v0::Id, - validator: bool, -) -> sc_service::error::Result { - start_node_impl::( - parachain_config, - collator_key, - polkadot_config, - id, - validator, - |client| { - let mut io = jsonrpc_core::IoHandler::default(); - - use cumulus_pallet_contracts_rpc::{Contracts, ContractsApi}; - io.extend_with(ContractsApi::to_delegate(Contracts::new(client))); - io - }, - ) - .map(|r| r.0) + .await } diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 2490984ec6..2cfdb18e9e 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -15,28 +15,25 @@ trie-db = { version = "0.22.0", default-features = false } cumulus-primitives = { path = "../primitives", default-features = false } # Substrate dependencies -frame-executive = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-trie = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } +sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +frame-executive = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-trie = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } # Polkadot dependencies -parachain = { package = "polkadot-parachain", git = "https://github.com/paritytech/polkadot", branch = "rococo-branch", default-features = false, features = [ "wasm-api" ] } +parachain = { package = "polkadot-parachain", git = "https://github.com/paritytech/polkadot", default-features = false, features = [ "wasm-api" ] , branch = "bkchr-adder-collator-integration-test" } [dev-dependencies] -# Substrate dependencies -sc-block-builder = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-executor = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } - -# Cumulus dependencies -test-client = { package = "cumulus-test-client", path = "../test/client" } +sc-block-builder = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sc-client-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +cumulus-test-client = { path = "../test/client" } +env_logger = "0.7.1" [features] default = ["std"] diff --git a/runtime/src/validate_block/implementation.rs b/runtime/src/validate_block/implementation.rs index fbda7777c6..68d9da13e1 100644 --- a/runtime/src/validate_block/implementation.rs +++ b/runtime/src/validate_block/implementation.rs @@ -19,24 +19,22 @@ use frame_executive::ExecuteBlock; use sp_runtime::traits::{Block as BlockT, HashFor, Header as HeaderT}; -use sp_std::{boxed::Box, vec::Vec, collections::btree_map::BTreeMap, ops::Bound}; +use sp_std::{boxed::Box, collections::btree_map::BTreeMap, ops::Bound, vec::Vec}; use sp_trie::{delta_trie_root, read_trie_value, Layout, MemoryDB, StorageProof}; use hash_db::{HashDB, EMPTY_PREFIX}; -use trie_db::{TrieDB, TrieDBIterator, Trie, TrieError}; +use trie_db::{Trie, TrieDB, TrieDBIterator}; use parachain::primitives::{HeadData, ValidationCode, ValidationParams, ValidationResult}; use codec::{Decode, Encode, EncodeAppend}; use cumulus_primitives::{ - validation_function_params::ValidationFunctionParams, well_known_keys::{ - NEW_VALIDATION_CODE, PROCESSED_DOWNWARD_MESSAGES, UPWARD_MESSAGES, - VALIDATION_FUNCTION_PARAMS, + NEW_VALIDATION_CODE, PROCESSED_DOWNWARD_MESSAGES, UPWARD_MESSAGES, VALIDATION_DATA, }, - GenericUpwardMessage, + GenericUpwardMessage, ValidationData, }; /// Stores the global [`Storage`] instance. @@ -117,16 +115,13 @@ pub fn validate_block>(params: ValidationParams) - let block = B::new(block_data.header, block_data.extrinsics); assert!( parent_head.hash() == *block.header().parent_hash(), - "Invalid parent hash" + "Invalid parent hash", ); - // make a copy for later use - let validation_function_params = (¶ms).into(); - let storage_inner = WitnessStorage::::new( block_data.storage_proof, parent_head.state_root().clone(), - validation_function_params, + params, ) .expect("Witness data and storage root always match; qed"); @@ -153,9 +148,6 @@ pub fn validate_block>(params: ValidationParams) - // its scheduled upgrade so we can validate that block number later. let new_validation_code = with_storage(|storage| storage.modified(NEW_VALIDATION_CODE)).map(ValidationCode); - if new_validation_code.is_some() && validation_function_params.code_upgrade_allowed.is_none() { - panic!("Attempt to upgrade validation function when not permitted!"); - } // Extract potential upward messages from the storage. let upward_messages = match with_storage(|storage| storage.modified(UPWARD_MESSAGES)) { @@ -183,7 +175,7 @@ struct WitnessStorage { witness_data: MemoryDB>, overlay: BTreeMap, Option>>, storage_root: B::Hash, - params: ValidationFunctionParams, + validation_params: ValidationParams, } impl WitnessStorage { @@ -193,9 +185,9 @@ impl WitnessStorage { fn new( storage_proof: StorageProof, storage_root: B::Hash, - params: ValidationFunctionParams, + validation_params: ValidationParams, ) -> Result { - let mut db = storage_proof.into_memory_db(); + let db = storage_proof.into_memory_db(); if !HashDB::contains(&db, &storage_root, EMPTY_PREFIX) { return Err("Witness data does not contain given storage root."); @@ -205,7 +197,7 @@ impl WitnessStorage { witness_data: db, overlay: Default::default(), storage_root, - params, + validation_params, }) } @@ -238,41 +230,50 @@ impl WitnessStorage { /// Find the next storage key after the given `key` in the overlay. fn overlay_next_key(&self, key: &[u8]) -> Option<(&[u8], Option<&[u8]>)> { let range = (Bound::Excluded(key), Bound::Unbounded); - self.overlay.range::<[u8], _>(range).next().map(|(k, v)| (&k[..], v.as_deref())) + self.overlay + .range::<[u8], _>(range) + .next() + .map(|(k, v)| (&k[..], v.as_deref())) + } + + /// Checks that the encoded `ValidationData` in `data` is correct. + /// + /// Should be removed with: https://github.com/paritytech/cumulus/issues/217 + fn check_validation_data(&self, mut data: &[u8]) { + let validation_data = ValidationData::decode(&mut data).expect("Invalid `ValidationData`"); + + assert_eq!( + self.validation_params.parent_head, + validation_data.persisted.parent_head + ); + assert_eq!( + self.validation_params.relay_chain_height, + validation_data.persisted.block_number + ); + assert_eq!( + self.validation_params.hrmp_mqc_heads, + validation_data.persisted.hrmp_mqc_heads + ); } } impl Storage for WitnessStorage { fn modified(&self, key: &[u8]) -> Option> { - match key { - VALIDATION_FUNCTION_PARAMS => Some(self.params.encode()), - key => self - .overlay - .get(key) - .cloned() - .unwrap_or(None), - } + self.overlay.get(key).cloned().unwrap_or(None) } fn get(&self, key: &[u8]) -> Option> { - match key { - VALIDATION_FUNCTION_PARAMS => Some(self.params.encode()), - key => self - .overlay - .get(key) - .cloned() - .unwrap_or_else(|| { - read_trie_value::>, _>( - &self.witness_data, - &self.storage_root, - key, - ) - .expect("Reading key from trie.") - }) - } + self.overlay.get(key).cloned().unwrap_or_else(|| { + read_trie_value::>, _>(&self.witness_data, &self.storage_root, key) + .expect("Reading key from trie.") + }) } fn insert(&mut self, key: &[u8], value: &[u8]) { + if key == VALIDATION_DATA { + self.check_validation_data(value); + } + self.overlay.insert(key.to_vec(), Some(value.to_vec())); } @@ -339,13 +340,17 @@ impl Storage for WitnessStorage { let next_overlay_key = self.overlay_next_key(key); match (next_trie_key, next_overlay_key) { - (Some(backend_key), Some(overlay_key)) if &backend_key[..] < overlay_key.0 => Some(backend_key), + (Some(backend_key), Some(overlay_key)) if &backend_key[..] < overlay_key.0 => { + Some(backend_key) + } (backend_key, None) => backend_key, - (_, Some(overlay_key)) => if overlay_key.1.is_some() { - Some(overlay_key.0.to_vec()) - } else { - self.next_key(&overlay_key.0) - }, + (_, Some(overlay_key)) => { + if overlay_key.1.is_some() { + Some(overlay_key.0.to_vec()) + } else { + self.next_key(&overlay_key.0) + } + } } } } diff --git a/runtime/src/validate_block/tests.rs b/runtime/src/validate_block/tests.rs index db939ddd11..48420083d2 100644 --- a/runtime/src/validate_block/tests.rs +++ b/runtime/src/validate_block/tests.rs @@ -16,6 +16,13 @@ use crate::ParachainBlockData; +use cumulus_primitives::{PersistedValidationData, ValidationData}; +use cumulus_test_client::{ + generate_block_inherents, + runtime::{Block, Hash, Header, UncheckedExtrinsic, WASM_BINARY}, + transfer, Client, DefaultTestClientBuilderExt, LongestChain, TestClientBuilder, + TestClientBuilderExt, +}; use parachain::primitives::{BlockData, HeadData, ValidationParams, ValidationResult}; use sc_block_builder::BlockBuilderProvider; use sc_executor::{ @@ -30,12 +37,6 @@ use sp_runtime::{ generic::BlockId, traits::{Block as BlockT, Header as HeaderT}, }; -use test_client::{ - generate_block_inherents, - runtime::{Block, Hash, Header, UncheckedExtrinsic, WASM_BINARY}, - transfer, Client, DefaultTestClientBuilderExt, LongestChain, TestClientBuilder, - TestClientBuilderExt, -}; use codec::{Decode, Encode}; @@ -48,10 +49,9 @@ fn call_validate_block( let params = ValidationParams { block_data: BlockData(block_data.encode()), parent_head: HeadData(parent_head.encode()), - code_upgrade_allowed: None, - max_code_size: 1024, - max_head_data_size: 1024, relay_chain_height: 1, + hrmp_mqc_heads: Vec::new(), + dmq_mqc_head: Default::default(), } .encode(); @@ -86,15 +86,26 @@ fn create_test_client() -> (Client, LongestChain) { fn build_block_with_proof( client: &Client, extra_extrinsics: Vec, + parent_head: Header, ) -> (Block, sp_trie::StorageProof) { let block_id = BlockId::Hash(client.info().best_hash); let mut builder = client .new_block_at(&block_id, Default::default(), true) .expect("Initializes new block"); - generate_block_inherents(client) - .into_iter() - .for_each(|e| builder.push(e).expect("Pushes an inherent")); + generate_block_inherents( + client, + Some(ValidationData { + persisted: PersistedValidationData { + block_number: 1, + parent_head: parent_head.encode().into(), + ..Default::default() + }, + ..Default::default() + }), + ) + .into_iter() + .for_each(|e| builder.push(e).expect("Pushes an inherent")); extra_extrinsics .into_iter() @@ -112,9 +123,11 @@ fn build_block_with_proof( #[test] fn validate_block_no_extra_extrinsics() { + let _ = env_logger::try_init(); + let (client, longest_chain) = create_test_client(); let parent_head = longest_chain.best_chain().expect("Best block exists"); - let (block, witness_data) = build_block_with_proof(&client, vec![]); + let (block, witness_data) = build_block_with_proof(&client, vec![], parent_head.clone()); let (header, extrinsics) = block.deconstruct(); let block_data = ParachainBlockData::new(header.clone(), extrinsics, witness_data); @@ -125,6 +138,8 @@ fn validate_block_no_extra_extrinsics() { #[test] fn validate_block_with_extra_extrinsics() { + let _ = env_logger::try_init(); + let (client, longest_chain) = create_test_client(); let parent_head = longest_chain.best_chain().expect("Best block exists"); let extra_extrinsics = vec![ @@ -133,7 +148,8 @@ fn validate_block_with_extra_extrinsics() { transfer(&client, Charlie, Alice, 500), ]; - let (block, witness_data) = build_block_with_proof(&client, extra_extrinsics); + let (block, witness_data) = + build_block_with_proof(&client, extra_extrinsics, parent_head.clone()); let (header, extrinsics) = block.deconstruct(); let block_data = ParachainBlockData::new(header.clone(), extrinsics, witness_data); @@ -145,9 +161,11 @@ fn validate_block_with_extra_extrinsics() { #[test] #[should_panic(expected = "Calls `validate_block`: Other(\"Trap: Trap { kind: Unreachable }\")")] fn validate_block_invalid_parent_hash() { + let _ = env_logger::try_init(); + let (client, longest_chain) = create_test_client(); let parent_head = longest_chain.best_chain().expect("Best block exists"); - let (block, witness_data) = build_block_with_proof(&client, vec![]); + let (block, witness_data) = build_block_with_proof(&client, vec![], parent_head.clone()); let (mut header, extrinsics) = block.deconstruct(); header.set_parent_hash(Hash::from_low_u64_be(1)); diff --git a/service/Cargo.toml b/service/Cargo.toml index 4c520158ea..c3fb3e816a 100644 --- a/service/Cargo.toml +++ b/service/Cargo.toml @@ -9,19 +9,21 @@ edition = "2018" cumulus-consensus = { path = "../consensus" } cumulus-collator = { path = "../collator" } cumulus-primitives = { path = "../primitives" } -cumulus-network = { path = "../network" } # Substrate dependencies -sc-service = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-api = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" } # Polkadot dependencies -polkadot-collator = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } +polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-overseer = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } + +# Other deps +futures = "0.3.6" diff --git a/service/src/lib.rs b/service/src/lib.rs index 85336ec203..ff05137370 100644 --- a/service/src/lib.rs +++ b/service/src/lib.rs @@ -18,33 +18,37 @@ //! //! Provides functions for starting a collator node or a normal full node. -use cumulus_collator::CollatorBuilder; -use cumulus_network::{DelayedBlockAnnounceValidator, JustifiedBlockAnnounceValidator}; use cumulus_primitives::ParaId; -use polkadot_primitives::v0::{Block as PBlock, CollatorPair}; -use polkadot_service::{AbstractClient, ClientHandle, RuntimeApiCollection}; +use futures::{Future, FutureExt}; +use polkadot_overseer::OverseerHandler; +use polkadot_primitives::v1::{Block as PBlock, CollatorId, CollatorPair}; +use polkadot_service::{AbstractClient, Client as PClient, ClientHandle, RuntimeApiCollection}; use sc_client_api::{Backend as BackendT, BlockBackend, Finalizer, UsageProvider}; -use sc_service::{Configuration, Role, TaskManager}; -use sp_blockchain::{HeaderBackend, Result as ClientResult}; -use sp_consensus::{BlockImport, Environment, Error as ConsensusError, Proposer, SyncOracle}; -use sp_core::crypto::Pair; +use sc_service::{error::Result as ServiceResult, Configuration, Role, TaskManager}; +use sp_blockchain::HeaderBackend; +use sp_consensus::{BlockImport, Environment, Error as ConsensusError, Proposer}; +use sp_core::traits::SpawnNamed; use sp_inherents::InherentDataProviders; use sp_runtime::traits::{BlakeTwo256, Block as BlockT}; use std::{marker::PhantomData, sync::Arc}; +/// Polkadot full node handles. +type PFullNode = polkadot_service::NewFull; + /// Parameters given to [`start_collator`]. -pub struct StartCollatorParams<'a, Block: BlockT, PF, BI, BS, Client> { - pub para_id: ParaId, +pub struct StartCollatorParams<'a, Block: BlockT, PF, BI, BS, Client, Backend, Spawner, PClient> { pub proposer_factory: PF, pub inherent_data_providers: InherentDataProviders, + pub backend: Arc, pub block_import: BI, pub block_status: Arc, - pub announce_block: Arc) + Send + Sync>, pub client: Arc, - pub block_announce_validator: DelayedBlockAnnounceValidator, + pub announce_block: Arc) + Send + Sync>, + pub spawner: Spawner, + pub para_id: ParaId, + pub collator_key: CollatorPair, + pub polkadot_full_node: PFullNode, pub task_manager: &'a mut TaskManager, - pub polkadot_config: Configuration, - pub collator_key: Arc, } /// Start a collator node for a parachain. @@ -52,20 +56,21 @@ pub struct StartCollatorParams<'a, Block: BlockT, PF, BI, BS, Client> { /// A collator is similar to a validator in a normal blockchain. /// It is responsible for producing blocks and sending the blocks to a /// parachain validator for validation and inclusion into the relay chain. -pub fn start_collator<'a, Block, PF, BI, BS, Client, Backend>( +pub async fn start_collator<'a, Block, PF, BI, BS, Client, Backend, Spawner, PClient>( StartCollatorParams { - para_id, proposer_factory, inherent_data_providers, + backend, block_import, block_status, - announce_block, client, - block_announce_validator, - task_manager, - polkadot_config, + announce_block, + spawner, + para_id, collator_key, - }: StartCollatorParams<'a, Block, PF, BI, BS, Client>, + polkadot_full_node, + task_manager, + }: StartCollatorParams<'a, Block, PF, BI, BS, Client, Backend, Spawner, PClient>, ) -> sc_service::error::Result<()> where Block: BlockT, @@ -87,55 +92,124 @@ where + 'static, for<'b> &'b Client: BlockImport, Backend: BackendT + 'static, + Spawner: SpawnNamed + Clone + Send + Sync + 'static, + PClient: ClientHandle, { - let builder = CollatorBuilder::new( - proposer_factory, - inherent_data_providers, - block_import, - block_status, - para_id, - client, - announce_block, - block_announce_validator, - ); + polkadot_full_node + .client + .execute_with(StartCollator { + proposer_factory, + inherent_data_providers, + backend, + client, + announce_block, + overseer_handler: polkadot_full_node + .overseer_handler + .ok_or_else(|| "Polkadot full node did not provided an `OverseerHandler`!")?, + spawner, + para_id, + collator_key, + block_import, + block_status, + }) + .await?; - let (polkadot_future, polkadot_task_manager) = - polkadot_collator::start_collator(builder, para_id, collator_key, polkadot_config)?; - - task_manager - .spawn_essential_handle() - .spawn("polkadot", polkadot_future); - - task_manager.add_child(polkadot_task_manager); + task_manager.add_child(polkadot_full_node.task_manager); Ok(()) } +struct StartCollator { + proposer_factory: PF, + inherent_data_providers: InherentDataProviders, + backend: Arc, + block_import: BI, + block_status: Arc, + client: Arc, + announce_block: Arc) + Send + Sync>, + overseer_handler: OverseerHandler, + spawner: Spawner, + para_id: ParaId, + collator_key: CollatorPair, +} + +impl polkadot_service::ExecuteWithClient + for StartCollator +where + Block: BlockT, + PF: Environment + Send + 'static, + BI: BlockImport< + Block, + Error = ConsensusError, + Transaction = >::Transaction, + > + Send + + Sync + + 'static, + BS: BlockBackend + Send + Sync + 'static, + Client: Finalizer + + UsageProvider + + HeaderBackend + + Send + + Sync + + BlockBackend + + 'static, + for<'b> &'b Client: BlockImport, + Backend: BackendT + 'static, + Spawner: SpawnNamed + Clone + Send + Sync + 'static, +{ + type Output = std::pin::Pin>>>; + + fn execute_with_client(self, client: Arc) -> Self::Output + where + >::StateBackend: sp_api::StateBackend, + PBackend: sc_client_api::Backend, + PBackend::State: sp_api::StateBackend, + Api: RuntimeApiCollection, + PClient: AbstractClient + 'static, + { + async move { + cumulus_collator::start_collator(cumulus_collator::StartCollatorParams { + proposer_factory: self.proposer_factory, + inherent_data_providers: self.inherent_data_providers, + backend: self.backend, + block_import: self.block_import, + block_status: self.block_status, + client: self.client, + announce_block: self.announce_block, + overseer_handler: self.overseer_handler, + spawner: self.spawner, + para_id: self.para_id, + key: self.collator_key, + polkadot_client: client, + }) + .await + .map_err(Into::into) + } + .boxed() + } +} + /// Parameters given to [`start_full_node`]. -pub struct StartFullNodeParams<'a, Block: BlockT, Client> { - pub polkadot_config: Configuration, - pub collator_key: Arc, +pub struct StartFullNodeParams<'a, Block: BlockT, Client, PClient> { pub para_id: ParaId, - pub block_announce_validator: DelayedBlockAnnounceValidator, pub client: Arc, - pub announce_block: Arc) + Send + Sync>, + pub polkadot_full_node: PFullNode, pub task_manager: &'a mut TaskManager, + pub announce_block: Arc) + Send + Sync>, } /// Start a full node for a parachain. /// /// A full node will only sync the given parachain and will follow the /// tip of the chain. -pub fn start_full_node( +pub fn start_full_node( StartFullNodeParams { - polkadot_config, - collator_key, - para_id, - block_announce_validator, client, announce_block, task_manager, - }: StartFullNodeParams, + polkadot_full_node, + para_id, + }: StartFullNodeParams, ) -> sc_service::error::Result<()> where Block: BlockT, @@ -147,54 +221,23 @@ where + 'static, for<'a> &'a Client: BlockImport, Backend: BackendT + 'static, + PClient: ClientHandle, { - let is_light = matches!(polkadot_config.role, Role::Light); - let (polkadot_task_manager, pclient, handles) = if is_light { - Err("Light client not supported.".into()) - } else { - polkadot_service::build_full( - polkadot_config, - Some((collator_key.public(), para_id)), - None, - false, - 6000, - None, - ) - }?; - - let polkadot_network = handles - .polkadot_network - .expect("Polkadot service is started; qed"); - - pclient.execute_with(InitParachainFullNode { - block_announce_validator, - para_id, - polkadot_sync_oracle: Box::new(polkadot_network), + polkadot_full_node.client.execute_with(StartFullNode { announce_block, + para_id, client, task_manager, _phantom: PhantomData, })?; - task_manager.add_child(polkadot_task_manager); + task_manager.add_child(polkadot_full_node.task_manager); Ok(()) } -/// Prepare the parachain's node condifugration -/// -/// This function will disable the default announcement of Substrate for the parachain in favor -/// of the one of Cumulus. -pub fn prepare_node_config(mut parachain_config: Configuration) -> Configuration { - parachain_config.announce_block = false; - - parachain_config -} - -struct InitParachainFullNode<'a, Block: BlockT, Client, Backend> { - block_announce_validator: DelayedBlockAnnounceValidator, +struct StartFullNode<'a, Block: BlockT, Client, Backend> { para_id: ParaId, - polkadot_sync_oracle: Box, announce_block: Arc) + Send + Sync>, client: Arc, task_manager: &'a mut TaskManager, @@ -202,7 +245,7 @@ struct InitParachainFullNode<'a, Block: BlockT, Client, Backend> { } impl<'a, Block, Client, Backend> polkadot_service::ExecuteWithClient - for InitParachainFullNode<'a, Block, Client, Backend> + for StartFullNode<'a, Block, Client, Backend> where Block: BlockT, Client: Finalizer @@ -214,7 +257,7 @@ where for<'b> &'b Client: BlockImport, Backend: BackendT + 'static, { - type Output = ClientResult<()>; + type Output = ServiceResult<()>; fn execute_with_client(self, client: Arc) -> Self::Output where @@ -224,13 +267,6 @@ where Api: RuntimeApiCollection, PClient: AbstractClient + 'static, { - self.block_announce_validator - .set(Box::new(JustifiedBlockAnnounceValidator::new( - client.clone(), - self.para_id, - self.polkadot_sync_oracle, - ))); - let future = cumulus_consensus::follow_polkadot( self.para_id, self.client, @@ -244,3 +280,31 @@ where Ok(()) } } + +/// Prepare the parachain's node condifugration +/// +/// This function will disable the default announcement of Substrate for the parachain in favor +/// of the one of Cumulus. +pub fn prepare_node_config(mut parachain_config: Configuration) -> Configuration { + parachain_config.announce_block = false; + + parachain_config +} + +/// Build the Polkadot full node using the given `config`. +pub fn build_polkadot_full_node( + config: Configuration, + collator_id: CollatorId, +) -> sc_service::error::Result> { + let is_light = matches!(config.role, Role::Light); + if is_light { + Err("Light client not supported.".into()) + } else { + polkadot_service::build_full( + config, + polkadot_service::IsCollator::Yes(collator_id), + None, + None, + ) + } +} diff --git a/test/client/Cargo.toml b/test/client/Cargo.toml index a57aaf6f0c..78ade9f1b0 100644 --- a/test/client/Cargo.toml +++ b/test/client/Cargo.toml @@ -5,25 +5,29 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -sc-service = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -test-client = { package = "substrate-test-client", git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -codec = { package = "parity-scale-codec", version = "1.0.5", default-features = false, features = [ "derive" ] } -sp-test-primitives = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-api = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-balances = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } +substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-test-primitives = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master" } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" } -# Cumulus dependencies +# Cumulus deps +cumulus-test-runtime = { path = "../runtime" } cumulus-test-service = { path = "../service" } cumulus-primitives = { path = "../../primitives" } -runtime = { package = "cumulus-test-runtime", path = "../runtime" } + +# Polkadot deps +polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } + +# Other deps +codec = { package = "parity-scale-codec", version = "1.0.5", default-features = false, features = [ "derive" ] } diff --git a/test/client/src/block_builder.rs b/test/client/src/block_builder.rs index 09d50e2ce9..841358aaec 100644 --- a/test/client/src/block_builder.rs +++ b/test/client/src/block_builder.rs @@ -15,34 +15,39 @@ // along with Cumulus. If not, see . use crate::Client; -use cumulus_primitives::{ - inherents::VALIDATION_FUNCTION_PARAMS_IDENTIFIER, - validation_function_params::ValidationFunctionParams, -}; -use runtime::GetLastTimestamp; +use cumulus_primitives::{inherents::VALIDATION_DATA_IDENTIFIER, ValidationData}; +use cumulus_test_runtime::GetLastTimestamp; +use polkadot_primitives::v1::BlockNumber as PBlockNumber; use sc_block_builder::BlockBuilderApi; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_core::ExecutionContext; use sp_runtime::generic::BlockId; -/// Generate the inherents to a block so you don't have to. -pub fn generate_block_inherents(client: &Client) -> Vec { - let mut inherent_data = sp_consensus::InherentData::new(); +/// Generate the inherents required by the test runtime. +/// +/// - `validation_data`: The [`ValidationData`] that will be passed as inherent +/// data into the runtime when building the inherents. If +/// `None` is passed, the default value will be used. +pub fn generate_block_inherents( + client: &Client, + validation_data: Option>, +) -> Vec { + let mut inherent_data = sp_inherents::InherentData::new(); let block_id = BlockId::Hash(client.info().best_hash); let last_timestamp = client .runtime_api() .get_last_timestamp(&block_id) .expect("Get last timestamp"); - let timestamp = last_timestamp + runtime::MinimumPeriod::get(); + let timestamp = last_timestamp + cumulus_test_runtime::MinimumPeriod::get(); inherent_data .put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp) .expect("Put timestamp failed"); inherent_data .put_data( - VALIDATION_FUNCTION_PARAMS_IDENTIFIER, - &ValidationFunctionParams::default(), + VALIDATION_DATA_IDENTIFIER, + &validation_data.unwrap_or_default(), ) .expect("Put validation function params failed"); diff --git a/test/client/src/lib.rs b/test/client/src/lib.rs index 9f22b3a6df..aea06be84a 100644 --- a/test/client/src/lib.rs +++ b/test/client/src/lib.rs @@ -21,7 +21,7 @@ mod block_builder; pub use block_builder::*; use codec::Encode; -pub use runtime; +pub use cumulus_test_runtime as runtime; use runtime::{ Balance, Block, BlockHashCount, Call, GenesisConfig, Runtime, Signature, SignedExtra, SignedPayload, UncheckedExtrinsic, VERSION, @@ -35,14 +35,14 @@ use sp_runtime::{ BuildStorage, SaturatedConversion, }; use std::collections::BTreeMap; -pub use test_client::*; +pub use substrate_test_client::*; mod local_executor { - use test_client::sc_executor::native_executor_instance; + use substrate_test_client::sc_executor::native_executor_instance; native_executor_instance!( pub LocalExecutor, - runtime::api::dispatch, - runtime::native_version, + cumulus_test_runtime::api::dispatch, + cumulus_test_runtime::native_version, ); } @@ -50,14 +50,14 @@ mod local_executor { pub use local_executor::LocalExecutor; /// Test client database backend. -pub type Backend = test_client::Backend; +pub type Backend = substrate_test_client::Backend; /// Test client executor. pub type Executor = client::LocalCallExecutor>; /// Test client builder for Cumulus pub type TestClientBuilder = - test_client::TestClientBuilder; + substrate_test_client::TestClientBuilder; /// LongestChain type for the test runtime/client. pub type LongestChain = sc_consensus::LongestChain; @@ -71,7 +71,7 @@ pub struct GenesisParameters { support_changes_trie: bool, } -impl test_client::GenesisInit for GenesisParameters { +impl substrate_test_client::GenesisInit for GenesisParameters { fn genesis_storage(&self) -> Storage { let changes_trie_config: Option = if self.support_changes_trie { Some(sp_test_primitives::changes_trie_config()) diff --git a/test/runtime/Cargo.toml b/test/runtime/Cargo.toml index 08ac1fa1f8..4ec03e2266 100644 --- a/test/runtime/Cargo.toml +++ b/test/runtime/Cargo.toml @@ -9,37 +9,36 @@ codec = { package = "parity-scale-codec", version = "1.3.0", default-features = serde = { version = "1.0.101", optional = true, features = ["derive"] } # Substrate dependencies -frame-executive = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-balances = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-sudo = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-block-builder = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-inherents = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-offchain = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-session = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-transaction-pool = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-version = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } +frame-executive = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +pallet-balances = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +pallet-sudo = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-block-builder = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-inherents = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-offchain = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-session = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-transaction-pool = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-version = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } # Cumulus dependencies cumulus-parachain-upgrade = { path = "../../parachain-upgrade", default-features = false } cumulus-primitives = { path = "../../primitives", default-features = false } cumulus-runtime = { path = "../../runtime", default-features = false } -cumulus-upward-message = { path = "../../upward-message", default-features = false } # Polkadot dependencies -polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch", default-features = false } +polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false , branch = "bkchr-adder-collator-integration-test" } [build-dependencies] -wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.6" } +wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "2.0.0" } [features] default = [ "std" ] @@ -48,7 +47,6 @@ std = [ "cumulus-parachain-upgrade/std", "cumulus-primitives/std", "cumulus-runtime/std", - "cumulus-upward-message/std", "frame-executive/std", "frame-support/std", "frame-system/std", @@ -70,7 +68,3 @@ std = [ "sp-transaction-pool/std", "sp-version/std", ] -# Will be enabled by the `wasm-builder` when building the runtime for WASM. -runtime-wasm = [ - "cumulus-upward-message/runtime-wasm", -] diff --git a/test/runtime/src/lib.rs b/test/runtime/src/lib.rs index bb9c298213..ce34d08e61 100644 --- a/test/runtime/src/lib.rs +++ b/test/runtime/src/lib.rs @@ -131,8 +131,7 @@ impl frame_system::Trait for Runtime { type AvailableBlockRatio = AvailableBlockRatio; /// Runtime version. type Version = Version; - /// Converts a module to an index of this module in the runtime. - type ModuleToIndex = ModuleToIndex; + type PalletInfo = PalletInfo; type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); @@ -172,11 +171,11 @@ impl pallet_balances::Trait for Runtime { type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; type WeightInfo = (); + type MaxLocks = (); } impl pallet_transaction_payment::Trait for Runtime { - type Currency = Balances; - type OnTransactionPayment = (); + type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; type TransactionByteFee = TransactionByteFee; type WeightToFee = IdentityFee; type FeeMultiplierUpdate = (); @@ -189,7 +188,7 @@ impl pallet_sudo::Trait for Runtime { impl cumulus_parachain_upgrade::Trait for Runtime { type Event = Event; - type OnValidationFunctionParams = (); + type OnValidationData = (); } parameter_types! { diff --git a/test/service/Cargo.toml b/test/service/Cargo.toml index a6ae3913d3..704c1dd880 100644 --- a/test/service/Cargo.toml +++ b/test/service/Cargo.toml @@ -1,48 +1,47 @@ [package] -name = 'cumulus-test-service' +name = "cumulus-test-service" version = '0.1.0' authors = ["Parity Technologies "] edition = '2018' [dependencies] -ansi_term = "0.12.1" codec = { package = 'parity-scale-codec', version = '1.0.0' } rand = "0.7.3" serde = { version = "1.0.101", features = ["derive"] } # Substrate -sc-basic-authorship = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", version = "0.8.0-rc5" } -sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-executor = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-informant = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-network = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-service = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-api = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-branch" } -sp-session = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -sp-trie = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } +sc-basic-authorship = { git = "https://github.com/paritytech/substrate", version = "0.8.0-rc5" , branch = "master" } +sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" } +substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "master" } # Polkadot -polkadot-collator = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-test-service = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } +polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-test-service = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-overseer = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } # Cumulus -cumulus-collator = { path = "../../collator" } cumulus-consensus = { path = "../../consensus" } cumulus-network = { path = "../../network" } cumulus-primitives = { path = "../../primitives" } @@ -50,17 +49,18 @@ cumulus-service = { path = "../../service" } cumulus-test-runtime = { path = "../runtime" } # RPC related dependencies -jsonrpc-core = "14.2.0" +jsonrpc-core = "15.1.0" [dev-dependencies] futures = { version = "0.3.5" } tokio = { version = "0.2.21", features = ["macros"] } # Polkadot dependencies -polkadot-test-runtime = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } -polkadot-test-service = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch" } +polkadot-test-runtime = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } +polkadot-test-service = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-adder-collator-integration-test" } # Substrate dependencies -pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -substrate-test-runtime-client = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } -substrate-test-utils = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch" } +pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "master" } +substrate-test-runtime-client = { git = "https://github.com/paritytech/substrate", branch = "master" } +substrate-test-utils = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/test/service/src/lib.rs b/test/service/src/lib.rs index 766d78a389..0bddab7fb6 100644 --- a/test/service/src/lib.rs +++ b/test/service/src/lib.rs @@ -24,21 +24,17 @@ mod genesis; pub use chain_spec::*; pub use genesis::*; -use ansi_term::Color; use core::future::Future; -use cumulus_collator::CollatorBuilder; -use cumulus_network::DelayedBlockAnnounceValidator; +use cumulus_network::BlockAnnounceValidator; use cumulus_primitives::ParaId; use cumulus_service::{ - prepare_node_config, start_full_node, StartCollatorParams, StartFullNodeParams, + prepare_node_config, start_collator, start_full_node, StartCollatorParams, StartFullNodeParams, }; use cumulus_test_runtime::{NodeBlock as Block, RuntimeApi}; -use polkadot_primitives::v0::CollatorPair; +use polkadot_primitives::v1::CollatorPair; use sc_client_api::execution_extensions::ExecutionStrategies; -use sc_client_api::BlockBackend; use sc_executor::native_executor_instance; pub use sc_executor::NativeExecutor; -use sc_informant::OutputFormat; use sc_network::{config::TransportConfig, multiaddr, NetworkService}; use sc_service::{ config::{ @@ -48,8 +44,7 @@ use sc_service::{ BasePath, ChainSpec, Configuration, Error as ServiceError, PartialComponents, Role, RpcHandlers, TFullBackend, TFullClient, TaskExecutor, TaskManager, }; -use sp_consensus::{BlockImport, Environment, Error as ConsensusError, Proposer}; -use sp_core::{crypto::Pair, H256}; +use sp_core::{Pair, H256}; use sp_keyring::Sr25519Keyring; use sp_runtime::traits::BlakeTwo256; use sp_state_machine::BasicExternalities; @@ -83,7 +78,7 @@ pub fn new_partial( > { let inherent_data_providers = sp_inherents::InherentDataProviders::new(); - let (client, backend, keystore, task_manager) = + let (client, backend, keystore_container, task_manager) = sc_service::new_full_parts::(&config)?; let client = Arc::new(client); @@ -108,7 +103,7 @@ pub fn new_partial( backend, client, import_queue, - keystore, + keystore_container, task_manager, transaction_pool, inherent_data_providers, @@ -119,96 +114,22 @@ pub fn new_partial( Ok(params) } -/// Start a test collator node for a parachain. -/// -/// A collator is similar to a validator in a normal blockchain. -/// It is responsible for producing blocks and sending the blocks to a -/// parachain validator for validation and inclusion into the relay chain. -pub fn start_test_collator<'a, PF, BI, BS>( - StartCollatorParams { - para_id, - proposer_factory, - inherent_data_providers, - block_import, - block_status, - announce_block, - client, - block_announce_validator, - task_manager, - polkadot_config, - collator_key, - }: StartCollatorParams<'a, Block, PF, BI, BS, TFullClient>, -) -> sc_service::error::Result<()> -where - PF: Environment + Send + 'static, - BI: BlockImport< - Block, - Error = ConsensusError, - Transaction = >::Transaction, - > + Send - + Sync - + 'static, - BS: BlockBackend + Send + Sync + 'static, -{ - let builder = CollatorBuilder::new( - proposer_factory, - inherent_data_providers, - block_import, - block_status, - para_id, - client, - announce_block, - block_announce_validator, - ); - - let (polkadot_future, polkadot_task_manager) = { - let (task_manager, client, handles, _network, _rpc_handlers) = - polkadot_test_service::polkadot_test_new_full( - polkadot_config, - Some((collator_key.public(), para_id)), - None, - false, - 6000, - )?; - - let test_client = polkadot_test_service::TestClient(client); - - let future = polkadot_collator::build_collator_service( - task_manager.spawn_handle(), - handles, - test_client, - para_id, - collator_key, - builder, - )?; - - (future, task_manager) - }; - - task_manager - .spawn_essential_handle() - .spawn("polkadot", polkadot_future); - - task_manager.add_child(polkadot_task_manager); - - Ok(()) -} - /// Start a node with the given parachain `Configuration` and relay chain `Configuration`. /// /// This is the actual implementation that is abstract over the executor and the runtime api. -fn start_node_impl( +#[sc_cli::prefix_logs_with(parachain_config.network.node_name.as_str())] +async fn start_node_impl( parachain_config: Configuration, - collator_key: Arc, - mut polkadot_config: polkadot_collator::Configuration, + collator_key: CollatorPair, + polkadot_config: Configuration, para_id: ParaId, - validator: bool, + is_collator: bool, rpc_ext_builder: RB, ) -> sc_service::error::Result<( TaskManager, Arc>, Arc>, - Arc, + RpcHandlers, )> where RB: Fn( @@ -223,32 +144,30 @@ where let mut parachain_config = prepare_node_config(parachain_config); - parachain_config.informant_output_format = OutputFormat { - enable_color: true, - prefix: format!("[{}] ", Color::Yellow.bold().paint("Parachain")), - }; - polkadot_config.informant_output_format = OutputFormat { - enable_color: true, - prefix: format!("[{}] ", Color::Blue.bold().paint("Relaychain")), - }; - let params = new_partial(&mut parachain_config)?; params .inherent_data_providers .register_provider(sp_timestamp::InherentDataProvider) - .unwrap(); + .expect("Registers timestamp inherent data provider."); + + let transaction_pool = params.transaction_pool.clone(); + let mut task_manager = params.task_manager; + + let polkadot_full_node = polkadot_test_service::new_full( + polkadot_config, + polkadot_service::IsCollator::Yes(collator_key.public()), + )?; let client = params.client.clone(); let backend = params.backend.clone(); - let block_announce_validator = DelayedBlockAnnounceValidator::new(); - let block_announce_validator_builder = { - let block_announce_validator = block_announce_validator.clone(); - move |_| Box::new(block_announce_validator) as Box<_> - }; + let block_announce_validator = BlockAnnounceValidator::new( + polkadot_full_node.client.clone(), + para_id, + Box::new(polkadot_full_node.network.clone()), + ); + let block_announce_validator_builder = move |_| Box::new(block_announce_validator) as Box<_>; let prometheus_registry = parachain_config.prometheus_registry().cloned(); - let transaction_pool = params.transaction_pool.clone(); - let mut task_manager = params.task_manager; let import_queue = params.import_queue; let (network, network_status_sinks, system_rpc_tx, start_network) = sc_service::build_network(sc_service::BuildNetworkParams { @@ -266,7 +185,7 @@ where let rpc_extensions_builder = { let client = client.clone(); - Box::new(move |_deny_unsafe| rpc_ext_builder(client.clone())) + Box::new(move |_, _| rpc_ext_builder(client.clone())) }; let rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams { @@ -278,7 +197,7 @@ where task_manager: &mut task_manager, telemetry_connection_sinks: Default::default(), config: parachain_config, - keystore: params.keystore, + keystore: params.keystore_container.sync_keystore(), backend, network: network.clone(), network_status_sinks, @@ -290,37 +209,38 @@ where Arc::new(move |hash, data| network.announce_block(hash, data)) }; - if validator { + let polkadot_full_node = polkadot_full_node.with_client(polkadot_test_service::TestClient); + if is_collator { let proposer_factory = sc_basic_authorship::ProposerFactory::new( + task_manager.spawn_handle(), client.clone(), transaction_pool, prometheus_registry.as_ref(), ); let params = StartCollatorParams { - para_id, - block_import: client.clone(), proposer_factory, inherent_data_providers: params.inherent_data_providers, + backend: params.backend, + block_import: client.clone(), block_status: client.clone(), announce_block, client: client.clone(), - block_announce_validator, + spawner: task_manager.spawn_handle(), task_manager: &mut task_manager, - polkadot_config, + para_id, collator_key, + polkadot_full_node, }; - start_test_collator(params)?; + start_collator(params).await?; } else { let params = StartFullNodeParams { client: client.clone(), announce_block, - polkadot_config, - collator_key, - block_announce_validator, task_manager: &mut task_manager, para_id, + polkadot_full_node, }; start_full_node(params)?; @@ -343,14 +263,14 @@ pub struct CumulusTestNode { /// to other nodes. pub addr: MultiaddrWithPeerId, /// RPCHandlers to make RPC queries. - pub rpc_handlers: Arc, + pub rpc_handlers: RpcHandlers, } /// Run a Cumulus test node using the Cumulus test runtime. The node will be using an in-memory /// socket, therefore you need to provide boot nodes if you want it to be connected to other nodes. /// The `storage_update_func` can be used to make adjustements to the runtime before the node /// starts. -pub fn run_test_node( +pub async fn run_test_node( task_executor: TaskExecutor, key: Sr25519Keyring, parachain_storage_update_func: impl Fn(), @@ -358,32 +278,39 @@ pub fn run_test_node( parachain_boot_nodes: Vec, polkadot_boot_nodes: Vec, para_id: ParaId, - validator: bool, + is_collator: bool, ) -> CumulusTestNode { - let collator_key = Arc::new(sp_core::Pair::generate().0); + let collator_key = CollatorPair::generate().0; let parachain_config = node_config( parachain_storage_update_func, task_executor.clone(), key, parachain_boot_nodes, para_id, + is_collator, ) .expect("could not generate Configuration"); - let polkadot_config = polkadot_test_service::node_config( + let mut polkadot_config = polkadot_test_service::node_config( polkadot_storage_update_func, task_executor.clone(), key, polkadot_boot_nodes, + false, ); + + polkadot_config.network.node_name = + format!("{} (relay chain)", polkadot_config.network.node_name); + let multiaddr = parachain_config.network.listen_addresses[0].clone(); - let (task_manager, client, network, rpc_handlers) = start_node_impl::<_>( + let (task_manager, client, network, rpc_handlers) = start_node_impl( parachain_config, collator_key, polkadot_config, para_id, - validator, + is_collator, |_| Default::default(), ) + .await .expect("could not create Cumulus test service"); let peer_id = network.local_peer_id().clone(); @@ -407,11 +334,16 @@ pub fn node_config( key: Sr25519Keyring, boot_nodes: Vec, para_id: ParaId, + is_collator: bool, ) -> Result { let base_path = BasePath::new_temp_dir()?; let root = base_path.path().to_path_buf(); - let role = Role::Authority { - sentry_nodes: Vec::new(), + let role = if is_collator { + Role::Authority { + sentry_nodes: Vec::new(), + } + } else { + Role::Full }; let key_seed = key.to_seed(); let mut spec = Box::new(chain_spec::get_chain_spec(para_id)); @@ -425,19 +357,15 @@ pub fn node_config( spec.set_storage(storage); let mut network_config = NetworkConfiguration::new( - format!("Cumulus Test Node for: {}", key_seed), + format!("{} (parachain)", key_seed.to_string()), "network/test/0.1", Default::default(), None, ); - let informant_output_format = OutputFormat { - enable_color: false, - prefix: format!("[{}] ", key_seed), - }; network_config.boot_nodes = boot_nodes; - network_config.allow_non_globals_in_dht = false; + network_config.allow_non_globals_in_dht = true; network_config .listen_addresses @@ -452,10 +380,7 @@ pub fn node_config( task_executor, transaction_pool: Default::default(), network: network_config, - keystore: KeystoreConfig::Path { - path: root.join("key"), - password: None, - }, + keystore: KeystoreConfig::InMemory, database: DatabaseConfig::RocksDb { path: root.join("db"), cache_size: 128, @@ -495,7 +420,8 @@ pub fn node_config( max_runtime_instances: 8, announce_block: true, base_path: Some(base_path), - informant_output_format, + informant_output_format: Default::default(), + wasm_runtime_overrides: None, }) } diff --git a/test/service/tests/integration.rs b/test/service/tests/integration.rs index e3ef7878b1..9b7e9e8fb6 100644 --- a/test/service/tests/integration.rs +++ b/test/service/tests/integration.rs @@ -21,38 +21,35 @@ use sc_service::TaskExecutor; use substrate_test_runtime_client::AccountKeyring::*; #[substrate_test_utils::test] -#[ignore] async fn test_collating_and_non_collator_mode_catching_up(task_executor: TaskExecutor) { + sc_cli::init_logger("", Default::default(), None).expect("Sets up logger"); + let para_id = ParaId::from(100); // start alice - let alice = polkadot_test_service::run_test_node(task_executor.clone(), Alice, || {}, vec![]); + let alice = polkadot_test_service::run_validator_node(task_executor.clone(), Alice, || {}, vec![]); // start bob - let bob = polkadot_test_service::run_test_node( + let bob = polkadot_test_service::run_validator_node( task_executor.clone(), Bob, || {}, vec![alice.addr.clone()], ); - // ensure alice and bob can produce blocks - join!(alice.wait_for_blocks(2), bob.wait_for_blocks(2)); - // register parachain alice - .register_para( + .register_parachain( para_id, cumulus_test_runtime::WASM_BINARY .expect("You need to build the WASM binary to run this test!") - .to_vec() - .into(), + .to_vec(), initial_head_data(para_id), ) .await .unwrap(); - // run cumulus charlie (a validator) + // run cumulus charlie (a parachain collator) let charlie = cumulus_test_service::run_test_node( task_executor.clone(), Charlie, @@ -62,29 +59,31 @@ async fn test_collating_and_non_collator_mode_catching_up(task_executor: TaskExe vec![alice.addr.clone(), bob.addr.clone()], para_id, true, - ); - charlie.wait_for_blocks(2).await; + ) + .await; + charlie.wait_for_blocks(5).await; - // run cumulus dave (not a validator) + //TODO: Fix bug with syncing and bring back! + // run cumulus dave (a parachain full node) // - // a collator running in non-validator mode should be able to sync blocks from the tip of the - // parachain - let dave = cumulus_test_service::run_test_node( - task_executor.clone(), - Dave, - || {}, - || {}, - vec![charlie.addr.clone()], - vec![alice.addr.clone(), bob.addr.clone()], - para_id, - false, - ); - dave.wait_for_blocks(4).await; + // Should sync to the tip + // let dave = cumulus_test_service::run_test_node( + // task_executor.clone(), + // Dave, + // || {}, + // || {}, + // vec![charlie.addr.clone()], + // vec![alice.addr.clone(), bob.addr.clone()], + // para_id, + // false, + // ) + // .await; + // dave.wait_for_blocks(4).await; join!( alice.task_manager.clean_shutdown(), bob.task_manager.clean_shutdown(), charlie.task_manager.clean_shutdown(), - dave.task_manager.clean_shutdown(), + // dave.task_manager.clean_shutdown(), ); } diff --git a/upward-message/Cargo.toml b/upward-message/Cargo.toml deleted file mode 100644 index 582e3841c0..0000000000 --- a/upward-message/Cargo.toml +++ /dev/null @@ -1,42 +0,0 @@ -[package] -name = "cumulus-upward-message" -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2018" - -[dependencies] -# Substrate dependencies -sp-std = { git = "https://github.com/paritytech/substrate", branch = "rococo-branch", default-features = false } - -# Polkadot deps -polkadot-core-primitives = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch", default-features = false } -polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch", default-features = false } - -# All these should be optional dependenices, but given the perfect Cargo, it is not possible. -polkadot-runtime = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch", default-features = false } -kusama-runtime = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch", default-features = false } -westend-runtime = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch", default-features = false } -rococo-runtime = { git = "https://github.com/paritytech/polkadot", branch = "rococo-branch", default-features = false } - -[features] -default = [ "std" ] -std = [ - "sp-std/std", - "polkadot-runtime/std", - "kusama-runtime/std", - "westend-runtime/std", - "rococo-runtime/std", - "polkadot-core-primitives/std", - "polkadot-parachain/std", -] -# Should be enabled by when compiling the runtime for WASM. -# -# This disables the runtime api of the Polkadot/Kusama/Westend -# runtimes to not clash with the runtime api of the Parachain when building -# for WASM. -runtime-wasm = [ - "polkadot-runtime/disable-runtime-api", - "westend-runtime/disable-runtime-api", - "rococo-runtime/disable-runtime-api", - "kusama-runtime/disable-runtime-api", -] diff --git a/upward-message/src/kusama.rs b/upward-message/src/kusama.rs deleted file mode 100644 index 1d75494d91..0000000000 --- a/upward-message/src/kusama.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Kusama upward message - -use crate::*; -use kusama_runtime::{BalancesCall, ParachainsCall}; -use polkadot_core_primitives::{AccountId, Balance}; -use sp_std::vec::Vec; - -/// The Kusama upward message. -pub type UpwardMessage = kusama_runtime::Call; - -impl BalancesMessage for UpwardMessage { - fn transfer(dest: AccountId, amount: Balance) -> Self { - BalancesCall::transfer(dest, amount).into() - } -} - -impl XCMPMessage for UpwardMessage { - fn send_message(dest: ParaId, msg: Vec) -> Self { - ParachainsCall::send_xcmp_message(dest, msg).into() - } -} diff --git a/upward-message/src/lib.rs b/upward-message/src/lib.rs deleted file mode 100644 index 399449df7b..0000000000 --- a/upward-message/src/lib.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Upward messages types and traits for Polkadot, Kusama, Rococo and Westend. -//! -//! As Cumulus needs to suits multiple Polkadot-like runtimes the upward message -//! type is different for each of them. To support all of them, Cumulus provides -//! traits to write upward message generic code. - -#![cfg_attr(not(feature = "std"), no_std)] - -use polkadot_parachain::primitives::Id as ParaId; -use sp_std::vec::Vec; - -mod kusama; -mod polkadot; -mod rococo; -mod westend; - -pub use kusama::UpwardMessage as KusamaUpwardMessage; -pub use polkadot::UpwardMessage as PolkadotUpwardMessage; -pub use rococo::UpwardMessage as RococoUpwardMessage; -pub use westend::UpwardMessage as WestendUpwardMessage; - -/// A `Balances` related upward message. -pub trait BalancesMessage: Sized { - /// Transfer the given `amount` from the parachain account to the given - /// `dest` account. - fn transfer(dest: AccountId, amount: Balance) -> Self; -} - -/// A `XCMP` related upward message. -pub trait XCMPMessage: Sized { - /// Send the given XCMP message to given parachain. - fn send_message(dest: ParaId, msg: Vec) -> Self; -} diff --git a/upward-message/src/polkadot.rs b/upward-message/src/polkadot.rs deleted file mode 100644 index c0c8dfc687..0000000000 --- a/upward-message/src/polkadot.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Polkadot upward message - -use crate::*; -use polkadot_core_primitives::{AccountId, Balance}; -use polkadot_runtime::{BalancesCall, ParachainsCall}; -use sp_std::vec::Vec; - -/// The Polkadot upward message. -pub type UpwardMessage = polkadot_runtime::Call; - -impl BalancesMessage for UpwardMessage { - fn transfer(dest: AccountId, amount: Balance) -> Self { - BalancesCall::transfer(dest, amount).into() - } -} - -impl XCMPMessage for UpwardMessage { - fn send_message(dest: ParaId, msg: Vec) -> Self { - ParachainsCall::send_xcmp_message(dest, msg).into() - } -} diff --git a/upward-message/src/rococo.rs b/upward-message/src/rococo.rs deleted file mode 100644 index 3e959eb291..0000000000 --- a/upward-message/src/rococo.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Rococo upward message - -use crate::*; -use polkadot_core_primitives::{AccountId, Balance}; -use rococo_runtime::{BalancesCall, ParachainsCall}; -use sp_std::vec::Vec; - -/// The Rococo upward message. -pub type UpwardMessage = rococo_runtime::Call; - -impl BalancesMessage for UpwardMessage { - fn transfer(dest: AccountId, amount: Balance) -> Self { - BalancesCall::transfer(dest, amount).into() - } -} - -impl XCMPMessage for UpwardMessage { - fn send_message(dest: ParaId, msg: Vec) -> Self { - ParachainsCall::send_xcmp_message(dest, msg).into() - } -} diff --git a/upward-message/src/westend.rs b/upward-message/src/westend.rs deleted file mode 100644 index 32610cc489..0000000000 --- a/upward-message/src/westend.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Westend upward message - -use crate::*; -use polkadot_core_primitives::{AccountId, Balance}; -use sp_std::vec::Vec; -use westend_runtime::{BalancesCall, ParachainsCall}; - -/// The Westend upward message. -pub type UpwardMessage = westend_runtime::Call; - -impl BalancesMessage for UpwardMessage { - fn transfer(dest: AccountId, amount: Balance) -> Self { - BalancesCall::transfer(dest, amount).into() - } -} - -impl XCMPMessage for UpwardMessage { - fn send_message(dest: ParaId, msg: Vec) -> Self { - ParachainsCall::send_xcmp_message(dest, msg).into() - } -}