diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 633e9d1160..456070e27b 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -303,6 +303,11 @@ name = "cast" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "cast" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "cc" version = "1.0.28" @@ -424,6 +429,29 @@ dependencies = [ "simplelog 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "criterion" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion-plot 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion-stats 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "csv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools-num 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)", + "simplelog 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "criterion-plot" version = "0.1.3" @@ -434,6 +462,18 @@ dependencies = [ "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "criterion-plot" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "criterion-stats" version = "0.1.3" @@ -446,6 +486,18 @@ dependencies = [ "thread-scoped 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "criterion-stats" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "thread-scoped 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam" version = "0.6.0" @@ -561,6 +613,23 @@ dependencies = [ "subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "csv" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "csv-core 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "csv-core" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ctr" version = "0.1.1" @@ -913,6 +982,21 @@ dependencies = [ "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "handlebars" +version = "0.32.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hash-db" version = "0.9.0" @@ -1115,6 +1199,22 @@ dependencies = [ "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "itertools" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "itertools-num" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.4.3" @@ -2200,6 +2300,21 @@ name = "percent-encoding" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "pest" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pest_derive" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "pkg-config" version = "0.3.14" @@ -2289,6 +2404,11 @@ name = "quick-error" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "quote" version = "0.5.2" @@ -2608,6 +2728,14 @@ name = "safemem" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "same-file" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "schannel" version = "0.1.14" @@ -2742,6 +2870,16 @@ dependencies = [ "time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "simplelog" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "slab" version = "0.4.1" @@ -2796,6 +2934,7 @@ name = "sr-api-macros" version = "0.1.0" dependencies = [ "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 0.1.0", @@ -3951,6 +4090,16 @@ name = "subtle" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "syn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syn" version = "0.13.11" @@ -3981,6 +4130,14 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "synom" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "synstructure" version = "0.10.1" @@ -4044,6 +4201,15 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "term" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "termcolor" version = "1.0.4" @@ -4445,6 +4611,11 @@ name = "unicode-width" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-xid" version = "0.1.0" @@ -4539,6 +4710,16 @@ dependencies = [ "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "walkdir" +version = "2.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "want" version = "0.0.6" @@ -4743,6 +4924,7 @@ dependencies = [ "checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" "checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa" "checksum cast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "011941fb53da1a8ac3e4132a1becc367c44fe13f630769f3143d8c66c91c6cb6" +"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" "checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749" "checksum cexpr 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8fc0086be9ca82f7fc89fc873435531cb898b86e850005850de1f820e2db6e9b" "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" @@ -4756,8 +4938,11 @@ dependencies = [ "checksum core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "286e0b41c3a20da26536c6000a280585d519fd07b3956b43aed8a79e9edce980" "checksum core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "716c271e8613ace48344f723b60b900a93150271e5be206212d052bbc0883efa" "checksum criterion 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f58b0200bf321214bdda8c797cf0071bcc638171c40ec198c3f652a4edaacde3" +"checksum criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c47d2b548c5647e1a436dc0cb78d4ebf51b6bf7ab101ed76662828bdd4d3a24a" "checksum criterion-plot 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "885431f7865f9d4956b466126674e5ea40a0f193d42157e56630c356c5501957" +"checksum criterion-plot 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5f81689739e463ece7a6b62c6ec63bdab5c4e28fe05ff451769e87d1511411" "checksum criterion-stats 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c71521cb4c7b7eac76b540e75447fb0172c4234d6333729001b886aaa21d6da4" +"checksum criterion-stats 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ff43cac80562f91ead0b617c1be74edf350adfaa195809d355de98dfc8f9237d" "checksum crossbeam 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad4c7ea749d9fb09e23c5cb17e3b70650860553a0e2744e38446b1803bf7db94" "checksum crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "137bc235f622ffaa0428e3854e24acb53291fc0b3ff6fb2cb75a8be6fb02f06b" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" @@ -4770,6 +4955,8 @@ dependencies = [ "checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2" "checksum crypto-mac 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7afa06d05a046c7a47c3a849907ec303504608c927f4e85f7bfff22b7180d971" "checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +"checksum csv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd1c44c58078cfbeaf11fbb3eac9ae5534c23004ed770cc4bfb48e658ae4f04" +"checksum csv-core 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa5cdef62f37e6ffe7d1f07a381bc0db32b7a3ff1cac0de56cb0d81e71f53d65" "checksum ctr 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4b669fcb8e20124db86dbd9b01e74ec0e9e420e65381311ce5249864fc7ff0c0" "checksum ctrlc 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "630391922b1b893692c6334369ff528dcc3a9d8061ccf4c803aa8f83cb13db5e" "checksum cuckoofilter 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd43f7cfaffe0a386636a10baea2ee05cc50df3b77bea4a456c9572a939bf1f" @@ -4812,6 +4999,7 @@ dependencies = [ "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4743617a7464bbda3c8aec8558ff2f9429047e025771037df561d383337ff865" "checksum h2 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1ac030ae20dee464c5d0f36544d8b914a6bc606da44a57e052d2b0f5dae129e0" +"checksum handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d89ec99d1594f285d4590fc32bac5f75cdab383f1123d504d27862c644a807dd" "checksum hash-db 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum hash256-std-hasher 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" @@ -4835,6 +5023,8 @@ dependencies = [ "checksum isatty 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e31a8281fc93ec9693494da65fbf28c0c2aa60a2eaec25dc58e2f31952e95edc" "checksum itertools 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "c4a9b56eb56058f43dc66e58f40a214b2ccbc9f3df51861b63d51dec7b65bc3f" "checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc" +"checksum itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d" +"checksum itertools-num 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a872a22f9e6f7521ca557660adb96dd830e54f0f490fa115bb55dd69d38b27e7" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "" "checksum jsonrpc-http-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "" @@ -4927,6 +5117,8 @@ dependencies = [ "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +"checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc" +"checksum pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3294f437119209b084c797604295f40227cffa35c57220b1e99a6ff3bf8ee4" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" "checksum pretty_assertions 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "28ea5118e2f41bfbc974b28d88c07621befd1fa5d6ec23549be96302a1a59dd2" "checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6" @@ -4939,6 +5131,7 @@ dependencies = [ "checksum pwasm-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "efb0dcbddbb600f47a7098d33762a00552c671992171637f5bb310b37fe1f0e4" "checksum quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb6ccf8db7bbcb9c2eae558db5ab4f3da1c2a87e4e597ed394726bc8ea6ca1d" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" +"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" "checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" @@ -4976,6 +5169,7 @@ dependencies = [ "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" "checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" +"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" "checksum schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56" "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" @@ -4992,6 +5186,7 @@ dependencies = [ "checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" "checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c" "checksum simplelog 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "24b615b1a3cc51ffa565d9a1d0cfcc49fe7d64737ada84eca284cddb0292d125" +"checksum simplelog 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e95345f185d5adeb8ec93459d2dc99654e294cc6ccf5b75414d8ea262de9a13" "checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" "checksum slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e1a2eec401952cd7b12a84ea120e2d57281329940c3f93c2bf04f462539508e" "checksum slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e544d16c6b230d84c866662fe55e31aacfca6ae71e6fc49ae9a311cb379bfc2f" @@ -5011,9 +5206,11 @@ dependencies = [ "checksum structopt-derive 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ef98172b1a00b0bec738508d3726540edcbd186d50dfd326f2b1febbb3559f04" "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" "checksum subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "702662512f3ddeb74a64ce2fbbf3707ee1b6bb663d28bb054e0779bbc720d926" +"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" "checksum syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)" = "734ecc29cd36e8123850d9bf21dfd62ef8300aaa8f879aabaa899721808be37c" +"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum sysinfo 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c747a1fbe091faa7bf76c19f40099f9f12495384c811485d81cf3d60c0eae62" "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" @@ -5021,6 +5218,7 @@ dependencies = [ "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7e91405c14320e5c79b3d148e1c86f40749a36e490642202a31689cb1a3452b2" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" +"checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" "checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" @@ -5062,6 +5260,7 @@ dependencies = [ "checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" "checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" +"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum unsigned-varint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8abc4b7d8158bdfbbaaccc35331ed3c30c2673e99000d7ae665a2eb6576f4" @@ -5075,6 +5274,7 @@ dependencies = [ "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "74e463a508e390cc7447e70f640fbf44ad52e1bd095314ace1fdf99516d32add" "checksum wabt-sys 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "462336bb61096e64761730e0dea1bc8b777bd4e3689c7e813c81f1cfdf4e8a51" +"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" "checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" "checksum wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21ef487a11df1ed468cf613c78798c26282da5c30e9d49f824872d4c77b47d1d" "checksum websocket 0.21.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c9faed2bff8af2ea6b9f8b917d3d00b467583f6781fe3def174a9e33c879703" diff --git a/substrate/core/basic-authorship/src/basic_authorship.rs b/substrate/core/basic-authorship/src/basic_authorship.rs index e524b6aa9e..d3b6421e6a 100644 --- a/substrate/core/basic-authorship/src/basic_authorship.rs +++ b/substrate/core/basic-authorship/src/basic_authorship.rs @@ -22,8 +22,10 @@ use std::sync::Arc; use std::time; use std; -use client::{self, error, Client as SubstrateClient, CallExecutor}; -use client::{block_builder::api::BlockBuilder as BlockBuilderApi, runtime_api::Core}; +use client::{ + self, error, Client as SubstrateClient, CallExecutor, + block_builder::api::BlockBuilder as BlockBuilderApi, runtime_api::{Core, ApiExt} +}; use codec::{Decode, Encode}; use consensus_common::{self, evaluation}; use primitives::{H256, Blake2Hasher}; @@ -68,7 +70,9 @@ where B: client::backend::Backend + 'static, E: CallExecutor + Send + Sync + Clone + 'static, Block: BlockT, - RA: BlockBuilderApi, + RA: Send + Sync + 'static, + SubstrateClient : ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: BlockBuilderApi, { fn push_extrinsic(&mut self, extrinsic: ::Extrinsic) -> Result<(), error::Error> { client::block_builder::BlockBuilder::push(self, extrinsic).map_err(Into::into) @@ -79,7 +83,9 @@ impl AuthoringApi for SubstrateClient where B: client::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + Clone + 'static, Block: BlockT, - RA: BlockBuilderApi, + RA: Send + Sync + 'static, + SubstrateClient : ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: BlockBuilderApi, { type Block = Block; type Error = client::error::Error; @@ -94,7 +100,7 @@ impl AuthoringApi for SubstrateClient where let runtime_api = self.runtime_api(); if runtime_api.has_api::>(at)? { - runtime_api.inherent_extrinsics(at, &inherent_data)? + runtime_api.inherent_extrinsics(at, inherent_data)? .into_iter().try_for_each(|i| block_builder.push(i))?; } diff --git a/substrate/core/client/src/block_builder/block_builder.rs b/substrate/core/client/src/block_builder/block_builder.rs index ac09f1e871..a0e9d67827 100644 --- a/substrate/core/client/src/block_builder/block_builder.rs +++ b/substrate/core/client/src/block_builder/block_builder.rs @@ -84,12 +84,12 @@ where /// the error. Otherwise, it will return a mutable reference to self (in order to chain). pub fn push(&mut self, xt: ::Extrinsic) -> error::Result<()> { use crate::runtime_api::ApiExt; - + let block_id = &self.block_id; let extrinsics = &mut self.extrinsics; - + self.api.map_api_result(|api| { - match api.apply_extrinsic(block_id, &xt)? { + match api.apply_extrinsic(block_id, xt.clone())? { Ok(ApplyOutcome::Success) | Ok(ApplyOutcome::Fail) => { extrinsics.push(xt); Ok(()) diff --git a/substrate/core/client/src/call_executor.rs b/substrate/core/client/src/call_executor.rs index 9872cdd97e..263c43596b 100644 --- a/substrate/core/client/src/call_executor.rs +++ b/substrate/core/client/src/call_executor.rs @@ -14,17 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::sync::Arc; -use std::cmp::Ord; -use codec::Encode; +use std::{sync::Arc, cmp::Ord, panic::UnwindSafe}; +use codec::{Encode, Decode}; use runtime_primitives::generic::BlockId; use runtime_primitives::traits::Block as BlockT; -use state_machine::{self, OverlayedChanges, Ext, - CodeExecutor, ExecutionManager, native_when_possible}; +use state_machine::{ + self, OverlayedChanges, Ext, CodeExecutor, ExecutionManager, native_when_possible +}; use executor::{RuntimeVersion, RuntimeInfo, NativeVersion}; use hash_db::Hasher; use trie::MemoryDB; -use primitives::{H256, Blake2Hasher}; +use primitives::{H256, Blake2Hasher, NativeOrEncoded, NeverNativeValue}; use crate::backend; use crate::error; @@ -56,7 +56,12 @@ where /// of the execution context. fn contextual_call< PB: Fn() -> error::Result, - EM: Fn(Result, Self::Error>, Result, Self::Error>) -> Result, Self::Error>, + EM: Fn( + Result, Self::Error>, + Result, Self::Error> + ) -> Result, Self::Error>, + R: Encode + Decode + PartialEq, + NC: FnOnce() -> R + UnwindSafe, >( &self, at: &BlockId, @@ -66,7 +71,8 @@ where initialised_block: &mut Option>, prepare_environment_block: PB, manager: ExecutionManager, - ) -> error::Result> where ExecutionManager: Clone; + native_call: Option, + ) -> error::Result> where ExecutionManager: Clone; /// Extract RuntimeVersion of given block /// @@ -78,14 +84,20 @@ where /// No changes are made. fn call_at_state< S: state_machine::Backend, - F: FnOnce(Result, Self::Error>, Result, Self::Error>) -> Result, Self::Error>, + F: FnOnce( + Result, Self::Error>, + Result, Self::Error> + ) -> Result, Self::Error>, + R: Encode + Decode + PartialEq, + NC: FnOnce() -> R + UnwindSafe, >(&self, state: &S, overlay: &mut OverlayedChanges, method: &str, call_data: &[u8], - manager: ExecutionManager - ) -> Result<(Vec, S::Transaction, Option>), error::Error>; + manager: ExecutionManager, + native_call: Option, + ) -> Result<(NativeOrEncoded, S::Transaction, Option>), error::Error>; /// Execute a call to a contract on top of given state, gathering execution proof. /// @@ -155,7 +167,9 @@ where ) -> error::Result> { let mut changes = OverlayedChanges::default(); let state = self.backend.state_at(*id)?; - let return_data = state_machine::execute_using_consensus_failure_handler( + let return_data = state_machine::execute_using_consensus_failure_handler::< + _, _, _, _, _, _, fn() -> NeverNativeValue + >( &state, self.backend.changes_trie_storage(), &mut changes, @@ -164,15 +178,21 @@ where call_data, native_when_possible(), false, + None, ) .map(|(result, _, _)| result)?; self.backend.destroy_state(state)?; - Ok(return_data) + Ok(return_data.into_encoded()) } fn contextual_call< PB: Fn() -> error::Result, - EM: Fn(Result, Self::Error>, Result, Self::Error>) -> Result, Self::Error>, + EM: Fn( + Result, Self::Error>, + Result, Self::Error> + ) -> Result, Self::Error>, + R: Encode + Decode + PartialEq, + NC: FnOnce() -> R + UnwindSafe, >( &self, at: &BlockId, @@ -182,12 +202,15 @@ where initialised_block: &mut Option>, prepare_environment_block: PB, manager: ExecutionManager, - ) -> Result, error::Error> where ExecutionManager: Clone { + native_call: Option, + ) -> Result, error::Error> where ExecutionManager: Clone { let state = self.backend.state_at(*at)?; //TODO: Find a better way to prevent double block initialization if method != "Core_initialise_block" && initialised_block.map(|id| id != *at).unwrap_or(true) { let header = prepare_environment_block()?; - state_machine::execute_using_consensus_failure_handler( + state_machine::execute_using_consensus_failure_handler::< + _, _, _, _, _, R, fn() -> R, + >( &state, self.backend.changes_trie_storage(), changes, @@ -196,6 +219,7 @@ where &header.encode(), manager.clone(), false, + None, )?; *initialised_block = Some(*at); } @@ -209,8 +233,8 @@ where call_data, manager, false, - ) - .map(|(result, _, _)| result)?; + native_call, + ).map(|(result, _, _)| result)?; self.backend.destroy_state(state)?; Ok(result) @@ -226,14 +250,20 @@ where fn call_at_state< S: state_machine::Backend, - F: FnOnce(Result, Self::Error>, Result, Self::Error>) -> Result, Self::Error>, + F: FnOnce( + Result, Self::Error>, + Result, Self::Error> + ) -> Result, Self::Error>, + R: Encode + Decode + PartialEq, + NC: FnOnce() -> R + UnwindSafe, >(&self, state: &S, changes: &mut OverlayedChanges, method: &str, call_data: &[u8], manager: ExecutionManager, - ) -> error::Result<(Vec, S::Transaction, Option>)> { + native_call: Option, + ) -> error::Result<(NativeOrEncoded, S::Transaction, Option>)> { state_machine::execute_using_consensus_failure_handler( state, self.backend.changes_trie_storage(), @@ -243,6 +273,7 @@ where call_data, manager, true, + native_call, ) .map(|(result, storage_tx, changes_tx)| ( result, diff --git a/substrate/core/client/src/client.rs b/substrate/core/client/src/client.rs index 10e1570934..67052ff7f1 100644 --- a/substrate/core/client/src/client.rs +++ b/substrate/core/client/src/client.rs @@ -16,25 +16,29 @@ //! Substrate Client -use std::{marker::PhantomData, collections::{HashSet, BTreeMap}, sync::Arc}; +use std::{marker::PhantomData, collections::{HashSet, BTreeMap}, sync::Arc, panic::UnwindSafe}; use crate::error::Error; use futures::sync::mpsc; use parking_lot::{Mutex, RwLock}; +use primitives::NativeOrEncoded; use runtime_primitives::{ Justification, generic::{BlockId, SignedBlock}, }; -use consensus::{Error as ConsensusError, ErrorKind as ConsensusErrorKind, ImportBlock, ImportResult, BlockOrigin, ForkChoiceStrategy}; +use consensus::{ + Error as ConsensusError, ErrorKind as ConsensusErrorKind, ImportBlock, ImportResult, + BlockOrigin, ForkChoiceStrategy +}; use runtime_primitives::traits::{ Block as BlockT, Header as HeaderT, Zero, As, NumberFor, CurrentHeight, BlockNumberToHash, ApiRef, ProvideRuntimeApi, Digest, DigestItem, AuthorityIdFor }; use runtime_primitives::BuildStorage; -use crate::runtime_api::{Core as CoreAPI, CallRuntimeAt, ConstructRuntimeApi}; -use primitives::{Blake2Hasher, H256, ChangesTrieConfiguration, convert_hash}; +use crate::runtime_api::{CallRuntimeAt, ConstructRuntimeApi}; +use primitives::{Blake2Hasher, H256, ChangesTrieConfiguration, convert_hash, NeverNativeValue}; use primitives::storage::{StorageKey, StorageData}; use primitives::storage::well_known_keys; -use codec::Decode; +use codec::{Encode, Decode}; use state_machine::{ DBValue, Backend as StateBackend, CodeExecutor, ChangesTrieAnchorBlockId, ExecutionStrategy, ExecutionManager, prove_read, @@ -557,7 +561,9 @@ impl Client where &self ) -> error::Result> where E: Clone + Send + Sync, - RA: BlockBuilderAPI + RA: Send + Sync, + Self: ProvideRuntimeApi, + ::Api: BlockBuilderAPI { block_builder::BlockBuilder::new(self) } @@ -567,7 +573,9 @@ impl Client where &self, parent: &BlockId ) -> error::Result> where E: Clone + Send + Sync, - RA: BlockBuilderAPI + RA: Send + Sync, + Self: ProvideRuntimeApi, + ::Api: BlockBuilderAPI { block_builder::BlockBuilder::at_block(parent, &self) } @@ -615,7 +623,7 @@ impl Client where let (storage_update, changes_update, storage_changes) = match transaction.state()? { Some(transaction_state) => { let mut overlay = Default::default(); - let r = self.executor.call_at_state( + let r = self.executor.call_at_state::<_, _, NeverNativeValue, fn() -> NeverNativeValue>( transaction_state, &mut overlay, "Core_execute_block", @@ -638,6 +646,7 @@ impl Client where wasm_result }), }, + None, ); let (_, storage_update, changes_update) = r?; overlay.commit_prospective(); @@ -1017,30 +1026,29 @@ impl ProvideRuntimeApi for Client where B: backend::Backend, E: CallExecutor + Clone + Send + Sync, Block: BlockT, - RA: CoreAPI + RA: ConstructRuntimeApi { - type Api = RA; + type Api = >::RuntimeApi; fn runtime_api<'a>(&'a self) -> ApiRef<'a, Self::Api> { - Self::Api::construct_runtime_api(self) + RA::construct_runtime_api(self) } } impl CallRuntimeAt for Client where B: backend::Backend, E: CallExecutor + Clone + Send + Sync, - Block: BlockT, - RA: CoreAPI, // not strictly necessary at the moment - // but we want to bound to make sure the API is actually available. + Block: BlockT { - fn call_api_at( + fn call_api_at R + UnwindSafe>( &self, at: &BlockId, function: &'static str, args: Vec, changes: &mut OverlayedChanges, initialised_block: &mut Option>, - ) -> error::Result> { + native_call: Option, + ) -> error::Result> { let execution_manager = match self.api_execution_strategy { ExecutionStrategy::NativeWhenPossible => ExecutionManager::NativeWhenPossible, ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm, @@ -1053,8 +1061,16 @@ impl CallRuntimeAt for Client where }), }; - self.executor.contextual_call(at, function, &args, changes, initialised_block, - || self.prepare_environment_block(at), execution_manager) + self.executor.contextual_call( + at, + function, + &args, + changes, + initialised_block, + || self.prepare_environment_block(at), + execution_manager, + native_call, + ) } fn runtime_version_at(&self, at: &BlockId) -> error::Result { @@ -1268,7 +1284,7 @@ pub(crate) mod tests { use consensus::BlockOrigin; use test_client::client::{backend::Backend as TestBackend, runtime_api::ApiExt}; use test_client::BlockBuilderExt; - use test_client::runtime::{self, Block, Transfer, RuntimeApi, test_api::TestAPI}; + use test_client::runtime::{self, Block, Transfer, RuntimeApi, TestAPI}; /// Returns tuple, consisting of: /// 1) test client pre-filled with blocks changing balances; @@ -1350,14 +1366,14 @@ pub(crate) mod tests { assert_eq!( client.runtime_api().balance_of( &BlockId::Number(client.info().unwrap().chain.best_number), - &Keyring::Alice.to_raw_public().into() + Keyring::Alice.to_raw_public().into() ).unwrap(), 1000 ); assert_eq!( client.runtime_api().balance_of( &BlockId::Number(client.info().unwrap().chain.best_number), - &Keyring::Ferdie.to_raw_public().into() + Keyring::Ferdie.to_raw_public().into() ).unwrap(), 0 ); @@ -1417,14 +1433,14 @@ pub(crate) mod tests { assert_eq!( client.runtime_api().balance_of( &BlockId::Number(client.info().unwrap().chain.best_number), - &Keyring::Alice.to_raw_public().into() + Keyring::Alice.to_raw_public().into() ).unwrap(), 958 ); assert_eq!( client.runtime_api().balance_of( &BlockId::Number(client.info().unwrap().chain.best_number), - &Keyring::Ferdie.to_raw_public().into() + Keyring::Ferdie.to_raw_public().into() ).unwrap(), 42 ); diff --git a/substrate/core/client/src/light/call_executor.rs b/substrate/core/client/src/light/call_executor.rs index 2f748ca0a8..734a1994bf 100644 --- a/substrate/core/client/src/light/call_executor.rs +++ b/substrate/core/client/src/light/call_executor.rs @@ -17,13 +17,11 @@ //! Light client call exector. Executes methods on remote full nodes, fetching //! execution proof and checking it locally. -use std::collections::HashSet; -use std::marker::PhantomData; -use std::sync::Arc; +use std::{collections::HashSet, marker::PhantomData, sync::Arc}; use futures::{IntoFuture, Future}; use codec::{Encode, Decode}; -use primitives::{H256, Blake2Hasher, convert_hash}; +use primitives::{H256, Blake2Hasher, convert_hash, NativeOrEncoded}; use runtime_primitives::generic::BlockId; use runtime_primitives::traits::{As, Block as BlockT, Header as HeaderT}; use state_machine::{self, Backend as StateBackend, CodeExecutor, OverlayedChanges, @@ -88,7 +86,12 @@ where fn contextual_call< PB: Fn() -> ClientResult, - EM: Fn(Result, Self::Error>, Result, Self::Error>) -> Result, Self::Error>, + EM: Fn( + Result, Self::Error>, + Result, Self::Error> + ) -> Result, Self::Error>, + R: Encode + Decode + PartialEq, + NC, >( &self, at: &BlockId, @@ -98,13 +101,14 @@ where initialised_block: &mut Option>, _prepare_environment_block: PB, _manager: ExecutionManager, - ) -> ClientResult> where ExecutionManager: Clone { + _native_call: Option, + ) -> ClientResult> where ExecutionManager: Clone { // it is only possible to execute contextual call if changes are empty if !changes.is_empty() || initialised_block.is_some() { return Err(ClientErrorKind::NotAvailableOnLightClient.into()); } - self.call(at, method, call_data) + self.call(at, method, call_data).map(NativeOrEncoded::Encoded) } fn runtime_version(&self, id: &BlockId) -> ClientResult { @@ -115,14 +119,20 @@ where fn call_at_state< S: StateBackend, - FF: FnOnce(Result, Self::Error>, Result, Self::Error>) -> Result, Self::Error> + FF: FnOnce( + Result, Self::Error>, + Result, Self::Error> + ) -> Result, Self::Error>, + R: Encode + Decode + PartialEq, + NC: FnOnce() -> R, >(&self, _state: &S, _changes: &mut OverlayedChanges, _method: &str, _call_data: &[u8], - _m: ExecutionManager - ) -> ClientResult<(Vec, S::Transaction, Option>)> { + _m: ExecutionManager, + _native_call: Option, + ) -> ClientResult<(NativeOrEncoded, S::Transaction, Option>)> { Err(ClientErrorKind::NotAvailableOnLightClient.into()) } diff --git a/substrate/core/client/src/runtime_api.rs b/substrate/core/client/src/runtime_api.rs index 66d86590f5..fbe5d1378b 100644 --- a/substrate/core/client/src/runtime_api.rs +++ b/substrate/core/client/src/runtime_api.rs @@ -20,6 +20,9 @@ #[cfg(feature = "std")] pub use state_machine::OverlayedChanges; #[doc(hidden)] +#[cfg(feature = "std")] +pub use primitives::NativeOrEncoded; +#[doc(hidden)] pub use runtime_primitives::{ traits::{AuthorityIdFor, Block as BlockT, GetNodeBlockType, GetRuntimeBlockType, ApiRef, RuntimeApiInfo}, generic::BlockId, transaction_validity::TransactionValidity @@ -34,16 +37,19 @@ pub use codec::{Encode, Decode}; #[cfg(feature = "std")] use crate::error; use rstd::vec::Vec; -use primitives::OpaqueMetadata; use sr_api_macros::decl_runtime_apis; +use primitives::OpaqueMetadata; +#[cfg(feature = "std")] +use std::panic::UnwindSafe; /// Something that can be constructed to a runtime api. #[cfg(feature = "std")] -pub trait ConstructRuntimeApi { +pub trait ConstructRuntimeApi> { + /// The actual runtime api that will be constructed. + type RuntimeApi; + /// Construct an instance of the runtime api. - fn construct_runtime_api<'a, T: CallRuntimeAt>( - call: &'a T - ) -> ApiRef<'a, Self> where Self: Sized; + fn construct_runtime_api<'a>(call: &'a C) -> ApiRef<'a, Self::RuntimeApi>; } /// An extension for the `RuntimeApi`. @@ -71,14 +77,15 @@ pub trait ApiExt { pub trait CallRuntimeAt { /// Calls the given api function with the given encoded arguments at the given block /// and returns the encoded result. - fn call_api_at( + fn call_api_at R + UnwindSafe>( &self, at: &BlockId, function: &'static str, args: Vec, changes: &mut OverlayedChanges, initialised_block: &mut Option>, - ) -> error::Result>; + native_call: Option, + ) -> error::Result>; /// Returns the runtime version at the given block. fn runtime_version_at(&self, at: &BlockId) -> error::Result; @@ -95,7 +102,7 @@ decl_runtime_apis! { /// Execute the given block. fn execute_block(block: Block); /// Initialise a block with the given header. - fn initialise_block(header: ::Header); + fn initialise_block(header: &::Header); } /// The `Metadata` api trait that returns metadata for the runtime. diff --git a/substrate/core/consensus/aura/src/lib.rs b/substrate/core/consensus/aura/src/lib.rs index 5906c267b3..374c4d613f 100644 --- a/substrate/core/consensus/aura/src/lib.rs +++ b/substrate/core/consensus/aura/src/lib.rs @@ -492,12 +492,12 @@ impl Verifier for AuraVerifier>( } fn safe_call(f: F) -> Result - where F: ::std::panic::UnwindSafe + FnOnce() -> U + where F: UnwindSafe + FnOnce() -> U { // Substrate uses custom panic hook that terminates process on panic. Disable it for the native call. let hook = ::std::panic::take_hook(); @@ -108,7 +108,7 @@ fn safe_call(f: F) -> Result /// /// If the inner closure panics, it will be caught and return an error. pub fn with_native_environment(ext: &mut Externalities, f: F) -> Result -where F: ::std::panic::UnwindSafe + FnOnce() -> U +where F: UnwindSafe + FnOnce() -> U { ::runtime_io::with_externalities(ext, move || safe_call(f)) } @@ -181,30 +181,78 @@ impl RuntimeInfo for NativeExecutor { impl CodeExecutor for NativeExecutor { type Error = Error; - fn call>( + fn call + < + E: Externalities, + R:Decode + Encode + PartialEq, + NC: FnOnce() -> R + UnwindSafe + >( &self, ext: &mut E, method: &str, data: &[u8], use_native: bool, - ) -> (Result>, bool) { + native_call: Option, + ) -> (Result>, bool) { RUNTIMES_CACHE.with(|c| { let mut c = c.borrow_mut(); let (module, onchain_version) = match fetch_cached_runtime_version(&self.fallback, &mut c, ext) { Ok((module, onchain_version)) => (module, onchain_version), Err(e) => return (Err(e), false), }; - match (use_native, onchain_version.as_ref().map_or(false, |v| v.can_call_with(&self.native_version.runtime_version))) { - (_, false) => { - trace!(target: "executor", "Request for native execution failed (native: {}, chain: {})", self.native_version.runtime_version, onchain_version.as_ref().map_or_else(||"".into(), |v| format!("{}", v))); - (self.fallback.call_in_wasm_module(ext, module, method, data), false) + match ( + use_native, + onchain_version + .as_ref() + .map_or(false, |v| v.can_call_with(&self.native_version.runtime_version)), + native_call, + ) { + (_, false, _) => { + trace!( + target: "executor", + "Request for native execution failed (native: {}, chain: {})", + self.native_version.runtime_version, + onchain_version + .as_ref() + .map_or_else(||"".into(), |v| format!("{}", v)) + ); + ( + self.fallback + .call_in_wasm_module(ext, module, method, data) + .map(NativeOrEncoded::Encoded), + false + ) } - (false, _) => { - (self.fallback.call_in_wasm_module(ext, module, method, data), false) + (false, _, _) => { + ( + self.fallback + .call_in_wasm_module(ext, module, method, data) + .map(NativeOrEncoded::Encoded), + false + ) + } + (true, true, Some(call)) => { + trace!( + target: "executor", + "Request for native execution with native call succeeded (native: {}, chain: {}).", + self.native_version.runtime_version, + onchain_version + .as_ref() + .map_or_else(||"".into(), |v| format!("{}", v)) + ); + ( + with_native_environment(ext, move || (call)()).map(NativeOrEncoded::Native), + true + ) } _ => { - trace!(target: "executor", "Request for native execution succeeded (native: {}, chain: {})", self.native_version.runtime_version, onchain_version.as_ref().map_or_else(||"".into(), |v| format!("{}", v))); - (D::dispatch(ext, method, data), true) + trace!( + target: "executor", + "Request for native execution succeeded (native: {}, chain: {})", + self.native_version.runtime_version, + onchain_version.as_ref().map_or_else(||"".into(), |v| format!("{}", v)) + ); + (D::dispatch(ext, method, data).map(NativeOrEncoded::Encoded), true) } } }) diff --git a/substrate/core/finality-grandpa/primitives/src/lib.rs b/substrate/core/finality-grandpa/primitives/src/lib.rs index 8776c262a0..6e8c10da31 100644 --- a/substrate/core/finality-grandpa/primitives/src/lib.rs +++ b/substrate/core/finality-grandpa/primitives/src/lib.rs @@ -53,14 +53,6 @@ pub const PENDING_CHANGE_CALL: &str = "grandpa_pending_change"; /// WASM function call to get current GRANDPA authorities. pub const AUTHORITIES_CALL: &str = "grandpa_authorities"; -/// The ApiIds for GRANDPA API. -pub mod id { - use client::runtime_api::ApiId; - - /// ApiId for the GrandpaApi trait. - pub const GRANDPA_API: ApiId = *b"fgrandpa"; -} - /// Well-known storage keys for GRANDPA. pub mod well_known_keys { /// The key for the authorities and weights vector in storage. @@ -92,7 +84,7 @@ decl_runtime_apis! { /// This should be a pure function: i.e. as long as the runtime can interpret /// the digest type it should return the same result regardless of the current /// state. - fn grandpa_pending_change(digest: DigestFor) + fn grandpa_pending_change(digest: &DigestFor) -> Option>>; /// Get the current GRANDPA authorities and weights. This should not change except diff --git a/substrate/core/finality-grandpa/src/tests.rs b/substrate/core/finality-grandpa/src/tests.rs index 344958c044..d973481af2 100644 --- a/substrate/core/finality-grandpa/src/tests.rs +++ b/substrate/core/finality-grandpa/src/tests.rs @@ -26,7 +26,7 @@ use keyring::Keyring; use client::{ BlockchainEvents, error::Result, blockchain::Backend as BlockchainBackend, - runtime_api::{Core, RuntimeVersion, ApiExt, ConstructRuntimeApi, CallRuntimeAt}, + runtime_api::{Core, RuntimeVersion, ApiExt}, }; use test_client::{self, runtime::BlockNumber}; use codec::Decode; @@ -265,7 +265,7 @@ impl Core for RuntimeApi { unimplemented!("Not required for testing!") } - fn execute_block(&self, _: &BlockId, _: &Block) -> Result<()> { + fn execute_block(&self, _: &BlockId, _: Block) -> Result<()> { unimplemented!("Not required for testing!") } @@ -291,12 +291,6 @@ impl ApiExt for RuntimeApi { } } -impl ConstructRuntimeApi for RuntimeApi { - fn construct_runtime_api<'a, T: CallRuntimeAt>(_: &'a T) -> ApiRef<'a, Self> { - unimplemented!("Not required for testing!") - } -} - impl GrandpaApi for RuntimeApi { fn grandpa_authorities( &self, diff --git a/substrate/core/primitives/src/lib.rs b/substrate/core/primitives/src/lib.rs index 98289ddc18..c1f427f496 100644 --- a/substrate/core/primitives/src/lib.rs +++ b/substrate/core/primitives/src/lib.rs @@ -81,6 +81,8 @@ macro_rules! map { use rstd::prelude::*; use rstd::ops::Deref; +#[cfg(feature = "std")] +use std::borrow::Cow; #[cfg(feature = "std")] pub use impl_serde::serialize as bytes; @@ -139,7 +141,7 @@ impl Deref for Bytes { } /// Stores the encoded `RuntimeMetadata` for the native side as opaque type. -#[derive(Encode, Decode)] +#[derive(Encode, Decode, PartialEq)] pub struct OpaqueMetadata(Vec); impl OpaqueMetadata { @@ -156,3 +158,72 @@ impl rstd::ops::Deref for OpaqueMetadata { &self.0 } } + +/// Something that is either a native or an encoded value. +#[cfg(feature = "std")] +pub enum NativeOrEncoded { + /// The native representation. + Native(R), + /// The encoded representation. + Encoded(Vec) +} + +#[cfg(feature = "std")] +impl ::std::fmt::Debug for NativeOrEncoded { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + self.as_encoded().as_ref().fmt(f) + } +} + +#[cfg(feature = "std")] +impl NativeOrEncoded { + /// Return the value as the encoded format. + pub fn as_encoded<'a>(&'a self) -> Cow<'a, [u8]> { + match self { + NativeOrEncoded::Encoded(e) => Cow::Borrowed(e.as_slice()), + NativeOrEncoded::Native(n) => Cow::Owned(n.encode()), + } + } + + /// Return the value as the encoded format. + pub fn into_encoded(self) -> Vec { + match self { + NativeOrEncoded::Encoded(e) => e, + NativeOrEncoded::Native(n) => n.encode(), + } + } +} + +#[cfg(feature = "std")] +impl PartialEq for NativeOrEncoded { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (NativeOrEncoded::Native(l), NativeOrEncoded::Native(r)) => l == r, + (NativeOrEncoded::Native(n), NativeOrEncoded::Encoded(e)) | + (NativeOrEncoded::Encoded(e), NativeOrEncoded::Native(n)) => + Some(n) == codec::Decode::decode(&mut &e[..]).as_ref(), + (NativeOrEncoded::Encoded(l), NativeOrEncoded::Encoded(r)) => l == r, + } + } +} + +/// A value that is never in a native representation. +/// This is type is useful in conjuction with `NativeOrEncoded`. +#[cfg(feature = "std")] +#[derive(PartialEq)] +pub enum NeverNativeValue {} + +#[cfg(feature = "std")] +impl codec::Encode for NeverNativeValue { + fn encode(&self) -> Vec { + // The enum is not constructable, so this function should never be callable! + unreachable!() + } +} + +#[cfg(feature = "std")] +impl codec::Decode for NeverNativeValue { + fn decode(_: &mut I) -> Option { + None + } +} diff --git a/substrate/core/rpc/src/state/mod.rs b/substrate/core/rpc/src/state/mod.rs index 49dc28137a..5084999679 100644 --- a/substrate/core/rpc/src/state/mod.rs +++ b/substrate/core/rpc/src/state/mod.rs @@ -277,7 +277,9 @@ impl StateApi for State where Block: BlockT + 'static, B: client::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + 'static + Clone, - RA: Metadata + RA: Send + Sync + 'static, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: Metadata { type Metadata = ::metadata::Metadata; diff --git a/substrate/core/service/src/components.rs b/substrate/core/service/src/components.rs index dc116873b6..8756f58009 100644 --- a/substrate/core/service/src/components.rs +++ b/substrate/core/service/src/components.rs @@ -135,7 +135,8 @@ pub trait StartRPC { } impl StartRPC for C where - C::RuntimeApi: Metadata>, + ComponentClient: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: Metadata>, { type ServersHandle = (Option, Option>); @@ -189,10 +190,10 @@ fn on_block_imported( client: &Client, transaction_pool: &TransactionPool, ) -> error::Result<()> where - Api: TaggedTransactionQueue, Block: BlockT::Out>, Backend: client::backend::Backend, - Client: ProvideRuntimeApi, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: TaggedTransactionQueue, Executor: client::CallExecutor, PoolApi: txpool::ChainApi, { @@ -210,7 +211,7 @@ fn on_block_imported( let parent_id = BlockId::hash(*block.block.header().parent_hash()); let mut tags = vec![]; for tx in block.block.extrinsics() { - let tx = client.runtime_api().validate_transaction(&parent_id, &tx)?; + let tx = client.runtime_api().validate_transaction(&parent_id, tx.clone())?; match tx { TransactionValidity::Valid { mut provides, .. } => { tags.append(&mut provides); @@ -230,8 +231,8 @@ fn on_block_imported( } impl MaintainTransactionPool for C where - ComponentClient: ProvideRuntimeApi, - C::RuntimeApi: TaggedTransactionQueue>, + ComponentClient: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: TaggedTransactionQueue>, { // TODO [ToDr] Optimize and re-use tags from the pool. fn on_block_imported( diff --git a/substrate/core/service/test/src/lib.rs b/substrate/core/service/test/src/lib.rs index 4335bffe86..2130ae4a83 100644 --- a/substrate/core/service/test/src/lib.rs +++ b/substrate/core/service/test/src/lib.rs @@ -181,10 +181,7 @@ impl TestNet { } } -pub fn connectivity(spec: FactoryChainSpec) where - ::RuntimeApi: - client::block_builder::api::BlockBuilder<::Block, Inherent> -{ +pub fn connectivity(spec: FactoryChainSpec) { const NUM_NODES: u32 = 10; { let temp = TempDir::new("substrate-connectivity-test").expect("Error creating test dir"); @@ -228,9 +225,6 @@ where F: ServiceFactory, B: Fn(&F::FullService) -> ImportBlock, E: Fn(&F::FullService) -> FactoryExtrinsic, - ::RuntimeApi: - client::block_builder::api::BlockBuilder<::Block, ()> + - client::runtime_api::TaggedTransactionQueue<::Block> { const NUM_NODES: u32 = 10; const NUM_BLOCKS: usize = 512; @@ -265,10 +259,8 @@ where } pub fn consensus(spec: FactoryChainSpec, authorities: Vec) -where - F: ServiceFactory, - ::RuntimeApi: - client::block_builder::api::BlockBuilder<::Block, ()> + where + F: ServiceFactory, { const NUM_NODES: u32 = 20; const NUM_BLOCKS: u64 = 200; diff --git a/substrate/core/sr-api-macros/Cargo.toml b/substrate/core/sr-api-macros/Cargo.toml index 5e6140df9d..7cc414a732 100644 --- a/substrate/core/sr-api-macros/Cargo.toml +++ b/substrate/core/sr-api-macros/Cargo.toml @@ -18,3 +18,8 @@ substrate-test-client = { path = "../test-client" } sr-primitives = { path = "../sr-primitives" } sr-version = { path = "../sr-version" } substrate-primitives = { path = "../primitives" } +criterion = "0.2" + +[[bench]] +name = "bench" +harness = false diff --git a/substrate/core/sr-api-macros/benches/bench.rs b/substrate/core/sr-api-macros/benches/bench.rs new file mode 100644 index 0000000000..54f8c8a3d1 --- /dev/null +++ b/substrate/core/sr-api-macros/benches/bench.rs @@ -0,0 +1,62 @@ +// Copyright 2018 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 . + +#[macro_use] +extern crate criterion; +extern crate substrate_client; +extern crate substrate_test_client as test_client; +extern crate sr_primitives as runtime_primitives; + +use criterion::Criterion; +use test_client::runtime::TestAPI; +use runtime_primitives::{generic::BlockId, traits::ProvideRuntimeApi}; + +fn sr_api_benchmark(c: &mut Criterion) { + c.bench_function("add one with same runtime api", |b| { + let client = test_client::new(); + let runtime_api = client.runtime_api(); + let block_id = BlockId::Number(client.info().unwrap().chain.best_number); + + b.iter(|| runtime_api.benchmark_add_one(&block_id, &1)) + }); + + c.bench_function("add one with recreating runtime api", |b| { + let client = test_client::new(); + let block_id = BlockId::Number(client.info().unwrap().chain.best_number); + + b.iter(|| client.runtime_api().benchmark_add_one(&block_id, &1)) + }); + + c.bench_function("vector add one with same runtime api", |b| { + let client = test_client::new(); + let runtime_api = client.runtime_api(); + let block_id = BlockId::Number(client.info().unwrap().chain.best_number); + let data = vec![0; 1000]; + + b.iter_with_large_drop(|| runtime_api.benchmark_vector_add_one(&block_id, &data)) + }); + + c.bench_function("vector add one with recreating runtime api", |b| { + let client = test_client::new(); + let block_id = BlockId::Number(client.info().unwrap().chain.best_number); + let data = vec![0; 1000]; + + b.iter_with_large_drop(|| client.runtime_api().benchmark_vector_add_one(&block_id, &data)) + }); +} + +criterion_group!(benches, sr_api_benchmark); +criterion_main!(benches); diff --git a/substrate/core/sr-api-macros/src/compile_fail_tests.rs b/substrate/core/sr-api-macros/src/compile_fail_tests.rs index ec2c2387bd..7d7be065fa 100644 --- a/substrate/core/sr-api-macros/src/compile_fail_tests.rs +++ b/substrate/core/sr-api-macros/src/compile_fail_tests.rs @@ -92,24 +92,6 @@ mod adding_at_parameter { */ } -mod adding_parameter_with_type_reference { - /*! - ```compile_fail - #[macro_use] - extern crate substrate_client; - extern crate sr_primitives as runtime_primitives; - - decl_runtime_apis! { - pub trait Api { - fn test(data: &u64); - } - } - - fn main() {} - ``` - */ -} - mod invalid_api_version { /*! ```compile_fail diff --git a/substrate/core/sr-api-macros/src/decl_runtime_apis.rs b/substrate/core/sr-api-macros/src/decl_runtime_apis.rs index 376949a628..54f8d81bef 100644 --- a/substrate/core/sr-api-macros/src/decl_runtime_apis.rs +++ b/substrate/core/sr-api-macros/src/decl_runtime_apis.rs @@ -16,24 +16,28 @@ use utils::{ generate_crate_access, generate_hidden_includes, generate_runtime_mod_name_for_trait, - fold_fn_decl_for_client_side, unwrap_or_error + fold_fn_decl_for_client_side, unwrap_or_error, extract_parameter_names_types_and_borrows, + generate_native_call_generator_fn_name }; use proc_macro; -use proc_macro2::TokenStream; +use proc_macro2::{TokenStream, Span}; use quote::quote; use syn::{ - spanned::Spanned, parse_macro_input, parse::{Parse, ParseStream, Result, Error}, + spanned::Spanned, parse_macro_input, parse::{Parse, ParseStream, Result, Error}, ReturnType, fold::{self, Fold}, FnDecl, parse_quote, ItemTrait, Generics, GenericParam, Attribute, - visit::{Visit, self}, FnArg, Pat, TraitBound, Type, Meta, NestedMeta, Lit + visit::{Visit, self}, FnArg, Pat, TraitBound, Meta, NestedMeta, Lit, TraitItem, Ident, Type }; use std::collections::HashMap; use blake2_rfc; +/// The ident used for the block generic parameter. +const BLOCK_GENERIC_IDENT: &str = "Block"; + /// Unique identifier used to make the hidden includes unique for this macro. const HIDDEN_INCLUDES_ID: &str = "DECL_RUNTIME_APIS"; @@ -88,6 +92,167 @@ fn remove_supported_attributes(attrs: &mut Vec) -> HashMap<&'static s result } +/// Visits the ast and checks if `Block` ident is used somewhere. +struct IsUsingBlock { + result: bool, +} + +impl<'ast> Visit<'ast> for IsUsingBlock { + fn visit_ident(&mut self, i: &'ast Ident) { + if i == BLOCK_GENERIC_IDENT { + self.result = true; + } + } +} + +/// Visits the ast and checks if `Block` ident is used somewhere. +fn type_is_using_block(ty: &Type) -> bool { + let mut visitor = IsUsingBlock { result: false }; + visitor.visit_type(ty); + visitor.result +} + +/// Visits the ast and checks if `Block` ident is used somewhere. +fn return_type_is_using_block(ty: &ReturnType) -> bool { + let mut visitor = IsUsingBlock { result: false }; + visitor.visit_return_type(ty); + visitor.result +} + +/// Replace all occurences of `Block` with `NodeBlock` +struct ReplaceBlockWithNodeBlock {} + +impl Fold for ReplaceBlockWithNodeBlock { + fn fold_ident(&mut self, input: Ident) -> Ident { + if input == BLOCK_GENERIC_IDENT { + Ident::new("NodeBlock", Span::call_site()) + } else { + input + } + } +} + +/// Replace all occurences of `Block` with `NodeBlock` +fn fn_arg_replace_block_with_node_block(fn_arg: FnArg) -> FnArg { + let mut replace = ReplaceBlockWithNodeBlock {}; + fold::fold_fn_arg(&mut replace, fn_arg) +} + +/// Replace all occurences of `Block` with `NodeBlock` +fn return_type_replace_block_with_node_block(return_type: ReturnType) -> ReturnType { + let mut replace = ReplaceBlockWithNodeBlock {}; + fold::fold_return_type(&mut replace, return_type) +} + +fn generate_native_call_generators(decl: &ItemTrait) -> Result { + let fns = decl.items.iter().filter_map(|i| match i { + TraitItem::Method(ref m) => Some(&m.sig), + _ => None, + }); + + let mut result = Vec::new(); + let trait_ = &decl.ident; + let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID); + + // Auxilariy function that is used to convert between types that use different block types. + // The function expects that both a convertable by encoding the one and decoding the other. + result.push(quote!( + fn convert_between_block_types + (input: &I) -> R + { + ::decode( + &mut &#crate_::runtime_api::Encode::encode(input)[..] + ).unwrap() + } + )); + + // Generate a native call generator for each function of the given trait. + for fn_ in fns { + let params = extract_parameter_names_types_and_borrows(&fn_.decl)?; + let trait_fn_name = &fn_.ident; + let fn_name = generate_native_call_generator_fn_name(&fn_.ident); + let output = return_type_replace_block_with_node_block(fn_.decl.output.clone()); + + // Every type that is using the `Block` generic parameter, we need to encode/decode, + // to make it compatible between the runtime/node. + let conversions = params.iter().filter(|v| type_is_using_block(&v.1)).map(|(n, t, _)| { + quote!( + let #n: #t = convert_between_block_types(&#n); + ) + }); + // Same as for the input types, we need to check if we also need to convert the output, + // before returning it. + let output_conversion = if return_type_is_using_block(&fn_.decl.output) { + quote!( convert_between_block_types(&res) ) + } else { + quote!( res ) + }; + + let input_names = params.iter().map(|v| &v.0); + // If the type is using the block generic type, we will encode/decode it to make it + // compatible. To ensure that we forward it by ref/value, we use the value given by the + // the user. Otherwise if it is not using the block, we don't need to add anything. + let input_borrows = params + .iter() + .map(|v| if type_is_using_block(&v.1) { v.2.clone() } else { quote!() }); + + // Replace all `Block` with `NodeBlock`, add `'a` lifetime to references and collect + // all the function inputs. + let fn_inputs = fn_ + .decl + .inputs + .iter() + .map(|v| fn_arg_replace_block_with_node_block(v.clone())) + .map(|v| match v { + FnArg::Captured(ref arg) => { + let mut arg = arg.clone(); + match arg.ty { + Type::Reference(ref mut r) => { + r.lifetime = Some(parse_quote!( 'a )); + }, + _ => {} + } + FnArg::Captured(arg) + }, + r => r.clone(), + }); + + let (impl_generics, ty_generics, where_clause) = decl.generics.split_for_impl(); + // We need to parse them again, to get an easy access to the actual parameters. + let mut impl_generics: Generics = parse_quote!(#impl_generics); + let impl_generics_params = impl_generics.params.iter().map(|p| { + match p { + GenericParam::Type(ref ty) => { + let mut ty = ty.clone(); + ty.bounds.push(parse_quote!( 'a )); + GenericParam::Type(ty) + }, + // We should not see anything different than type params here. + r => r.clone(), + } + }); + + // Generate the generator function + result.push(quote!( + #[cfg(any(feature = "std", test))] + pub fn #fn_name< + 'a, ApiImpl: #trait_ #ty_generics, NodeBlock: #crate_::runtime_api::BlockT + #(, #impl_generics_params)* + >( + #( #fn_inputs ),* + ) -> impl FnOnce() #output + 'a #where_clause { + move || { + #( #conversions )* + let res = ApiImpl::#trait_fn_name(#( #input_borrows #input_names ),*); + #output_conversion + } + } + )); + } + + Ok(quote!( #( #result )* )) +} + /// Generate the decleration of the trait for the runtime. fn generate_runtime_decls(decls: &[ItemTrait]) -> TokenStream { let mut result = Vec::new(); @@ -101,9 +266,11 @@ fn generate_runtime_decls(decls: &[ItemTrait]) -> TokenStream { generate_runtime_api_version(v as u32) })); let id = generate_runtime_api_id(&decl.ident.to_string()); + let native_call_generators = unwrap_or_error(generate_native_call_generators(&decl)); result.push(quote!( #[doc(hidden)] + #[allow(dead_code)] pub mod #mod_name { use super::*; @@ -112,6 +279,8 @@ fn generate_runtime_decls(decls: &[ItemTrait]) -> TokenStream { pub #api_version pub #id + + #native_call_generators } )); } @@ -143,6 +312,7 @@ impl<'a> Fold for ToClientSideDecl<'a> { *self.found_attributes = remove_supported_attributes(&mut input.attrs); // Check if this is the `Core` runtime api trait. let is_core_trait = self.found_attributes.contains_key(CORE_TRAIT_ATTRIBUTE); + let block_ident = Ident::new(BLOCK_GENERIC_IDENT, Span::call_site()); if is_core_trait { // Add all the supertraits we want to have for `Core`. @@ -151,13 +321,12 @@ impl<'a> Fold for ToClientSideDecl<'a> { 'static + Send + Sync - + #crate_::runtime_api::ConstructRuntimeApi - + #crate_::runtime_api::ApiExt + + #crate_::runtime_api::ApiExt<#block_ident> ); } else { // Add the `Core` runtime api as super trait. let crate_ = &self.crate_; - input.supertraits.push(parse_quote!( #crate_::runtime_api::Core )); + input.supertraits.push(parse_quote!( #crate_::runtime_api::Core<#block_ident> )); } // The client side trait is only required when compiling with the feature `std` or `test`. @@ -291,19 +460,6 @@ impl<'ast> Visit<'ast> for CheckTraitDecl { }, _ => {} } - - match arg.ty { - Type::Reference(ref reference) => { - self.errors.push( - Error::new( - reference.span(), - "Do not use type references as arguments. The client side \ - declaration will take all arguments as reference automatically." - ) - ) - }, - _ => {}, - } }, FnArg::SelfRef(_) | FnArg::SelfValue(_) => { self.errors.push(Error::new(input.span(), "Self values are not supported.")) @@ -323,7 +479,7 @@ impl<'ast> Visit<'ast> for CheckTraitDecl { fn visit_generic_param(&mut self, input: &'ast GenericParam) { match input { - GenericParam::Type(ty) if &ty.ident == "Block" => { + GenericParam::Type(ty) if &ty.ident == BLOCK_GENERIC_IDENT => { self.errors.push( Error::new( input.span(), @@ -340,7 +496,7 @@ impl<'ast> Visit<'ast> for CheckTraitDecl { fn visit_trait_bound(&mut self, input: &'ast TraitBound) { if let Some(last_ident) = input.path.segments.last().map(|v| &v.value().ident) { - if last_ident == "BlockT" || last_ident == "Block" { + if last_ident == "BlockT" || last_ident == BLOCK_GENERIC_IDENT { self.errors.push( Error::new( input.span(), diff --git a/substrate/core/sr-api-macros/src/impl_runtime_apis.rs b/substrate/core/sr-api-macros/src/impl_runtime_apis.rs index a6aa4b82a5..6663cae85f 100644 --- a/substrate/core/sr-api-macros/src/impl_runtime_apis.rs +++ b/substrate/core/sr-api-macros/src/impl_runtime_apis.rs @@ -16,7 +16,8 @@ use utils::{ unwrap_or_error, generate_crate_access, generate_hidden_includes, - generate_runtime_mod_name_for_trait, fold_fn_decl_for_client_side + generate_runtime_mod_name_for_trait, fold_fn_decl_for_client_side, generate_unique_pattern, + extract_parameter_names_types_and_borrows, generate_native_call_generator_fn_name }; use proc_macro; @@ -25,9 +26,9 @@ use proc_macro2::{Span, TokenStream}; use quote::quote; use syn::{ - spanned::Spanned, parse_macro_input, Ident, Type, ItemImpl, MethodSig, FnArg, Path, + spanned::Spanned, parse_macro_input, Ident, Type, ItemImpl, MethodSig, Path, ImplItem, parse::{Parse, ParseStream, Result, Error}, PathArguments, GenericArgument, TypePath, - fold::{self, Fold}, FnDecl, parse_quote, Pat + fold::{self, Fold}, FnDecl, parse_quote, FnArg }; use std::{collections::HashSet, iter}; @@ -60,47 +61,17 @@ fn generate_impl_call( input: &Ident, impl_trait: &Path ) -> Result { - let mut pnames = Vec::new(); - let mut ptypes = Vec::new(); - let mut generated_pattern_counter = 0; - for input in signature.decl.inputs.iter() { - match input { - FnArg::Captured(arg) => { - match &arg.ty { - Type::Reference(_) => { - return Err( - Error::new( - arg.ty.span(), - "No type references are allowed in the api traits!" - ) - ) - }, - _ => {}, - } - - pnames.push( - generate_unique_pattern(arg.pat.clone(), &mut generated_pattern_counter) - ); - ptypes.push(&arg.ty); - }, - _ => { - return Err( - Error::new( - input.span(), - "Only function arguments with the following \ - pattern are accepted: `name: type`!" - ) - ) - } - } - } + let params = extract_parameter_names_types_and_borrows(&signature.decl)?; let c = generate_crate_access(HIDDEN_INCLUDES_ID); let c_iter = iter::repeat(&c); let fn_name = &signature.ident; let fn_name_str = iter::repeat(fn_name.to_string()); let input = iter::repeat(input); - let pnames2 = pnames.clone(); + let pnames = params.iter().map(|v| &v.0); + let pnames2 = params.iter().map(|v| &v.0); + let ptypes = params.iter().map(|v| &v.1); + let pborrow = params.iter().map(|v| &v.2); Ok( quote!( @@ -111,7 +82,7 @@ fn generate_impl_call( }; )* - let output = <#runtime as #impl_trait>::#fn_name(#( #pnames2 ),*); + let output = <#runtime as #impl_trait>::#fn_name(#( #pborrow #pnames2 ),*); #c::runtime_api::Encode::encode(&output) ).into() ) @@ -294,10 +265,11 @@ fn generate_runtime_api_base_structures(impls: &[ItemImpl]) -> Result>, + pub struct RuntimeApiImpl + 'static> { + call: &'static C, commit_on_success: ::std::cell::RefCell, initialised_block: ::std::cell::RefCell>, changes: ::std::cell::RefCell<#crate_::runtime_api::OverlayedChanges>, @@ -307,12 +279,14 @@ fn generate_runtime_api_base_structures(impls: &[ItemImpl]) -> Result> Send for RuntimeApiImpl {} #[cfg(any(feature = "std", test))] - unsafe impl Sync for RuntimeApi {} + unsafe impl> Sync for RuntimeApiImpl {} #[cfg(any(feature = "std", test))] - impl #crate_::runtime_api::ApiExt<#block> for RuntimeApi { + impl> #crate_::runtime_api::ApiExt<#block> + for RuntimeApiImpl + { fn map_api_result ::std::result::Result, R, E>( &self, map_call: F @@ -330,22 +304,21 @@ fn generate_runtime_api_base_structures(impls: &[ItemImpl]) -> Result #crate_::error::Result where Self: Sized { - unsafe { self.call.as_ref().runtime_version_at(at) }.map(|r| r.has_api::()) + self.call.runtime_version_at(at).map(|r| r.has_api::()) } } #[cfg(any(feature = "std", test))] - impl #crate_::runtime_api::ConstructRuntimeApi<#block> for RuntimeApi { - fn construct_runtime_api<'a, T: #crate_::runtime_api::CallRuntimeAt<#block>>( - call: &'a T - ) -> #crate_::runtime_api::ApiRef<'a, Self> where Self: Sized { - RuntimeApi { - call: unsafe { - ::std::ptr::NonNull::new_unchecked( - call as - &#crate_::runtime_api::CallRuntimeAt<#block> as *const _ as *mut _ - ) - }, + impl + 'static> + #crate_::runtime_api::ConstructRuntimeApi<#block, C> for RuntimeApi + { + type RuntimeApi = RuntimeApiImpl; + + fn construct_runtime_api<'a>( + call: &'a C, + ) -> #crate_::runtime_api::ApiRef<'a, Self::RuntimeApi> { + RuntimeApiImpl { + call: unsafe { ::std::mem::transmute(call) }, commit_on_success: true.into(), initialised_block: None.into(), changes: Default::default(), @@ -354,25 +327,39 @@ fn generate_runtime_api_base_structures(impls: &[ItemImpl]) -> Result( + impl> RuntimeApiImpl { + fn call_api_at< + R: #crate_::runtime_api::Encode + #crate_::runtime_api::Decode + PartialEq, + NC: FnOnce() -> R + ::std::panic::UnwindSafe, + >( &self, at: &#block_id, function: &'static str, - args: &A + args: Vec, + native_call: NC, ) -> #crate_::error::Result { let res = unsafe { - self.call.as_ref().call_api_at( + self.call.call_api_at( at, function, - args.encode(), + args, &mut *self.changes.borrow_mut(), - &mut *self.initialised_block.borrow_mut() + &mut *self.initialised_block.borrow_mut(), + Some(native_call), ).and_then(|r| - R::decode(&mut &r[..]) - .ok_or_else(|| - #crate_::error::ErrorKind::CallResultDecode(function).into() - ) + match r { + #crate_::runtime_api::NativeOrEncoded::Native(n) => { + Ok(n) + }, + #crate_::runtime_api::NativeOrEncoded::Encoded(r) => { + R::decode(&mut &r[..]) + .ok_or_else(|| + #crate_::error::ErrorKind::CallResultDecode( + function + ).into() + ) + } + } ) }; @@ -431,21 +418,6 @@ fn generate_api_impl_for_runtime(impls: &[ItemImpl]) -> Result { Ok(quote!( #( #impls_prepared )* )) } -/// Generate an unique pattern based on the given counter, if the given pattern is a `_`. -fn generate_unique_pattern(pat: Pat, counter: &mut u32) -> Pat { - match pat { - Pat::Wild(_) => { - let generated_name = Ident::new( - &format!("impl_runtime_api_generated_name_{}", counter), - pat.span() - ); - *counter += 1; - - parse_quote!( #generated_name ) - }, - _ => pat, - } -} /// Auxilariy data structure that is used to convert `impl Api for Runtime` to /// `impl Api for RuntimeApi`. @@ -457,6 +429,9 @@ struct ApiRuntimeImplToApiRuntimeApiImpl<'a> { runtime_block: &'a TypePath, node_block_id: &'a TokenStream, impl_trait_ident: &'a Ident, + runtime_mod_path: &'a Path, + runtime_type: &'a Type, + trait_generic_arguments: &'a [GenericArgument] } impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> { @@ -482,30 +457,63 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> { } fn fold_impl_item_method(&mut self, mut input: syn::ImplItemMethod) -> syn::ImplItemMethod { - { + let block = { + let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID); let mut generated_name_counter = 0; + // Replace `_` with unique patterns and collect all patterns. let arg_names = input.sig.decl.inputs.iter_mut().filter_map(|i| match i { FnArg::Captured(ref mut arg) => Some(&mut arg.pat), _ => None, }).map(|p| { *p = generate_unique_pattern(p.clone(), &mut generated_name_counter); - p - }); - let name = prefix_function_with_trait(self.impl_trait_ident, &input.sig.ident); + p.clone() + }).collect::>(); + + let runtime_mod_path = self.runtime_mod_path; + let runtime = self.runtime_type; + let arg_names2 = arg_names.clone(); + let fn_name = prefix_function_with_trait(self.impl_trait_ident, &input.sig.ident); + let native_call_generator_ident = + generate_native_call_generator_fn_name(&input.sig.ident); + let trait_generic_arguments = self.trait_generic_arguments; + let node_block = self.node_block; // Generate the new method implementation that calls into the runime. - input.block = parse_quote!( { self.call_api_at(at, #name, &( #( #arg_names ),* )) } ); - } + parse_quote!( + { + let args = #crate_::runtime_api::Encode::encode(&( #( &#arg_names ),* )); + self.call_api_at( + at, + #fn_name, + args, + #runtime_mod_path #native_call_generator_ident :: + <#runtime, #node_block #(, #trait_generic_arguments )*> ( + #( #arg_names2 ),* + ) + ) + } + ) + }; - fold::fold_impl_item_method(self, input) + let mut input = fold::fold_impl_item_method(self, input); + // We need to set the block, after we modified the rest of the ast, otherwise we would + // modify our generated block as well. + input.block = block; + input } fn fold_item_impl(&mut self, mut input: ItemImpl) -> ItemImpl { - // Implement the trait for the `RuntimeApi` - input.self_ty = Box::new(parse_quote!( RuntimeApi )); + // Implement the trait for the `RuntimeApiImpl` + input.self_ty = Box::new(parse_quote!( RuntimeApiImpl )); - // The implementation for the `RuntimeApi` is only required when compiling with the feature - // `std` or `test`. + let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID); + let block = self.node_block; + input.generics.params.push( + parse_quote!( RuntimeApiImplCall: #crate_::runtime_api::CallRuntimeAt<#block> + 'static ) + ); + + // The implementation for the `RuntimeApiImpl` is only required when compiling with + // the feature `std` or `test`. input.attrs.push(parse_quote!( #[cfg(any(feature = "std", test))] )); fold::fold_item_impl(self, input) @@ -517,21 +525,33 @@ fn generate_api_impl_for_runtime_api(impls: &[ItemImpl]) -> Result let mut result = Vec::with_capacity(impls.len()); for impl_ in impls { - let impl_trait = extract_impl_trait(&impl_)?; - let impl_trait_ident = &impl_trait + let impl_trait_path = extract_impl_trait(&impl_)?; + let impl_trait = &impl_trait_path .segments .last() - .ok_or_else(|| Error::new(impl_trait.span(), "Empty trait path not possible!"))? - .value() - .ident; - let runtime_block = extract_runtime_block_ident(impl_trait)?; + .ok_or_else(|| Error::new(impl_trait_path.span(), "Empty trait path not possible!"))? + .into_value(); + let impl_trait_ident = &impl_trait.ident; + let runtime_block = extract_runtime_block_ident(impl_trait_path)?; let (node_block, node_block_id) = generate_node_block_and_block_id_ty(&impl_.self_ty); + let runtime_type = &impl_.self_ty; + let mut runtime_mod_path = extend_with_runtime_decl_path(impl_trait_path.clone()); + // remove the trait to get just the module path + runtime_mod_path.segments.pop(); + + let trait_generic_arguments = match impl_trait.arguments { + PathArguments::Parenthesized(_) | PathArguments::None => vec![], + PathArguments::AngleBracketed(ref b) => b.args.iter().cloned().collect(), + }; let mut visitor = ApiRuntimeImplToApiRuntimeApiImpl { runtime_block, node_block: &node_block, node_block_id: &node_block_id, impl_trait_ident: &impl_trait_ident, + runtime_mod_path: &runtime_mod_path, + runtime_type: &*runtime_type, + trait_generic_arguments: &trait_generic_arguments, }; result.push(visitor.fold_item_impl(impl_.clone())); diff --git a/substrate/core/sr-api-macros/src/utils.rs b/substrate/core/sr-api-macros/src/utils.rs index 4c80adf16b..e35ed52084 100644 --- a/substrate/core/sr-api-macros/src/utils.rs +++ b/substrate/core/sr-api-macros/src/utils.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . use proc_macro2::{TokenStream, Span}; -use syn::{Result, Ident, FnDecl, parse_quote, Type, FnArg}; +use syn::{Result, Ident, FnDecl, parse_quote, Type, Pat, spanned::Spanned, FnArg, Error}; use quote::quote; use std::env; @@ -64,19 +64,6 @@ pub fn fold_fn_decl_for_client_side( block_id: &TokenStream, crate_: &TokenStream ) -> FnDecl { - // Add `&` to all parameter types. - input.inputs - .iter_mut() - .filter_map(|i| match i { - FnArg::Captured(ref mut arg) => Some(&mut arg.ty), - _ => None, - }) - .filter_map(|i| match i { - Type::Reference(_) => None, - r => Some(r), - }) - .for_each(|i| *i = parse_quote!( &#i )); - // Add `&self, at:& BlockId` as parameters to each function at the beginning. input.inputs.insert(0, parse_quote!( at: &#block_id )); input.inputs.insert(0, parse_quote!( &self )); @@ -95,3 +82,61 @@ pub fn fold_fn_decl_for_client_side( input } + +/// Generate an unique pattern based on the given counter, if the given pattern is a `_`. +pub fn generate_unique_pattern(pat: Pat, counter: &mut u32) -> Pat { + match pat { + Pat::Wild(_) => { + let generated_name = Ident::new( + &format!("runtime_api_generated_name_{}", counter), + pat.span() + ); + *counter += 1; + + parse_quote!( #generated_name ) + }, + _ => pat, + } +} + +/// Extracts the name, the type and `&` or ``(if it is a reference or not) +/// for each parameter in the given function declaration. +pub fn extract_parameter_names_types_and_borrows(fn_decl: &FnDecl) + -> Result> +{ + let mut result = Vec::new(); + let mut generated_pattern_counter = 0; + for input in fn_decl.inputs.iter() { + match input { + FnArg::Captured(arg) => { + let (ty, borrow) = match &arg.ty { + Type::Reference(t) => { + let ty = &t.elem; + (parse_quote!( #ty ), quote!( & )) + }, + t => { (t.clone(), quote!()) }, + }; + + let name = + generate_unique_pattern(arg.pat.clone(), &mut generated_pattern_counter); + result.push((name, ty, borrow)); + }, + _ => { + return Err( + Error::new( + input.span(), + "Only function arguments with the following \ + pattern are accepted: `name: type`!" + ) + ) + } + } + } + + Ok(result) +} + +/// Generates the name for the native call generator function. +pub fn generate_native_call_generator_fn_name(fn_name: &Ident) -> Ident { + Ident::new(&format!("{}_native_call_generator", fn_name.to_string()), Span::call_site()) +} diff --git a/substrate/core/sr-api-macros/tests/decl_and_impl.rs b/substrate/core/sr-api-macros/tests/decl_and_impl.rs index 699c8c01cf..1d87a15201 100644 --- a/substrate/core/sr-api-macros/tests/decl_and_impl.rs +++ b/substrate/core/sr-api-macros/tests/decl_and_impl.rs @@ -1,13 +1,13 @@ #[macro_use] -extern crate substrate_client; +extern crate substrate_client as client; extern crate sr_primitives as runtime_primitives; extern crate substrate_primitives as primitives; extern crate substrate_test_client as test_client; use runtime_primitives::traits::{GetNodeBlockType, Block as BlockT, AuthorityIdFor}; use runtime_primitives::generic::BlockId; -use substrate_client::runtime_api::{self, RuntimeApiInfo}; -use substrate_client::error::Result; +use client::runtime_api::{self, RuntimeApiInfo}; +use client::error::Result; use test_client::runtime::Block; /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` @@ -62,17 +62,21 @@ impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialise_block(_: ::Header) { + fn initialise_block(_: &::Header) { unimplemented!() } } } +type TestClient = client::Client; + #[test] fn test_client_side_function_signature() { - let _test: fn(&RuntimeApi, &BlockId, &u64) -> Result<()> = RuntimeApi::test; - let _something_with_block: fn(&RuntimeApi, &BlockId, &Block) -> Result = - RuntimeApi::something_with_block; + let _test: fn(&RuntimeApiImpl, &BlockId, u64) -> Result<()> = + RuntimeApiImpl::::test; + let _something_with_block: + fn(&RuntimeApiImpl, &BlockId, Block) -> Result = + RuntimeApiImpl::::something_with_block; } #[test] diff --git a/substrate/core/sr-primitives/src/lib.rs b/substrate/core/sr-primitives/src/lib.rs index 26b26974a2..6ca72cf80c 100644 --- a/substrate/core/sr-primitives/src/lib.rs +++ b/substrate/core/sr-primitives/src/lib.rs @@ -531,7 +531,7 @@ impl BasicInherentData { //TODO: https://github.com/paritytech/substrate/issues/1022 /// Error type used while checking inherents. -#[derive(Encode)] +#[derive(Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode))] pub enum CheckInherentError { /// The inherents are generally valid but a delay until the given timestamp diff --git a/substrate/core/sr-primitives/src/traits.rs b/substrate/core/sr-primitives/src/traits.rs index 4db2d580d7..8723dbec91 100644 --- a/substrate/core/sr-primitives/src/traits.rs +++ b/substrate/core/sr-primitives/src/traits.rs @@ -470,7 +470,7 @@ pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDe type Number: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec; type Hash: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; type Hashing: Hash; - type Digest: Digest; + type Digest: Digest + Codec; fn new( number: Self::Number, diff --git a/substrate/core/state-machine/src/lib.rs b/substrate/core/state-machine/src/lib.rs index e4fe89e2d2..b10ae42bc8 100644 --- a/substrate/core/state-machine/src/lib.rs +++ b/substrate/core/state-machine/src/lib.rs @@ -30,15 +30,16 @@ extern crate substrate_trie; extern crate parking_lot; extern crate heapsize; -#[cfg_attr(test, macro_use)] extern crate substrate_primitives as primitives; +#[cfg_attr(test, macro_use)] +extern crate substrate_primitives as primitives; extern crate parity_codec as codec; extern crate substrate_trie as trie; -use std::fmt; +use std::{fmt, panic::UnwindSafe}; use hash_db::Hasher; use heapsize::HeapSizeOf; -use codec::Decode; -use primitives::storage::well_known_keys; +use codec::{Decode, Encode}; +use primitives::{storage::well_known_keys, NativeOrEncoded, NeverNativeValue}; pub mod backend; mod changes_trie; @@ -171,13 +172,14 @@ pub trait CodeExecutor: Sized + Send + Sync { /// Call a given method in the runtime. Returns a tuple of the result (either the output data /// or an execution error) together with a `bool`, which is true if native execution was used. - fn call>( + fn call, R: Encode + Decode + PartialEq, NC: FnOnce() -> R + UnwindSafe>( &self, ext: &mut E, method: &str, data: &[u8], - use_native: bool - ) -> (Result, Self::Error>, bool); + use_native: bool, + native_call: Option, + ) -> (Result, Self::Error>, bool); } /// Strategy for executing a call into the runtime. @@ -213,12 +215,26 @@ impl<'a, F> From<&'a ExecutionManager> for ExecutionStrategy { } /// Evaluate to ExecutionManager::NativeWhenPossible, without having to figure out the type. -pub fn native_when_possible() -> ExecutionManager, E>, Result, E>)->Result, E>> { +pub fn native_when_possible() -> + ExecutionManager< + fn( + Result, E>, + Result, E> + ) -> Result, E> + > +{ ExecutionManager::NativeWhenPossible } /// Evaluate to ExecutionManager::NativeWhenPossible, without having to figure out the type. -pub fn always_wasm() -> ExecutionManager, E>, Result, E>)->Result, E>> { +pub fn always_wasm() -> + ExecutionManager< + fn( + Result, E>, + Result, E> + ) -> Result, E> + > +{ ExecutionManager::AlwaysWasm } @@ -246,7 +262,9 @@ where T: ChangesTrieStorage, H::Out: Ord + HeapSizeOf, { - execute_using_consensus_failure_handler( + // We are not giving a native call and thus we are sure that the result can never be a native + // value. + execute_using_consensus_failure_handler::<_, _, _, _, _, NeverNativeValue, fn() -> NeverNativeValue>( backend, changes_trie_storage, overlay, @@ -257,14 +275,19 @@ where ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm, ExecutionStrategy::NativeWhenPossible => ExecutionManager::NativeWhenPossible, ExecutionStrategy::Both => ExecutionManager::Both(|wasm_result, native_result| { - warn!("Consensus error between wasm {:?} and native {:?}. Using wasm.", wasm_result, native_result); + warn!( + "Consensus error between wasm {:?} and native {:?}. Using wasm.", + wasm_result, + native_result + ); wasm_result }), }, true, + None, ) .map(|(result, storage_tx, changes_tx)| ( - result, + result.into_encoded(), storage_tx.expect("storage_tx is always computed when compute_tx is true; qed"), changes_tx, )) @@ -278,7 +301,9 @@ where /// /// Note: changes to code will be in place if this call is made again. For running partial /// blocks (e.g. a transaction at a time), ensure a different method is used. -pub fn execute_using_consensus_failure_handler( +pub fn execute_using_consensus_failure_handler< + H, B, T, Exec, Handler, R: Decode + Encode + PartialEq, NC: FnOnce() -> R + UnwindSafe +>( backend: &B, changes_trie_storage: Option<&T>, overlay: &mut OverlayedChanges, @@ -287,14 +312,18 @@ pub fn execute_using_consensus_failure_handler( call_data: &[u8], manager: ExecutionManager, compute_tx: bool, -) -> Result<(Vec, Option, Option>), Box> + mut native_call: Option, +) -> Result<(NativeOrEncoded, Option, Option>), Box> where H: Hasher, Exec: CodeExecutor, B: Backend, T: ChangesTrieStorage, H::Out: Ord + HeapSizeOf, - Handler: FnOnce(Result, Exec::Error>, Result, Exec::Error>) -> Result, Exec::Error> + Handler: FnOnce( + Result, Exec::Error>, + Result, Exec::Error> + ) -> Result, Exec::Error> { let strategy: ExecutionStrategy = (&manager).into(); @@ -325,6 +354,7 @@ where call_data, // attempt to run native first, if we're not directed to run wasm only strategy != ExecutionStrategy::AlwaysWasm, + native_call.take(), ); let (storage_delta, changes_delta) = if compute_tx { let (storage_delta, changes_delta) = externalities.transaction(); @@ -351,6 +381,7 @@ where method, call_data, false, + native_call, ); let (storage_delta, changes_delta) = if compute_tx { let (storage_delta, changes_delta) = externalities.transaction(); @@ -363,9 +394,9 @@ where (result, storage_delta, changes_delta) }; - if (result.is_ok() && wasm_result.is_ok() && result.as_ref().unwrap() == wasm_result.as_ref().unwrap()/* && delta == wasm_delta*/) - || (result.is_err() && wasm_result.is_err()) - { + if (result.is_ok() && wasm_result.is_ok() + && result.as_ref().ok() == wasm_result.as_ref().ok()) + || result.is_err() && wasm_result.is_err() { (result, storage_delta, changes_delta) } else { // Consensus error. @@ -427,7 +458,9 @@ where H::Out: Ord + HeapSizeOf, { let proving_backend = proving_backend::ProvingBackend::new(trie_backend); - let (result, _, _) = execute_using_consensus_failure_handler::, _, _>( + let (result, _, _) = execute_using_consensus_failure_handler:: + , _, _, NeverNativeValue, fn() -> NeverNativeValue> + ( &proving_backend, None, overlay, @@ -436,9 +469,10 @@ where call_data, native_when_possible(), false, + None, )?; let proof = proving_backend.extract_proof(); - Ok((result, proof)) + Ok((result.into_encoded(), proof)) } /// Check execution proof, generated by `prove_execution` call. @@ -472,7 +506,9 @@ where Exec: CodeExecutor, H::Out: Ord + HeapSizeOf, { - execute_using_consensus_failure_handler::, _, _>( + execute_using_consensus_failure_handler:: + , _, _, NeverNativeValue, fn() -> NeverNativeValue> + ( trie_backend, None, overlay, @@ -481,7 +517,8 @@ where call_data, native_when_possible(), false, - ).map(|(result, _, _)| result) + None, + ).map(|(result, _, _)| result.into_encoded()) } /// Generate storage read proof. @@ -588,7 +625,7 @@ mod tests { InMemoryStorage as InMemoryChangesTrieStorage, Configuration as ChangesTrieConfig, }; - use primitives::{Blake2Hasher}; + use primitives::Blake2Hasher; struct DummyCodeExecutor { change_changes_trie_config: bool, @@ -600,24 +637,41 @@ mod tests { impl CodeExecutor for DummyCodeExecutor { type Error = u8; - fn call>( + fn call, R: Encode + Decode + PartialEq, NC: FnOnce() -> R>( &self, ext: &mut E, _method: &str, _data: &[u8], - use_native: bool - ) -> (Result, Self::Error>, bool) { + use_native: bool, + _native_call: Option, + ) -> (Result, Self::Error>, bool) { if self.change_changes_trie_config { - ext.place_storage(well_known_keys::CHANGES_TRIE_CONFIG.to_vec(), Some(ChangesTrieConfig { - digest_interval: 777, - digest_levels: 333, - }.encode())); + ext.place_storage( + well_known_keys::CHANGES_TRIE_CONFIG.to_vec(), + Some( + ChangesTrieConfig { + digest_interval: 777, + digest_levels: 333, + }.encode() + ) + ); } let using_native = use_native && self.native_available; match (using_native, self.native_succeeds, self.fallback_succeeds) { - (true, true, _) | (false, _, true) => - (Ok(vec![ext.storage(b"value1").unwrap()[0] + ext.storage(b"value2").unwrap()[0]]), using_native), + (true, true, _) | (false, _, true) => { + ( + Ok( + NativeOrEncoded::Encoded( + vec![ + ext.storage(b"value1").unwrap()[0] + + ext.storage(b"value2").unwrap()[0] + ] + ) + ), + using_native + ) + }, _ => (Err(0), using_native), } } @@ -646,7 +700,7 @@ mod tests { #[test] fn dual_execution_strategy_detects_consensus_failure() { let mut consensus_failed = false; - assert!(execute_using_consensus_failure_handler( + assert!(execute_using_consensus_failure_handler::<_, _, _, _, _, NeverNativeValue, fn() -> NeverNativeValue>( &trie_backend::tests::test_trie(), Some(&InMemoryChangesTrieStorage::new()), &mut Default::default(), @@ -664,6 +718,7 @@ mod tests { we }), true, + None, ).is_err()); assert!(consensus_failed); } diff --git a/substrate/core/test-client/src/lib.rs b/substrate/core/test-client/src/lib.rs index 66b057350a..c2cd79f3a1 100644 --- a/substrate/core/test-client/src/lib.rs +++ b/substrate/core/test-client/src/lib.rs @@ -50,7 +50,12 @@ mod local_executor { #![allow(missing_docs)] use super::runtime; // TODO: change the macro and pass in the `BlakeHasher` that dispatch needs from here instead - native_executor_instance!(pub LocalExecutor, runtime::api::dispatch, runtime::native_version, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm")); + native_executor_instance!( + pub LocalExecutor, + runtime::api::dispatch, + runtime::native_version, + include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm") + ); } /// Native executor used for tests. @@ -71,7 +76,9 @@ pub fn new() -> client::Client client::Client { +pub fn new_with_changes_trie() + -> client::Client +{ new_with_backend(Arc::new(Backend::new()), true) } @@ -80,9 +87,12 @@ pub fn new_with_changes_trie() -> client::Client( backend: Arc, support_changes_trie: bool -) -> client::Client>, runtime::Block, runtime::RuntimeApi> - where - B: backend::LocalBackend, +) -> client::Client< + B, + client::LocalCallExecutor>, + runtime::Block, + runtime::RuntimeApi +> where B: backend::LocalBackend { let executor = NativeExecutor::new(); client::new_with_backend(backend, executor, genesis_storage(support_changes_trie)).unwrap() diff --git a/substrate/core/test-client/src/trait_tests.rs b/substrate/core/test-client/src/trait_tests.rs index 982c92d291..aef6c75654 100644 --- a/substrate/core/test-client/src/trait_tests.rs +++ b/substrate/core/test-client/src/trait_tests.rs @@ -32,7 +32,7 @@ use runtime::{self, Transfer}; use runtime_primitives::generic::BlockId; /// helper to test the `leaves` implementation for various backends -pub fn test_leaves_for_backend(backend: Arc) where +pub fn test_leaves_for_backend(backend: Arc) where B: backend::LocalBackend, { // block tree: @@ -145,7 +145,7 @@ pub fn test_leaves_for_backend(backend: Arc) where } -pub fn test_blockchain_query_by_number_gets_canonical(backend: Arc) where +pub fn test_blockchain_query_by_number_gets_canonical(backend: Arc) where B: backend::LocalBackend, { // block tree: diff --git a/substrate/core/test-runtime/src/lib.rs b/substrate/core/test-runtime/src/lib.rs index 3d2e9b5ca8..fd87782e38 100644 --- a/substrate/core/test-runtime/src/lib.rs +++ b/substrate/core/test-runtime/src/lib.rs @@ -186,13 +186,14 @@ pub fn changes_trie_config() -> primitives::ChangesTrieConfiguration { } } -pub mod test_api { - use super::AccountId; - - decl_runtime_apis! { - pub trait TestAPI { - fn balance_of(id: AccountId) -> u64; - } +decl_runtime_apis! { + pub trait TestAPI { + fn balance_of(id: AccountId) -> u64; + /// A benchmkark function that adds one to the given value and returns the result. + fn benchmark_add_one(val: &u64) -> u64; + /// A benchmark function that adds one to each value in the given vector and returns the + /// result. + fn benchmark_vector_add_one(vec: &Vec) -> Vec; } } @@ -220,7 +221,7 @@ impl_runtime_apis! { system::execute_block(block) } - fn initialise_block(header: ::Header) { + fn initialise_block(header: &::Header) { system::initialise_block(header) } } @@ -259,10 +260,20 @@ impl_runtime_apis! { } } - impl self::test_api::TestAPI for Runtime { + impl self::TestAPI for Runtime { fn balance_of(id: AccountId) -> u64 { system::balance_of(id) } + + fn benchmark_add_one(val: &u64) -> u64 { + val + 1 + } + + fn benchmark_vector_add_one(vec: &Vec) -> Vec { + let mut vec = vec.clone(); + vec.iter_mut().for_each(|v| *v += 1); + vec + } } impl aura_api::AuraApi for Runtime { diff --git a/substrate/core/test-runtime/src/system.rs b/substrate/core/test-runtime/src/system.rs index d4559b1eb7..5b01ecb500 100644 --- a/substrate/core/test-runtime/src/system.rs +++ b/substrate/core/test-runtime/src/system.rs @@ -62,7 +62,7 @@ pub fn authorities() -> Vec { .collect() } -pub fn initialise_block(header: Header) { +pub fn initialise_block(header: &Header) { // populate environment. ::put(&header.number); ::put(&header.parent_hash); diff --git a/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm index b366072456..991bf00699 100644 Binary files a/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm and b/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm differ diff --git a/substrate/core/transaction-pool/graph/src/pool.rs b/substrate/core/transaction-pool/graph/src/pool.rs index e96d320046..923a4f2295 100644 --- a/substrate/core/transaction-pool/graph/src/pool.rs +++ b/substrate/core/transaction-pool/graph/src/pool.rs @@ -60,7 +60,7 @@ pub trait ChainApi: Send + Sync { type Error: From + error::IntoPoolError; /// Verify extrinsic at given block. - fn validate_transaction(&self, at: &BlockId, uxt: &ExtrinsicFor) -> Result; + fn validate_transaction(&self, at: &BlockId, uxt: ExtrinsicFor) -> Result; /// Returns a block number given the block id. fn block_id_to_number(&self, at: &BlockId) -> Result>, Self::Error>; @@ -105,10 +105,10 @@ impl Pool { bail!(error::Error::from(error::ErrorKind::TemporarilyBanned)) } - match self.api.validate_transaction(at, &xt)? { + match self.api.validate_transaction(at, xt.clone())? { TransactionValidity::Valid { priority, requires, provides, longevity } => { Ok(base::Transaction { - data: xt, + data: xt, hash, priority, requires, @@ -325,7 +325,7 @@ mod tests { type Error = error::Error; /// Verify extrinsic at given block. - fn validate_transaction(&self, at: &BlockId, uxt: &ExtrinsicFor) -> Result { + fn validate_transaction(&self, at: &BlockId, uxt: ExtrinsicFor) -> Result { let block_number = self.block_id_to_number(at)?.unwrap(); let nonce = uxt.transfer().nonce; diff --git a/substrate/core/transaction-pool/src/api.rs b/substrate/core/transaction-pool/src/api.rs index a29010b50c..382f4f6ed8 100644 --- a/substrate/core/transaction-pool/src/api.rs +++ b/substrate/core/transaction-pool/src/api.rs @@ -63,7 +63,7 @@ impl txpool::ChainApi for ChainApi where type Hash = H256; type Error = error::Error; - fn validate_transaction(&self, at: &BlockId, uxt: &txpool::ExtrinsicFor) -> error::Result { + fn validate_transaction(&self, at: &BlockId, uxt: txpool::ExtrinsicFor) -> error::Result { Ok(self.client.runtime_api().validate_transaction(at, uxt)?) } diff --git a/substrate/core/transaction-pool/src/tests.rs b/substrate/core/transaction-pool/src/tests.rs index c79ca5605b..5e00b63ad0 100644 --- a/substrate/core/transaction-pool/src/tests.rs +++ b/substrate/core/transaction-pool/src/tests.rs @@ -40,7 +40,7 @@ impl txpool::ChainApi for TestApi { type Hash = Hash; type Error = error::Error; - fn validate_transaction(&self, at: &BlockId, uxt: &txpool::ExtrinsicFor) -> error::Result { + fn validate_transaction(&self, at: &BlockId, uxt: txpool::ExtrinsicFor) -> error::Result { let expected = index(at); let requires = if expected == uxt.transfer().nonce { vec![] diff --git a/substrate/node/executor/src/lib.rs b/substrate/node/executor/src/lib.rs index af366faf0a..1785a88437 100644 --- a/substrate/node/executor/src/lib.rs +++ b/substrate/node/executor/src/lib.rs @@ -58,8 +58,9 @@ mod tests { use keyring::Keyring; use runtime_support::{Hashable, StorageValue, StorageMap}; use state_machine::{CodeExecutor, Externalities, TestExternalities}; - use primitives::{twox_128, Blake2Hasher, ChangesTrieConfiguration, - ed25519::{Public, Pair}}; + use primitives::{ + twox_128, Blake2Hasher, ChangesTrieConfiguration, ed25519::{Public, Pair}, NeverNativeValue + }; use node_primitives::{Hash, BlockNumber, AccountId}; use runtime_primitives::traits::{Header as HeaderT, Digest as DigestT, Hash as HashT}; use runtime_primitives::{generic, generic::Era, ApplyOutcome, ApplyError, ApplyResult, Perbill}; @@ -135,10 +136,22 @@ mod tests { twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); - let r = executor().call(&mut t, "Core_initialise_block", &vec![].and(&from_block_number(1u64)), true).0; + let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "Core_initialise_block", + &vec![].and(&from_block_number(1u64)), + true, + None, + ).0; assert!(r.is_ok()); - let v = executor().call(&mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), true).0.unwrap(); - let r = ApplyResult::decode(&mut &v[..]).unwrap(); + let v = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "BlockBuilder_apply_extrinsic", + &vec![].and(&xt()), + true, + None, + ).0.unwrap(); + let r = ApplyResult::decode(&mut &v.as_encoded()[..]).unwrap(); assert_eq!(r, Err(ApplyError::CantPay)); } @@ -156,10 +169,22 @@ mod tests { twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); - let r = executor().call(&mut t, "Core_initialise_block", &vec![].and(&from_block_number(1u64)), true).0; + let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "Core_initialise_block", + &vec![].and(&from_block_number(1u64)), + true, + None, + ).0; assert!(r.is_ok()); - let v = executor().call(&mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), true).0.unwrap(); - let r = ApplyResult::decode(&mut &v[..]).unwrap(); + let v = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "BlockBuilder_apply_extrinsic", + &vec![].and(&xt()), + true, + None, + ).0.unwrap(); + let r = ApplyResult::decode(&mut &v.as_encoded()[..]).unwrap(); assert_eq!(r, Err(ApplyError::CantPay)); } @@ -177,9 +202,21 @@ mod tests { twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); - let r = executor().call(&mut t, "Core_initialise_block", &vec![].and(&from_block_number(1u64)), true).0; + let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "Core_initialise_block", + &vec![].and(&from_block_number(1u64)), + true, + None, + ).0; assert!(r.is_ok()); - let r = executor().call(&mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), true).0; + let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "BlockBuilder_apply_extrinsic", + &vec![].and(&xt()), + true, + None, + ).0; assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { @@ -202,9 +239,21 @@ mod tests { twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); - let r = executor().call(&mut t, "Core_initialise_block", &vec![].and(&from_block_number(1u64)), true).0; + let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "Core_initialise_block", + &vec![].and(&from_block_number(1u64)), + true, + None, + ).0; assert!(r.is_ok()); - let r = executor().call(&mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), true).0; + let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "BlockBuilder_apply_extrinsic", + &vec![].and(&xt()), + true, + None, + ).0; assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { @@ -391,7 +440,13 @@ mod tests { fn full_native_block_import_works() { let mut t = new_test_ext(COMPACT_CODE, false); - executor().call(&mut t, "Core_execute_block", &block1(false).0, true).0.unwrap(); + executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "Core_execute_block", + &block1(false).0, + true, + None, + ).0.unwrap(); runtime_io::with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 41); @@ -440,7 +495,13 @@ mod tests { ]); }); - executor().call(&mut t, "Core_execute_block", &block2().0, true).0.unwrap(); + executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "Core_execute_block", + &block2().0, + true, + None, + ).0.unwrap(); runtime_io::with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 30); @@ -686,11 +747,12 @@ mod tests { fn native_big_block_import_succeeds() { let mut t = new_test_ext(COMPACT_CODE, false); - Executor::new().call( + Executor::new().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( &mut t, "Core_execute_block", &block1big().0, - true + true, + None, ).0.unwrap(); } @@ -699,11 +761,12 @@ mod tests { let mut t = new_test_ext(COMPACT_CODE, false); assert!( - Executor::new().call( + Executor::new().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( &mut t, "Core_execute_block", &block1big().0, - false + false, + None, ).0.is_err() ); } @@ -760,7 +823,13 @@ mod tests { #[test] fn full_native_block_import_works_with_changes_trie() { let mut t = new_test_ext(COMPACT_CODE, true); - Executor::new().call(&mut t, "Core_execute_block", &block1(true).0, true).0.unwrap(); + Executor::new().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "Core_execute_block", + &block1(true).0, + true, + None, + ).0.unwrap(); assert!(t.storage_changes_root(Default::default(), 0).is_some()); } diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs index ad6595cbd5..f8cfae1edf 100644 --- a/substrate/node/runtime/src/lib.rs +++ b/substrate/node/runtime/src/lib.rs @@ -279,8 +279,8 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialise_block(header: ::Header) { - Executive::initialise_block(&header) + fn initialise_block(header: &::Header) { + Executive::initialise_block(header) } } @@ -353,7 +353,7 @@ impl_runtime_apis! { } impl fg_primitives::GrandpaApi for Runtime { - fn grandpa_pending_change(digest: DigestFor) + fn grandpa_pending_change(digest: &DigestFor) -> Option>> { for log in digest.logs.iter().filter_map(|l| match l { diff --git a/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm b/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm index e7964a296f..cc77de34eb 100644 Binary files a/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm and b/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm differ diff --git a/substrate/srml/support/src/lib.rs b/substrate/srml/support/src/lib.rs index 3a988426e2..3708129b2c 100644 --- a/substrate/srml/support/src/lib.rs +++ b/substrate/srml/support/src/lib.rs @@ -30,7 +30,7 @@ pub extern crate sr_primitives as runtime_primitives; extern crate srml_metadata; extern crate mashup; -#[macro_use] +#[cfg_attr(test, macro_use)] extern crate srml_support_procedural; #[cfg(test)]