diff --git a/Cargo.lock b/Cargo.lock index 996a22db197..0206b299424 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,11 +13,11 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" dependencies = [ - "gimli 0.27.2", + "gimli 0.27.3", ] [[package]] @@ -203,9 +203,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" [[package]] name = "arc-swap" @@ -221,9 +221,9 @@ checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-stream" @@ -244,18 +244,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] @@ -301,9 +301,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" +checksum = "a6a1de45611fdb535bfde7b7de4fd54f4fd2b17b1737c0a59b69bf9b92074b8c" dependencies = [ "async-trait", "axum-core", @@ -346,16 +346,16 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" dependencies = [ - "addr2line 0.19.0", + "addr2line 0.20.0", "cc", "cfg-if", "libc", - "miniz_oxide 0.6.2", - "object 0.30.4", + "miniz_oxide", + "object 0.31.1", "rustc-demangle", ] @@ -373,9 +373,9 @@ checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" [[package]] name = "basic-toml" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0de75129aa8d0cceaf750b89013f0e08804d6ec61416da787b35ad0d7cddf1" +checksum = "7bfc506e7a2370ec239e1d072507b2a80c833083699d3c6fa176fbb4de8448c6" dependencies = [ "serde", ] @@ -412,9 +412,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.1" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6776fc96284a0bb647b615056fc496d1fe1644a7ab01829818a6d91cae888b84" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" [[package]] name = "bitvec" @@ -497,13 +497,12 @@ checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" [[package]] name = "bstr" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a246e68bb43f6cd9db24bea052a53e40405417c5fb372e3d1a8a7f770a564ef5" +checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" dependencies = [ "memchr", - "once_cell", - "regex-automata", + "regex-automata 0.3.3", "serde", ] @@ -654,7 +653,7 @@ dependencies = [ "bitflags 1.3.2", "clap_derive 3.2.25", "clap_lex 0.2.4", - "indexmap", + "indexmap 1.9.3", "once_cell", "strsim", "termcolor", @@ -663,20 +662,20 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.11" +version = "4.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1640e5cc7fb47dbb8338fd471b105e7ed6c3cb2aeb00c2e067127ffd3764a05d" +checksum = "8f644d0dac522c8b05ddc39aaaccc5b136d5dc4ff216610c5641e3be5becf56c" dependencies = [ "clap_builder", - "clap_derive 4.3.2", + "clap_derive 4.3.12", "once_cell", ] [[package]] name = "clap_builder" -version = "4.3.11" +version = "4.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c59138d527eeaf9b53f35a77fcc1fad9d883116070c63d5de1c7dc7b00c72b" +checksum = "af410122b9778e024f9e0fb35682cc09cc3f85cad5e8d3ba8f47a9702df6e73d" dependencies = [ "anstream", "anstyle", @@ -700,14 +699,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.3.2" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] @@ -776,13 +775,13 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "colored" -version = "2.0.0" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" dependencies = [ - "atty", + "is-terminal", "lazy_static", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -812,9 +811,9 @@ dependencies = [ [[package]] name = "console-subscriber" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ab2224a0311582eb03adba4caaf18644f7b1f10a760803a803b9b605187fc7" +checksum = "d4cf42660ac07fcebed809cfe561dd8730bcd35b075215e6479c516bcd0d11cb" dependencies = [ "console-api", "crossbeam-channel", @@ -867,9 +866,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] @@ -1058,14 +1057,14 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg 1.1.0", "cfg-if", "crossbeam-utils", - "memoffset 0.8.0", + "memoffset 0.9.0", "scopeguard", ] @@ -1081,9 +1080,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if", ] @@ -1106,9 +1105,9 @@ dependencies = [ [[package]] name = "crossterm_winapi" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" dependencies = [ "winapi", ] @@ -1200,9 +1199,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.97" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88abab2f5abbe4c56e8f1fb431b784d710b709888f35755a160e62e33fe38e8" +checksum = "5032837c1384de3708043de9d4e97bb91290faca6c16529a28aa340592a78166" dependencies = [ "cc", "cxxbridge-flags", @@ -1212,9 +1211,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.97" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0c11acd0e63bae27dcd2afced407063312771212b7a823b4fd72d633be30fb" +checksum = "51368b3d0dbf356e10fcbfd455a038503a105ee556f7ee79b6bb8c53a7247456" dependencies = [ "cc", "codespan-reporting", @@ -1222,31 +1221,31 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] name = "cxxbridge-flags" -version = "1.0.97" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3816ed957c008ccd4728485511e3d9aaf7db419aa321e3d2c5a2f3411e36c8" +checksum = "0d9062157072e4aafc8e56ceaf8325ce850c5ae37578c852a0d4de2cecdded13" [[package]] name = "cxxbridge-macro" -version = "1.0.97" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26acccf6f445af85ea056362561a24ef56cdc15fcc685f03aec50b9c702cb6d" +checksum = "cf01e8a540f5a4e0f284595834f81cf88572f244b768f051724537afa99a2545" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] name = "darling" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -1254,37 +1253,37 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] name = "darling_macro" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] name = "dashmap" -version = "5.4.0" +version = "5.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +checksum = "6943ae99c34386c84a470c499d3414f66502a41340aa895406e0d2e4a207b91d" dependencies = [ "cfg-if", - "hashbrown 0.12.3", + "hashbrown 0.14.0", "lock_api", "once_cell", "parking_lot_core", @@ -1377,14 +1376,14 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] name = "dissimilar" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "210ec60ae7d710bed8683e333e9d2855a8a56a3e9892b38bad3bb0d4d29b0d5e" +checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632" [[package]] name = "duct" @@ -1406,9 +1405,9 @@ checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "dyn-clone" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" +checksum = "304e6508efa593091e97a9abbc10f90aa7ca635b6d2784feff3c89d41dd12272" [[package]] name = "ecdsa" @@ -1495,11 +1494,17 @@ dependencies = [ "termcolor", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "erased-serde" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2b0c2380453a92ea8b6c8e5f64ecaafccddde8ceab55ff7a8ac1029f894569" +checksum = "da96524cc884f6558f1769b6c46686af2fe8e8b4cd253bd5a3cdba8181b8e070" dependencies = [ "serde", ] @@ -1593,6 +1598,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + [[package]] name = "ff" version = "0.10.1" @@ -1652,7 +1663,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", - "miniz_oxide 0.7.1", + "miniz_oxide", ] [[package]] @@ -1747,7 +1758,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] @@ -1871,24 +1882,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" dependencies = [ "fallible-iterator", - "indexmap", + "indexmap 1.9.3", "stable_deref_trait", ] [[package]] name = "gimli" -version = "0.27.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" [[package]] name = "gix" -version = "0.44.1" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bf41b61f7df395284f7a579c0fa1a7e012c5aede655174d4e91299ef1cac643" +checksum = "c1e74cea676de7f53a79f3c0365812b11f6814b81e671b8ee4abae6ca09c7881" dependencies = [ "gix-actor", "gix-attributes", + "gix-commitgraph", "gix-config", "gix-credentials", "gix-date", @@ -1903,6 +1915,7 @@ dependencies = [ "gix-index", "gix-lock", "gix-mailmap", + "gix-negotiate", "gix-object", "gix-odb", "gix-pack", @@ -1913,6 +1926,7 @@ dependencies = [ "gix-revision", "gix-sec", "gix-tempfile", + "gix-trace", "gix-traverse", "gix-url", "gix-utils", @@ -1928,9 +1942,9 @@ dependencies = [ [[package]] name = "gix-actor" -version = "0.20.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848efa0f1210cea8638f95691c82a46f98a74b9e3524f01d4955ebc25a8f84f3" +checksum = "1969b77b9ee4cc1755c841987ec6f7622aaca95e952bcafb76973ae59d1b8716" dependencies = [ "bstr", "btoi", @@ -1942,9 +1956,9 @@ dependencies = [ [[package]] name = "gix-attributes" -version = "0.12.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3015baa01ad2122fbcaab7863c857a603eb7b7ec12ac8141207c42c6439805e2" +checksum = "e3772b0129dcd1fc73e985bbd08a1482d082097d2915cb1ee31ce8092b8e4434" dependencies = [ "bstr", "gix-glob", @@ -1959,36 +1973,50 @@ dependencies = [ [[package]] name = "gix-bitmap" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc02feb20ad313d52a450852f2005c2205d24f851e74d82b7807cbe12c371667" +checksum = "311e2fa997be6560c564b070c5da2d56d038b645a94e1e5796d5d85a350da33c" dependencies = [ "thiserror", ] [[package]] name = "gix-chunk" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7acf3bc6c4b91e8fb260086daf5e105ea3a6d913f5fd3318137f7e309d6e540" +checksum = "39db5ed0fc0a2e9b1b8265993f7efdbc30379dec268f3b91b7af0c2de4672fdd" dependencies = [ "thiserror", ] [[package]] name = "gix-command" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6141b70cfb21255223e42f3379855037cbbe8673b58dd8318d2f09b516fad1" +checksum = "bb49ab557a37b0abb2415bca2b10e541277dff0565deb5bd5e99fd95f93f51eb" dependencies = [ "bstr", ] +[[package]] +name = "gix-commitgraph" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed42baa50075d41c1a0931074ce1a97c5797c7c6fe7591d9f1f2dcd448532c26" +dependencies = [ + "bstr", + "gix-chunk", + "gix-features", + "gix-hash", + "memmap2", + "thiserror", +] + [[package]] name = "gix-config" -version = "0.22.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d252a0eddb6df74600d3d8872dc9fe98835a7da43110411d705b682f49d4ac1" +checksum = "817688c7005a716d9363e267913526adea402dabd947f4ba63842d10cc5132af" dependencies = [ "bstr", "gix-config-value", @@ -2008,11 +2036,11 @@ dependencies = [ [[package]] name = "gix-config-value" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f216df1c33e6e1555923eff0096858a879e8aaadd35b5d788641e4e8064c892" +checksum = "83960be5e99266bcf55dae5a24731bbd39f643bfb68f27e939d6b06836b5b87d" dependencies = [ - "bitflags 2.3.1", + "bitflags 2.3.3", "bstr", "gix-path", "libc", @@ -2021,9 +2049,9 @@ dependencies = [ [[package]] name = "gix-credentials" -version = "0.14.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4874a4fc11ffa844a3c2b87a66957bda30a73b577ef1acf15ac34df5745de5ff" +checksum = "75a75565e0e6e7f80cfa4eb1b05cc448c6846ddd48dcf413a28875fbc11ee9af" dependencies = [ "bstr", "gix-command", @@ -2037,21 +2065,21 @@ dependencies = [ [[package]] name = "gix-date" -version = "0.5.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc164145670e9130a60a21670d9b6f0f4f8de04e5dd256c51fa5a0340c625902" +checksum = "8e9a04a1d2387c955ec91059d56b673000dd24f3c07cad08ed253e36381782bf" dependencies = [ "bstr", "itoa", "thiserror", - "time 0.3.22", + "time 0.3.23", ] [[package]] name = "gix-diff" -version = "0.29.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "644a0f2768bc42d7a69289ada80c9e15c589caefc6a315d2307202df83ed1186" +checksum = "aaf5d9b9b521b284ebe53ee69eee33341835ec70edc314f36b2100ea81396121" dependencies = [ "gix-hash", "gix-object", @@ -2061,9 +2089,9 @@ dependencies = [ [[package]] name = "gix-discover" -version = "0.18.1" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a6b61363e63e7cdaa3e6f96acb0257ebdb3d8883e21eba5930c99f07f0a5fc0" +checksum = "272aad20dc63dedba76615373dd8885fb5aebe4795e5b5b0aa2a24e63c82085c" dependencies = [ "bstr", "dunce", @@ -2076,13 +2104,14 @@ dependencies = [ [[package]] name = "gix-features" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf69b0f5c701cc3ae22d3204b671907668f6437ca88862d355eaf9bc47a4f897" +checksum = "06142d8cff5d17509399b04052b64d2f9b3a311d5cff0b1a32b220f62cd0d595" dependencies = [ "crc32fast", "flate2", "gix-hash", + "gix-trace", "libc", "once_cell", "prodash", @@ -2093,20 +2122,20 @@ dependencies = [ [[package]] name = "gix-fs" -version = "0.1.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b37a1832f691fdc09910bd267f9a2e413737c1f9ec68c6e31f9e802616278a9" +checksum = "bb15956bc0256594c62a2399fcf6958a02a11724217eddfdc2b49b21b6292496" dependencies = [ "gix-features", ] [[package]] name = "gix-glob" -version = "0.7.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c07c98204529ac3f24b34754540a852593d2a4c7349008df389240266627a72a" +checksum = "c18bdff83143d61e7d60da6183b87542a870d026b2a2d0b30170b8e9c0cd321a" dependencies = [ - "bitflags 2.3.1", + "bitflags 2.3.3", "bstr", "gix-features", "gix-path", @@ -2114,9 +2143,9 @@ dependencies = [ [[package]] name = "gix-hash" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee181c85d3955f54c4426e6bfaeeada4428692e1a39b8788c2ac7785fc301dd8" +checksum = "a0dd58cdbe7ffa4032fc111864c80d5f8cecd9a2c9736c97ae7e5be834188272" dependencies = [ "hex", "thiserror", @@ -2124,20 +2153,20 @@ dependencies = [ [[package]] name = "gix-hashtable" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd259bd0d96e6153e357a8cdaca76c48e103fd34208b6c0ce77b1ad995834bd2" +checksum = "9e133bc56d938eaec1c675af7c681a51de9662b0ada779f45607b967a10da77a" dependencies = [ "gix-hash", - "hashbrown 0.13.2", + "hashbrown 0.14.0", "parking_lot", ] [[package]] name = "gix-ignore" -version = "0.2.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba205b6df563e2906768bb22834c82eb46c5fdfcd86ba2c347270bc8309a05b2" +checksum = "ca801f2d0535210f77b33e2c067d565aedecacc82f1b3dbce26da1388ebc4634" dependencies = [ "bstr", "gix-glob", @@ -2147,11 +2176,11 @@ dependencies = [ [[package]] name = "gix-index" -version = "0.16.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f39c1ccc8f1912cbbd5191efc28dbc5f0d0598042aa56bc09427b7c34efab3ba" +checksum = "68099abdf6ee50ae3c897e8b05de96871cbe54d52a37cdf559101f911b883562" dependencies = [ - "bitflags 2.3.1", + "bitflags 2.3.3", "bstr", "btoi", "filetime", @@ -2169,9 +2198,9 @@ dependencies = [ [[package]] name = "gix-lock" -version = "5.0.1" +version = "7.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c693d7f05730fa74a7c467150adc7cea393518410c65f0672f80226b8111555" +checksum = "714bcb13627995ac33716e9c5e4d25612b19947845395f64d2a9cbe6007728e4" dependencies = [ "gix-tempfile", "gix-utils", @@ -2180,24 +2209,42 @@ dependencies = [ [[package]] name = "gix-mailmap" -version = "0.12.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8856cec3bdc3610c06970d28b6cb20a0c6621621cf9a8ec48cbd23f2630f362" +checksum = "1787e3c37fc43b1f7c0e3be6196c6837b3ba5f869190dfeaa444b816f0a7f34b" dependencies = [ "bstr", "gix-actor", + "gix-date", + "thiserror", +] + +[[package]] +name = "gix-negotiate" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7bce64d4452dd609f44d04b14b29da2e0ad2c45fcdf4ce1472a5f5f8ec21c2" +dependencies = [ + "bitflags 2.3.3", + "gix-commitgraph", + "gix-date", + "gix-hash", + "gix-object", + "gix-revwalk", + "smallvec", "thiserror", ] [[package]] name = "gix-object" -version = "0.29.2" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d96bd620fd08accdd37f70b2183cfa0b001b4f1c6ade8b7f6e15cb3d9e261ce" +checksum = "a953f3d7ffad16734aa3ab1d05807972c80e339d1bd9dde03e0198716b99e2a6" dependencies = [ "bstr", "btoi", "gix-actor", + "gix-date", "gix-features", "gix-hash", "gix-validate", @@ -2210,11 +2257,12 @@ dependencies = [ [[package]] name = "gix-odb" -version = "0.45.0" +version = "0.49.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca2f324aa67672b6d0f2c0fa93f96eb6a7029d260e4c1df5dce3c015f5e5add" +checksum = "f6418cff00ecc2713b58c8e04bff30dda808fbba1a080e7248b299d069894a01" dependencies = [ "arc-swap", + "gix-date", "gix-features", "gix-hash", "gix-object", @@ -2228,9 +2276,9 @@ dependencies = [ [[package]] name = "gix-pack" -version = "0.35.0" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "164a515900a83257ae4aa80e741655bee7a2e39113fb535d7a5ac623b445ff20" +checksum = "414935138d90043ea5898de7a93f02c2558e52652492719470e203ef26a8fd0a" dependencies = [ "clru", "gix-chunk", @@ -2250,11 +2298,12 @@ dependencies = [ [[package]] name = "gix-path" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1226f2e50adeb4d76c754c1856c06f13a24cad1624801653fbf09b869e5b808" +checksum = "dfca182d2575ded2ed38280f1ebf75cd5d3790b77e0872de07854cf085821fbe" dependencies = [ "bstr", + "gix-trace", "home", "once_cell", "thiserror", @@ -2262,22 +2311,22 @@ dependencies = [ [[package]] name = "gix-prompt" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e15fe57fa48572b7d3bf465d6a2a0351cd3c55cba74fd5f0b9c23689f9c1a31e" +checksum = "8dfd363fd89a40c1e7bff9c9c1b136cd2002480f724b0c627c1bc771cd5480ec" dependencies = [ "gix-command", "gix-config-value", "parking_lot", - "rustix 0.37.19", + "rustix 0.37.23", "thiserror", ] [[package]] name = "gix-quote" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29d59489bff95b06dcdabe763b7266d3dc0a628cac1ac1caf65a7ca0a43eeae0" +checksum = "3874de636c2526de26a3405b8024b23ef1a327bebf4845d770d00d48700b6a40" dependencies = [ "bstr", "btoi", @@ -2286,11 +2335,12 @@ dependencies = [ [[package]] name = "gix-ref" -version = "0.29.1" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e03989e9d49954368e1b526578230fc7189d1634acdfbe79e9ba1de717e15d5" +checksum = "39453f4e5f23cddc2e6e4cca2ba20adfdbec29379e3ca829714dfe98ae068ccd" dependencies = [ "gix-actor", + "gix-date", "gix-features", "gix-fs", "gix-hash", @@ -2306,9 +2356,9 @@ dependencies = [ [[package]] name = "gix-refspec" -version = "0.10.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6ea733820df67e4cd7797deb12727905824d8f5b7c59d943c456d314475892" +checksum = "b8e76ff1f82fba295a121e31ab02f69642994e532c45c0c899aa393f4b740302" dependencies = [ "bstr", "gix-hash", @@ -2320,25 +2370,41 @@ dependencies = [ [[package]] name = "gix-revision" -version = "0.13.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "810f35e9afeccca999d5d348b239f9c162353127d2e13ff3240e31b919e35476" +checksum = "237428a7d3978e8572964e1e45d984027c2acc94df47e594baa6c4b0da7c9922" dependencies = [ "bstr", "gix-date", "gix-hash", "gix-hashtable", "gix-object", + "gix-revwalk", + "thiserror", +] + +[[package]] +name = "gix-revwalk" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "028d50fcaf8326a8f79a359490d9ca9fb4e2b51ac9ac86503560d0bcc888d2eb" +dependencies = [ + "gix-commitgraph", + "gix-date", + "gix-hash", + "gix-hashtable", + "gix-object", + "smallvec", "thiserror", ] [[package]] name = "gix-sec" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b7b38b766eb95dcc5350a9c450030b69892c0902fa35f4a6d0809273bd9dae" +checksum = "ede298863db2a0574a14070991710551e76d1f47c9783b62d4fcbca17f56371c" dependencies = [ - "bitflags 2.3.1", + "bitflags 2.3.3", "gix-path", "libc", "windows", @@ -2346,9 +2412,9 @@ dependencies = [ [[package]] name = "gix-tempfile" -version = "5.0.3" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71a0d32f34e71e86586124225caefd78dabc605d0486de580d717653addf182" +checksum = "4fac8310c17406ea619af72f42ee46dac795110f68f41b4f4fa231b69889c6a2" dependencies = [ "gix-fs", "libc", @@ -2359,23 +2425,33 @@ dependencies = [ "tempfile", ] +[[package]] +name = "gix-trace" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "103eac621617be3ebe0605c9065ca51a223279a23218aaf67d10daa6e452f663" + [[package]] name = "gix-traverse" -version = "0.25.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5be1e807f288c33bb005075111886cceb43ed8a167b3182a0f62c186e2a0dd1" +checksum = "e3cdfd54598db4fae57d5ae6f52958422b2d13382d2745796bfe5c8015ffa86e" dependencies = [ + "gix-commitgraph", + "gix-date", "gix-hash", "gix-hashtable", "gix-object", + "gix-revwalk", + "smallvec", "thiserror", ] [[package]] name = "gix-url" -version = "0.18.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc77f89054297cc81491e31f1bab4027e554b5ef742a44bd7035db9a0f78b76" +checksum = "beaede6dbc83f408b19adfd95bb52f1dbf01fb8862c3faf6c6243e2e67fcdfa1" dependencies = [ "bstr", "gix-features", @@ -2387,18 +2463,18 @@ dependencies = [ [[package]] name = "gix-utils" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbcfcb150c7ef553d76988467d223254045bdcad0dc6724890f32fbe96415da5" +checksum = "7058c94f4164fcf5b8457d35f6d8f6e1007f9f7f938c9c7684a7e01d23c6ddde" dependencies = [ - "fastrand", + "fastrand 2.0.0", ] [[package]] name = "gix-validate" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ea5845b506c7728b9d89f4227cc369a5fc5a1d5b26c3add0f0d323413a3a60" +checksum = "8d092b594c8af00a3a31fe526d363ee8a51a6f29d8496cdb991ed2f01ec0ec13" dependencies = [ "bstr", "thiserror", @@ -2406,9 +2482,9 @@ dependencies = [ [[package]] name = "gix-worktree" -version = "0.17.1" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69eaff0ae973a9d37c40f02ae5ae50fa726c8fc2fd3ab79d0a19eb61975aafa" +checksum = "c1363b9aa66b9e14412ac04e1f759827203f491729d92172535a8ce6cde02efa" dependencies = [ "bstr", "filetime", @@ -2444,9 +2520,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ "bytes", "fnv", @@ -2454,7 +2530,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", @@ -2484,9 +2560,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.13.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" [[package]] name = "hdrhistogram" @@ -2543,18 +2619,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "hex" @@ -2642,9 +2709,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.26" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", @@ -2759,6 +2826,16 @@ dependencies = [ "serde", ] +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + [[package]] name = "inquire" version = "0.6.2" @@ -2812,7 +2889,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.1", + "hermit-abi 0.3.2", "libc", "windows-sys 0.48.0", ] @@ -2823,6 +2900,7 @@ version = "2.0.0-pre-rc.16" dependencies = [ "async-trait", "color-eyre", + "dashmap", "displaydoc", "eyre", "futures", @@ -2938,6 +3016,7 @@ dependencies = [ "iroha_data_model", "iroha_primitives", "json5", + "once_cell", "path-absolutize", "proptest", "serde", @@ -3395,13 +3474,12 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes 1.0.11", - "rustix 0.37.19", + "hermit-abi 0.3.2", + "rustix 0.38.4", "windows-sys 0.48.0", ] @@ -3422,9 +3500,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "ittapi-rs" @@ -3446,9 +3524,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -3480,7 +3558,7 @@ dependencies = [ name = "kagami" version = "2.0.0-pre-rc.16" dependencies = [ - "clap 4.3.11", + "clap 4.3.15", "color-eyre", "derive_more", "duct", @@ -3528,7 +3606,7 @@ dependencies = [ name = "kura_inspector" version = "2.0.0-pre-rc.16" dependencies = [ - "clap 4.3.11", + "clap 4.3.15", "iroha_core", "iroha_data_model", "iroha_version", @@ -3548,9 +3626,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.146" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libm" @@ -3560,9 +3638,9 @@ checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "link-cplusplus" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" dependencies = [ "cc", ] @@ -3579,6 +3657,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "linux-raw-sys" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" + [[package]] name = "lock_api" version = "0.4.10" @@ -3591,9 +3675,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.18" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "mach" @@ -3610,7 +3694,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata", + "regex-automata 0.1.10", ] [[package]] @@ -3631,14 +3715,14 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffc89ccdc6e10d6907450f753537ebc5c5d3460d2e4e62ea74bd571db62c0f9e" dependencies = [ - "rustix 0.37.19", + "rustix 0.37.23", ] [[package]] name = "memmap2" -version = "0.5.10" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" dependencies = [ "libc", ] @@ -3654,9 +3738,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg 1.1.0", ] @@ -3683,15 +3767,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" -dependencies = [ - "adler", -] - [[package]] name = "miniz_oxide" version = "0.7.1" @@ -3802,11 +3877,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi 0.3.2", "libc", ] @@ -3827,15 +3902,15 @@ checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" dependencies = [ "crc32fast", "hashbrown 0.11.2", - "indexmap", + "indexmap 1.9.3", "memchr", ] [[package]] name = "object" -version = "0.30.4" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" dependencies = [ "memchr", ] @@ -3866,9 +3941,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.54" +version = "0.10.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019" +checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" dependencies = [ "bitflags 1.3.2", "cfg-if", @@ -3887,7 +3962,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] @@ -3907,9 +3982,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.88" +version = "0.9.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617" +checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" dependencies = [ "cc", "libc", @@ -3930,9 +4005,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.5.0" +version = "6.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" +checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" [[package]] name = "overload" @@ -3951,9 +4026,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.5.0" +version = "3.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ddb756ca205bd108aee3c62c6d3c994e1df84a59b9d6d4a5ea42ee1fd5a9a28" +checksum = "dd8e946cc0cc711189c0b0249fb8b599cbeeab9784d83c415719368bb8d4ac64" dependencies = [ "arrayvec", "bitvec", @@ -3965,9 +4040,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.1.4" +version = "3.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b26a931f824dd4eca30b3e43bb4f31cd5f0d3a403c5f5ff27106b805bfde7b" +checksum = "2a296c3079b5fefbc499e1de58dc26c09b1b9a5952d26694ee89f04a43ebbb3e" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -3979,7 +4054,7 @@ dependencies = [ name = "parity_scale_decoder" version = "2.0.0-pre-rc.16" dependencies = [ - "clap 4.3.11", + "clap 4.3.15", "colored", "eyre", "iroha_crypto", @@ -4017,14 +4092,14 @@ dependencies = [ "redox_syscall 0.3.5", "smallvec", "thread-id", - "windows-targets 0.48.0", + "windows-targets 0.48.1", ] [[package]] name = "paste" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "path-absolutize" @@ -4058,9 +4133,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.6.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e68e84bfb01f0507134eac1e9b410a12ba379d064eab48c50ba4ce329a527b70" +checksum = "0d2d1d55045829d65aad9d389139882ad623b33b904e7c9f1b10c5b8927298e5" dependencies = [ "thiserror", "ucd-trie", @@ -4068,9 +4143,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.6.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b79d4c71c865a25a4322296122e3924d30bc8ee0834c8bfc8b95f7f054afbfb" +checksum = "5f94bca7e7a599d89dea5dfa309e217e7906c3c007fb9c3299c40b10d6a315d3" dependencies = [ "pest", "pest_generator", @@ -4078,26 +4153,26 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.6.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c435bf1076437b851ebc8edc3a18442796b30f1728ffea6262d59bbe28b077e" +checksum = "99d490fe7e8556575ff6911e45567ab95e71617f43781e5c05490dc8d75c965c" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] name = "pest_meta" -version = "2.6.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "745a452f8eb71e39ffd8ee32b3c5f51d03845f99786fa9b68db6ff509c505411" +checksum = "2674c66ebb4b4d9036012091b537aae5878970d6999f81a265034d85b136b341" dependencies = [ "once_cell", "pest", - "sha2 0.10.6", + "sha2 0.10.7", ] [[package]] @@ -4107,34 +4182,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" dependencies = [ "fixedbitset", - "indexmap", + "indexmap 1.9.3", ] [[package]] name = "pin-project" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" [[package]] name = "pin-utils" @@ -4160,9 +4235,9 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "plotters" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" dependencies = [ "num-traits", "plotters-backend", @@ -4173,15 +4248,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" [[package]] name = "plotters-svg" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" +checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" dependencies = [ "plotters-backend", ] @@ -4249,18 +4324,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] [[package]] name = "prodash" -version = "23.1.2" +version = "25.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9516b775656bc3e8985e19cd4b8c0c0de045095074e453d2c0a513b5f978392d" +checksum = "c236e70b7f9b9ea00d33c69f63ec1ae6e9ae96118923cd37bd4e9c7396f0b107" [[package]] name = "prometheus" @@ -4345,9 +4420,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.28" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" dependencies = [ "proc-macro2", ] @@ -4594,13 +4669,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.4" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.2", + "regex-automata 0.3.3", + "regex-syntax 0.7.4", ] [[package]] @@ -4612,6 +4688,17 @@ dependencies = [ "regex-syntax 0.6.29", ] +[[package]] +name = "regex-automata" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.4", +] + [[package]] name = "regex-syntax" version = "0.6.29" @@ -4620,9 +4707,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "region" @@ -4650,9 +4737,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.35.13" +version = "0.35.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727a1a6d65f786ec22df8a81ca3121107f235970dc1705ed681d3e6e8b9cd5f9" +checksum = "6380889b07a03b5ecf1d44dc9ede6fd2145d84b502a2a9ca0b03c48e0cc3220f" dependencies = [ "bitflags 1.3.2", "errno 0.2.8", @@ -4664,9 +4751,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.19" +version = "0.37.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" dependencies = [ "bitflags 1.3.2", "errno 0.3.1", @@ -4676,20 +4763,33 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "rustix" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +dependencies = [ + "bitflags 2.3.3", + "errno 0.3.1", + "libc", + "linux-raw-sys 0.4.3", + "windows-sys 0.48.0", +] + [[package]] name = "rustls-pemfile" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ "base64 0.21.2", ] [[package]] name = "rustversion" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "rusty-fork" @@ -4705,9 +4805,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "same-file" @@ -4720,11 +4820,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] @@ -4735,15 +4835,15 @@ checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scratch" -version = "1.0.5" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" +checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" [[package]] name = "sealed" @@ -4754,7 +4854,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] @@ -4802,18 +4902,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.163" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.9" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" +checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" dependencies = [ "serde", ] @@ -4830,20 +4930,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.163" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] name = "serde_json" -version = "1.0.99" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" +checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" dependencies = [ "itoa", "ryu", @@ -4881,16 +4981,16 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] name = "serde_yaml" -version = "0.9.21" +version = "0.9.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9d684e3ec7de3bf5466b32bd75303ac16f0736426e5a4e0d6e489559ce1249c" +checksum = "bd5f51e3fdb5b9cdd1577e1cb7a733474191b1aca6a72c2e50913241632c1180" dependencies = [ - "indexmap", + "indexmap 2.0.0", "itoa", "ryu", "serde", @@ -4979,9 +5079,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", @@ -4990,12 +5090,15 @@ dependencies = [ [[package]] name = "sha256" -version = "1.1.4" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a975c1bc0941703000eaf232c4d8ce188d8d5408d6344b6b2c8c6262772828" +checksum = "f894f93906f2a96d3a75a60362f790e71247c588d9f87e97796db1e94bcb808e" dependencies = [ + "async-trait", + "bytes", "hex", - "sha2 0.10.6", + "sha2 0.10.7", + "tokio", ] [[package]] @@ -5050,9 +5153,9 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" [[package]] name = "signal-hook" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" +checksum = "b824b6e687aff278cdbf3b36f07aa52d4bd4099699324d5da86a2ebce3aa00b3" dependencies = [ "libc", "signal-hook-registry", @@ -5115,9 +5218,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" dependencies = [ "serde", ] @@ -5255,9 +5358,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.23" +version = "2.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" +checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" dependencies = [ "proc-macro2", "quote", @@ -5290,9 +5393,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.7" +version = "0.12.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd1ba337640d60c3e96bc6f0638a939b9c9a7f2c316a1598c279828b3d1dc8c5" +checksum = "df8e77cb757a61f51b947ec4a7e3646efd825b73561db1c232a8ccb639e611a0" [[package]] name = "tempfile" @@ -5302,9 +5405,9 @@ checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ "autocfg 1.1.0", "cfg-if", - "fastrand", + "fastrand 1.9.0", "redox_syscall 0.3.5", - "rustix 0.37.19", + "rustix 0.37.23", "windows-sys 0.48.0", ] @@ -5327,6 +5430,7 @@ dependencies = [ "iroha_client", "iroha_config", "iroha_core", + "iroha_crypto", "iroha_data_model", "iroha_genesis", "iroha_logger", @@ -5354,22 +5458,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] @@ -5412,9 +5516,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" dependencies = [ "itoa", "libc", @@ -5432,9 +5536,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" dependencies = [ "time-core", ] @@ -5466,11 +5570,12 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.2" +version = "1.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" dependencies = [ "autocfg 1.1.0", + "backtrace", "bytes", "libc", "mio", @@ -5501,7 +5606,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] @@ -5588,17 +5693,17 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" [[package]] name = "toml_edit" -version = "0.19.10" +version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ - "indexmap", + "indexmap 2.0.0", "toml_datetime", "winnow", ] @@ -5639,7 +5744,7 @@ checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ "futures-core", "futures-util", - "indexmap", + "indexmap 1.9.3", "pin-project", "pin-project-lite", "rand 0.8.5", @@ -5678,27 +5783,27 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] name = "tracing-bunyan-formatter" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a348912d4e90923cb93343691d3be97e3409607363706c400fc935bb032fb0" +checksum = "464ce79ea7f689ca56d90a9c5563e803a4b61b2695e789205644ed8e8101e6bf" dependencies = [ "ahash 0.8.3", "gethostname", "log", "serde", "serde_json", - "time 0.3.22", + "time 0.3.23", "tracing", "tracing-core", "tracing-log", @@ -5782,9 +5887,9 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "trybuild" -version = "1.0.80" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501dbdbb99861e4ab6b60eb6a7493956a9defb644fd034bc4a5ef27c693c8a3a" +checksum = "04366e99ff743345622cd00af2af01d711dc2d1ef59250d7347698d21b546729" dependencies = [ "basic-toml", "glob", @@ -5861,9 +5966,9 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucd-trie" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "unarray" @@ -5894,9 +5999,9 @@ checksum = "98e90c70c9f0d4d1ee6d0a7d04aa06cb9bbd53d8cfbdd62a0269a7c2eb640552" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-normalization" @@ -5946,9 +6051,9 @@ dependencies = [ [[package]] name = "unsafe-libyaml" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1865806a559042e51ab5414598446a5871b561d21b6764f2eabb0dd481d880a6" +checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" [[package]] name = "url" @@ -6033,14 +6138,14 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vergen" -version = "8.2.1" +version = "8.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b3c89c2c7e50f33e4d35527e5bf9c11d6d132226dbbd1753f0fbe9f19ef88c6" +checksum = "bbc5ad0d9d26b2c49a5ab7da76c3e79d3ee37e7821799f8223fcb8f2f391a2e7" dependencies = [ "anyhow", "gix", "rustversion", - "time 0.3.22", + "time 0.3.23", ] [[package]] @@ -6070,11 +6175,10 @@ dependencies = [ [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -6129,9 +6233,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -6139,24 +6243,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6164,28 +6268,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-encoder" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18c41dbd92eaebf3612a39be316540b8377c871cb9bde6b064af962984912881" +checksum = "06a3d1b4a575ffb873679402b2aedb3117555eb65c27b1b86c8a91e574bc2a2a" dependencies = [ "leb128", ] @@ -6236,7 +6340,7 @@ version = "0.86.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bcbfe95447da2aa7ff171857fc8427513eb57c75a729bb190e974dc695e8f5c" dependencies = [ - "indexmap", + "indexmap 1.9.3", ] [[package]] @@ -6250,7 +6354,7 @@ dependencies = [ "backtrace", "bincode", "cfg-if", - "indexmap", + "indexmap 1.9.3", "lazy_static", "libc", "log", @@ -6285,7 +6389,7 @@ dependencies = [ "directories-next", "file-per-thread-logger", "log", - "rustix 0.35.13", + "rustix 0.35.14", "serde", "sha2 0.9.9", "toml", @@ -6324,7 +6428,7 @@ dependencies = [ "anyhow", "cranelift-entity", "gimli 0.26.2", - "indexmap", + "indexmap 1.9.3", "log", "more-asserts", "object 0.28.4", @@ -6343,7 +6447,7 @@ checksum = "2f6aba0b317746e8213d1f36a4c51974e66e69c1f05bfc09ed29b4d4bda290eb" dependencies = [ "cc", "cfg-if", - "rustix 0.35.13", + "rustix 0.35.14", "windows-sys 0.36.1", ] @@ -6364,7 +6468,7 @@ dependencies = [ "object 0.28.4", "region", "rustc-demangle", - "rustix 0.35.13", + "rustix 0.35.14", "serde", "target-lexicon", "thiserror", @@ -6382,7 +6486,7 @@ checksum = "55e23273fddce8cab149a0743c46932bf4910268641397ed86b46854b089f38f" dependencies = [ "lazy_static", "object 0.28.4", - "rustix 0.35.13", + "rustix 0.35.14", ] [[package]] @@ -6395,7 +6499,7 @@ dependencies = [ "backtrace", "cc", "cfg-if", - "indexmap", + "indexmap 1.9.3", "libc", "log", "mach", @@ -6404,7 +6508,7 @@ dependencies = [ "more-asserts", "rand 0.8.5", "region", - "rustix 0.35.13", + "rustix 0.35.14", "thiserror", "wasmtime-environ", "wasmtime-fiber", @@ -6426,9 +6530,9 @@ dependencies = [ [[package]] name = "wast" -version = "60.0.0" +version = "62.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd06cc744b536e30387e72a48fdd492105b9c938bb4f415c39c616a7a0a697ad" +checksum = "c7f7ee878019d69436895f019b65f62c33da63595d8e857cbdc87c13ecb29a32" dependencies = [ "leb128", "memchr", @@ -6438,18 +6542,18 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.66" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5abe520f0ab205366e9ac7d3e6b2fc71de44e32a2b58f2ec871b6b575bdcea3b" +checksum = "295572bf24aa5b685a971a83ad3e8b6e684aaad8a9be24bc7bf59bed84cc1c08" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", @@ -6508,7 +6612,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.1", ] [[package]] @@ -6554,7 +6658,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.1", ] [[package]] @@ -6574,9 +6678,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ "windows_aarch64_gnullvm 0.48.0", "windows_aarch64_msvc 0.48.0", @@ -6703,9 +6807,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.4.6" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" +checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7" dependencies = [ "memchr", ] @@ -6747,7 +6851,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.26", ] [[package]] diff --git a/cli/Cargo.toml b/cli/Cargo.toml index fc07c845864..328ebcae528 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -67,6 +67,7 @@ thiserror = { workspace = true } displaydoc = { workspace = true } tokio = { workspace = true, features = ["sync", "time", "rt", "io-util", "rt-multi-thread", "macros", "fs", "signal"] } warp = { workspace = true, features = ["multipart", "websocket"] } +dashmap = "5.4.0" serial_test = "0.8.0" once_cell = { workspace = true } owo-colors = { workspace = true, features = ["supports-colors"] } diff --git a/cli/src/stream.rs b/cli/src/stream.rs index ade044472b7..340923c9426 100644 --- a/cli/src/stream.rs +++ b/cli/src/stream.rs @@ -13,7 +13,7 @@ const TIMEOUT: Duration = Duration::from_millis(10_000); const TIMEOUT: Duration = Duration::from_millis(1000); /// Error type with generic for actual Stream/Sink error type -#[derive(thiserror::Error, displaydoc::Display, Debug)] +#[derive(Debug, displaydoc::Display, thiserror::Error)] #[ignore_extra_doc_attributes] pub enum Error where diff --git a/cli/src/torii/cursor.rs b/cli/src/torii/cursor.rs new file mode 100644 index 00000000000..aae3713314c --- /dev/null +++ b/cli/src/torii/cursor.rs @@ -0,0 +1,79 @@ +use std::num::NonZeroUsize; + +use iroha_data_model::query::ForwardCursor; + +use crate::torii::{Error, Result}; + +pub trait Batch: IntoIterator + Sized { + fn batched(self, fetch_size: NonZeroUsize) -> Batched; +} + +impl Batch for I { + fn batched(self, batch_size: NonZeroUsize) -> Batched { + Batched { + iter: self.into_iter(), + batch_size, + cursor: ForwardCursor::default(), + } + } +} + +/// Paginated [`Iterator`]. +/// Not recommended to use directly, only use in iterator chains. +#[derive(Debug)] +pub struct Batched { + iter: I::IntoIter, + batch_size: NonZeroUsize, + cursor: ForwardCursor, +} + +impl> Batched { + pub(crate) fn next_batch(&mut self, cursor: ForwardCursor) -> Result<(I, ForwardCursor)> { + if cursor != self.cursor { + return Err(Error::UnknownCursor); + } + + let mut batch_size = 0; + let batch: I = self + .iter + .by_ref() + .inspect(|_| batch_size += 1) + .take(self.batch_size.get()) + .collect(); + + self.cursor.cursor = if let Some(cursor) = self.cursor.cursor { + if batch_size >= self.batch_size.get() { + let batch_size = self + .batch_size + .get() + .try_into() + .expect("usize should fit in u64"); + Some( + cursor + .checked_add(batch_size) + .expect("Cursor size should never reach the platform limit"), + ) + } else { + None + } + } else if batch_size >= self.batch_size.get() { + Some(self.batch_size.try_into().expect("usize should fit in u64")) + } else { + None + }; + + Ok((batch, self.cursor)) + } + + pub fn is_depleted(&self) -> bool { + self.cursor.cursor.is_none() + } +} + +impl Iterator for Batched { + type Item = I::Item; + + fn next(&mut self) -> Option { + self.iter.next() + } +} diff --git a/cli/src/torii/mod.rs b/cli/src/torii/mod.rs index 5490a31cf75..c98ba158b1d 100644 --- a/cli/src/torii/mod.rs +++ b/cli/src/torii/mod.rs @@ -7,8 +7,10 @@ use std::{ fmt::{Debug, Write as _}, net::ToSocketAddrs, sync::Arc, + time::{Duration, Instant}, }; +use dashmap::DashMap; use futures::{stream::FuturesUnordered, StreamExt}; use iroha_core::{ kura::Kura, @@ -17,8 +19,8 @@ use iroha_core::{ sumeragi::SumeragiHandle, EventsSender, }; -use thiserror::Error; -use tokio::sync::Notify; +use iroha_data_model::Value; +use tokio::{sync::Notify, time::sleep}; use utils::*; use warp::{ http::StatusCode, @@ -27,10 +29,44 @@ use warp::{ Filter as _, Reply, }; +use self::cursor::Batched; + #[macro_use] pub(crate) mod utils; +mod cursor; mod pagination; -pub mod routing; +mod routing; + +type LiveQuery = Batched>; + +#[derive(Default)] +struct LiveQueryStore { + queries: DashMap, (LiveQuery, Instant)>, +} + +impl LiveQueryStore { + fn insert(&self, request: Vec, live_query: LiveQuery) { + self.queries.insert(request, (live_query, Instant::now())); + } + + fn remove(&self, request: &Vec) -> Option<(Vec, LiveQuery)> { + self.queries + .remove(request) + .map(|(query_id, (query, _))| (query_id, query)) + } + + // TODO: Add notifier channel to enable graceful shutdown + fn expired_query_cleanup(self: Arc, idle_time: Duration) -> tokio::task::JoinHandle<()> { + tokio::task::spawn(async move { + loop { + sleep(idle_time).await; + + self.queries + .retain(|_, (_, last_access_time)| last_access_time.elapsed() <= idle_time); + } + }) + } +} /// Main network handler and the only entrypoint of the Iroha. pub struct Torii { @@ -39,11 +75,12 @@ pub struct Torii { events: EventsSender, notify_shutdown: Arc, sumeragi: SumeragiHandle, + query_store: Arc, kura: Arc, } /// Torii errors. -#[derive(Debug, Error, displaydoc::Display)] +#[derive(Debug, thiserror::Error, displaydoc::Display)] pub enum Error { /// Failed to execute or validate query Query(#[from] iroha_data_model::ValidationFail), @@ -58,10 +95,12 @@ pub enum Error { #[cfg(feature = "telemetry")] /// Error while getting Prometheus metrics Prometheus(#[source] eyre::Report), + /// Error while resuming cursor + UnknownCursor, } /// Status code for query error response. -pub(crate) fn query_status_code(validation_error: &iroha_data_model::ValidationFail) -> StatusCode { +fn query_status_code(validation_error: &iroha_data_model::ValidationFail) -> StatusCode { use iroha_data_model::{ isi::error::InstructionExecutionError, query::error::QueryExecutionFail::*, ValidationFail::*, @@ -104,7 +143,9 @@ impl Error { use Error::*; match self { Query(e) => query_status_code(e), - AcceptTransaction(_) | ConfigurationReload(_) => StatusCode::BAD_REQUEST, + AcceptTransaction(_) | ConfigurationReload(_) | UnknownCursor => { + StatusCode::BAD_REQUEST + } Config(_) => StatusCode::NOT_FOUND, PushIntoQueue(err) => match **err { queue::Error::Full => StatusCode::INTERNAL_SERVER_ERROR, diff --git a/cli/src/torii/pagination.rs b/cli/src/torii/pagination.rs index 2a20556a686..e305edbaec1 100644 --- a/cli/src/torii/pagination.rs +++ b/cli/src/torii/pagination.rs @@ -1,4 +1,4 @@ -use iroha_data_model::prelude::*; +use iroha_data_model::query::Pagination; /// Describes a collection to which pagination can be applied. /// Implemented for the [`Iterator`] implementors. @@ -7,53 +7,46 @@ pub trait Paginate: Iterator + Sized { fn paginate(self, pagination: Pagination) -> Paginated; } -impl Paginate for I { +impl Paginate for I { fn paginate(self, pagination: Pagination) -> Paginated { - Paginated { - pagination, - iter: self, - } + Paginated::new(pagination, self) } } /// Paginated [`Iterator`]. /// Not recommended to use directly, only use in iterator chains. #[derive(Debug)] -pub struct Paginated { - pagination: Pagination, - iter: I, +pub struct Paginated(core::iter::Take>); + +impl Paginated { + fn new(pagination: Pagination, iter: I) -> Self { + Self( + iter.skip(pagination.start.map_or_else( + || 0, + |start| start.get().try_into().expect("U64 should fit into usize"), + )) + .take(pagination.limit.map_or_else( + || usize::MAX, + |limit| limit.get().try_into().expect("U32 should fit into usize"), + )), + ) + } } impl Iterator for Paginated { type Item = I::Item; fn next(&mut self) -> Option { - if let Some(limit) = self.pagination.limit.as_mut() { - if *limit == 0 { - return None; - } - - *limit -= 1 - } - - #[allow(clippy::option_if_let_else)] - // Required because of E0524. 2 closures with unique refs to self - if let Some(start) = self.pagination.start.take() { - self.iter - .nth(start.try_into().expect("u32 should always fit in usize")) - } else { - self.iter.next() - } + self.0.next() } } -/// Filter for warp which extracts pagination -pub fn paginate() -> impl warp::Filter + Copy { - warp::query() -} - #[cfg(test)] mod tests { + use std::num::{NonZeroU32, NonZeroU64}; + + use iroha_data_model::query::pagination::Pagination; + use super::*; #[test] @@ -61,7 +54,10 @@ mod tests { assert_eq!( vec![1_i32, 2_i32, 3_i32] .into_iter() - .paginate(Pagination::new(None, None)) + .paginate(Pagination { + limit: None, + start: None + }) .collect::>(), vec![1_i32, 2_i32, 3_i32] ) @@ -72,21 +68,20 @@ mod tests { assert_eq!( vec![1_i32, 2_i32, 3_i32] .into_iter() - .paginate(Pagination::new(Some(0), None)) - .collect::>(), - vec![1_i32, 2_i32, 3_i32] - ); - assert_eq!( - vec![1_i32, 2_i32, 3_i32] - .into_iter() - .paginate(Pagination::new(Some(1), None)) + .paginate(Pagination { + limit: None, + start: NonZeroU64::new(1) + }) .collect::>(), vec![2_i32, 3_i32] ); assert_eq!( vec![1_i32, 2_i32, 3_i32] .into_iter() - .paginate(Pagination::new(Some(3), None)) + .paginate(Pagination { + limit: None, + start: NonZeroU64::new(3) + }) .collect::>(), Vec::::new() ); @@ -97,21 +92,20 @@ mod tests { assert_eq!( vec![1_i32, 2_i32, 3_i32] .into_iter() - .paginate(Pagination::new(None, Some(0))) - .collect::>(), - Vec::::new() - ); - assert_eq!( - vec![1_i32, 2_i32, 3_i32] - .into_iter() - .paginate(Pagination::new(None, Some(2))) + .paginate(Pagination { + limit: NonZeroU32::new(2), + start: None + }) .collect::>(), vec![1_i32, 2_i32] ); assert_eq!( vec![1_i32, 2_i32, 3_i32] .into_iter() - .paginate(Pagination::new(None, Some(4))) + .paginate(Pagination { + limit: NonZeroU32::new(4), + start: None + }) .collect::>(), vec![1_i32, 2_i32, 3_i32] ); @@ -122,7 +116,10 @@ mod tests { assert_eq!( vec![1_i32, 2_i32, 3_i32] .into_iter() - .paginate(Pagination::new(Some(1), Some(1))) + .paginate(Pagination { + limit: NonZeroU32::new(1), + start: NonZeroU64::new(1), + }) .collect::>(), vec![2_i32] ) diff --git a/cli/src/torii/routing.rs b/cli/src/torii/routing.rs index fa3a0c1bc3c..01003c30360 100644 --- a/cli/src/torii/routing.rs +++ b/cli/src/torii/routing.rs @@ -5,8 +5,9 @@ // FIXME: This can't be fixed, because one trait in `warp` is private. #![allow(opaque_hidden_inferred_bound)] -use std::cmp::Ordering; +use std::{cmp::Ordering, num::NonZeroUsize}; +use cursor::Batch; use eyre::WrapErr; use futures::TryStreamExt; use iroha_config::{ @@ -28,22 +29,34 @@ use iroha_data_model::{ VersionedCommittedBlock, }, prelude::*, + query::{ForwardCursor, Pagination, Sorting}, }; #[cfg(feature = "telemetry")] use iroha_telemetry::metrics::Status; -use pagination::{paginate, Paginate}; +use pagination::Paginate; +use parity_scale_codec::Encode; use tokio::task; use super::*; use crate::stream::{Sink, Stream}; /// Filter for warp which extracts sorting -pub fn sorting() -> impl warp::Filter + Copy { +fn sorting() -> impl warp::Filter + Copy { + warp::query() +} + +/// Filter for warp which extracts cursor +fn cursor() -> impl warp::Filter + Copy { + warp::query() +} + +/// Filter for warp which extracts pagination +fn paginate() -> impl warp::Filter + Copy { warp::query() } #[iroha_futures::telemetry_future] -pub(crate) async fn handle_instructions( +async fn handle_instructions( queue: Arc, sumeragi: SumeragiHandle, transaction: VersionedSignedTransaction, @@ -67,30 +80,52 @@ pub(crate) async fn handle_instructions( } #[iroha_futures::telemetry_future] -pub(crate) async fn handle_queries( +async fn handle_queries( sumeragi: SumeragiHandle, - pagination: Pagination, - sorting: Sorting, + query_store: Arc, + fetch_size: NonZeroUsize, + request: VersionedSignedQuery, -) -> Result> { - let mut wsv = sumeragi.wsv_clone(); + sorting: Sorting, + pagination: Pagination, - let valid_request = ValidQueryRequest::validate(request, &mut wsv)?; - let result = valid_request.execute(&wsv).map_err(ValidationFail::from)?; + cursor: ForwardCursor, +) -> Result> { + let (query_id, mut live_query) = if cursor.cursor.is_some() { + let query_id = (&request, &sorting, &pagination).encode(); + query_store.remove(&query_id).ok_or(Error::UnknownCursor)? + } else { + let mut wsv = sumeragi.wsv_clone(); - let result = match result { - LazyValue::Value(value) => value, - LazyValue::Iter(iter) => { - Value::Vec(apply_sorting_and_pagination(iter, &sorting, pagination)) + let valid_request = ValidQueryRequest::validate(request, &mut wsv)?; + let res = valid_request.execute(&wsv).map_err(ValidationFail::from)?; + + match res { + LazyValue::Value(result) => { + let cursor = ForwardCursor::default(); + let result = QueryResponse { result, cursor }; + return Ok(Scale(result.into())); + } + LazyValue::Iter(iter) => { + let query_id = (&valid_request, &sorting, &pagination).encode(); + let query = apply_sorting_and_pagination(iter, &sorting, pagination); + (query_id, query.batched(fetch_size)) + } } }; - let paginated_result = QueryResult { - result, - pagination, - sorting, + let (batch, next_cursor) = live_query.next_batch(cursor)?; + + if !live_query.is_depleted() { + query_store.insert(query_id, live_query); + } + + let query_response = QueryResponse { + result: Value::Vec(batch), + cursor: next_cursor, }; - Ok(Scale(paginated_result.into())) + + Ok(Scale(query_response.into())) } fn apply_sorting_and_pagination( @@ -155,6 +190,7 @@ async fn handle_pending_transactions( sumeragi: SumeragiHandle, pagination: Pagination, ) -> Result>> { + // TODO: Don't clone wsv here let wsv = sumeragi.wsv_clone(); Ok(Scale( queue @@ -162,6 +198,9 @@ async fn handle_pending_transactions( .map(Into::into) .paginate(pagination) .collect::>(), + // TODO: + // NOTE: batching is done after collecting the result of pagination + //.batched(fetch_size) )) } @@ -257,10 +296,10 @@ mod subscription { use crate::event; /// Type for any error during subscription handling - #[derive(thiserror::Error, displaydoc::Display, Debug)] + #[derive(Debug, displaydoc::Display, thiserror::Error)] enum Error { /// Event consumption resulted in an error - Consumer(#[source] Box), + Consumer(#[from] Box), /// Event reception error Event(#[from] tokio::sync::broadcast::error::RecvError), /// WebSocket error @@ -292,7 +331,10 @@ mod subscription { /// There should be a [`warp::filters::ws::Message::close()`] /// message to end subscription #[iroha_futures::telemetry_future] - pub async fn handle_subscription(events: EventsSender, stream: WebSocket) -> eyre::Result<()> { + pub(crate) async fn handle_subscription( + events: EventsSender, + stream: WebSocket, + ) -> eyre::Result<()> { let mut consumer = event::Consumer::new(stream).await?; match subscribe_forever(events, &mut consumer).await { @@ -404,6 +446,7 @@ impl Torii { queue, notify_shutdown, sumeragi, + query_store: Arc::default(), kura, } } @@ -443,9 +486,7 @@ impl Torii { } /// Helper function to create router. This router can tested without starting up an HTTP server - pub(crate) fn create_api_router( - &self, - ) -> impl warp::Filter + Clone + Send { + fn create_api_router(&self) -> impl warp::Filter + Clone + Send { let health_route = warp::get() .and(warp::path(uri::HEALTH)) .and_then(|| async { Ok::<_, Infallible>(handle_health()) }); @@ -480,13 +521,19 @@ impl Torii { )) .and(body::versioned()), ) - .or(endpoint4( + .or(endpoint7( handle_queries, warp::path(uri::QUERY) - .and(add_state!(self.sumeragi)) - .and(paginate()) + .and(add_state!( + self.sumeragi, + self.query_store, + NonZeroUsize::try_from(self.iroha_cfg.torii.fetch_size) + .expect("u64 should always fit into usize"), + )) + .and(body::versioned()) .and(sorting()) - .and(body::versioned()), + .and(paginate()) + .and(cursor()), )) .or(endpoint2( handle_post_configuration, @@ -612,13 +659,16 @@ impl Torii { /// # Errors /// Can fail due to listening to network or if http server fails #[iroha_futures::telemetry_future] - pub async fn start(self) -> eyre::Result<()> { - let mut handles = vec![]; + pub(crate) async fn start(self) -> eyre::Result<()> { + let query_idle_time = Duration::from_millis(self.iroha_cfg.torii.query_idle_time_ms.get()); let torii = Arc::new(self); + let mut handles = vec![]; + #[cfg(feature = "telemetry")] handles.extend(Arc::clone(&torii).start_telemetry()?); handles.extend(Arc::clone(&torii).start_api()?); + handles.push(Arc::clone(&torii.query_store).expired_query_cleanup(query_idle_time)); handles .into_iter() diff --git a/cli/src/torii/utils.rs b/cli/src/torii/utils.rs index 80c0d0028ab..77d31319c06 100644 --- a/cli/src/torii/utils.rs +++ b/cli/src/torii/utils.rs @@ -66,4 +66,4 @@ impl Reply for WarpResult { } } -iroha_cli_derive::generate_endpoints!(2, 3, 4, 5); +iroha_cli_derive::generate_endpoints!(2, 3, 4, 5, 7); diff --git a/client/benches/torii.rs b/client/benches/torii.rs index eb280c0496f..99fc7df5e5c 100644 --- a/client/benches/torii.rs +++ b/client/benches/torii.rs @@ -87,14 +87,19 @@ fn query_requests(criterion: &mut Criterion) { let mut failures_count = 0; let _dropable = group.throughput(Throughput::Bytes(request.encode().len() as u64)); let _dropable2 = group.bench_function("query", |b| { - b.iter(|| match iroha_client.request(request.clone()) { - Ok(assets) => { - assert!(!assets.is_empty()); - success_count += 1; - } - Err(e) => { - eprintln!("Query failed: {e}"); - failures_count += 1; + b.iter(|| { + match iroha_client + .request(request.clone()) + .and_then(|iter| iter.collect::, _>>()) + { + Ok(assets) => { + assert!(!assets.is_empty()); + success_count += 1; + } + Err(e) => { + eprintln!("Query failed: {e}"); + failures_count += 1; + } } }); }); diff --git a/client/src/client.rs b/client/src/client.rs index 9bf83301e3e..aa2e7bacf0d 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -21,8 +21,13 @@ use http_default::{AsyncWebSocketStream, WebSocketStream}; use iroha_config::{client::Configuration, torii::uri, GetConfiguration, PostConfiguration}; use iroha_crypto::{HashOf, KeyPair}; use iroha_data_model::{ - block::VersionedCommittedBlock, isi::Instruction, predicate::PredicateBox, prelude::*, - transaction::TransactionPayload, ValidationFail, + block::VersionedCommittedBlock, + isi::Instruction, + predicate::PredicateBox, + prelude::*, + query::{ForwardCursor, Pagination, Query, Sorting}, + transaction::TransactionPayload, + ValidationFail, }; use iroha_logger::prelude::*; use iroha_telemetry::metrics::Status; @@ -40,28 +45,25 @@ use crate::{ const APPLICATION_JSON: &str = "application/json"; -/// General trait for all response handlers -pub trait ResponseHandler> { - /// What is the output of the handler - type Output; - - /// Handles HTTP response - fn handle(self, response: Response) -> Self::Output; -} - /// Phantom struct that handles responses of Query API. /// Depending on input query struct, transforms a response into appropriate output. -#[derive(Clone, Copy)] -pub struct QueryResponseHandler(PhantomData); +#[derive(Debug, Clone, serde::Serialize)] +pub struct QueryResponseHandler { + query_request: QueryRequest, + _output_type: PhantomData, +} -impl Default for QueryResponseHandler { - fn default() -> Self { - Self(PhantomData) +impl QueryResponseHandler { + fn new(query_request: QueryRequest) -> Self { + Self { + query_request, + _output_type: PhantomData, + } } } /// `Result` with [`ClientQueryError`] as an error -pub type QueryHandlerResult = core::result::Result; +pub type QueryResult = core::result::Result; /// Trait for signing transactions pub trait Sign { @@ -94,21 +96,18 @@ impl Sign for VersionedSignedTransaction { } } -impl ResponseHandler for QueryResponseHandler +impl QueryResponseHandler where - R: Query + Debug, - >::Error: Into, + >::Error: Into, { - type Output = QueryHandlerResult>; - - fn handle(self, resp: Response>) -> Self::Output { + fn handle(&mut self, resp: &Response>) -> QueryResult { // Separate-compilation friendly response handling fn _handle_query_response_base( resp: &Response>, - ) -> QueryHandlerResult { + ) -> QueryResult { match resp.status() { StatusCode::OK => { - let res = VersionedQueryResult::decode_all_versioned(resp.body()); + let res = VersionedQueryResponse::decode_all_versioned(resp.body()); res.wrap_err( "Failed to decode response from Iroha. \ You are likely using a version of the client library \ @@ -143,9 +142,15 @@ where } } - _handle_query_response_base(&resp).and_then(|VersionedQueryResult::V1(result)| { - ClientQueryRequest::try_from(result).map_err(Into::into) - }) + let response = _handle_query_response_base(resp) + .map(|VersionedQueryResponse::V1(response)| response)?; + + let value = R::try_from(response.result) + .map_err(Into::into) + .wrap_err("Unexpected type")?; + + self.query_request.server_cursor = response.cursor; + Ok(value) } } @@ -167,17 +172,15 @@ impl From for ClientQueryError { /// Phantom struct that handles Transaction API HTTP response #[derive(Clone, Copy)] -pub struct TransactionResponseHandler; - -impl ResponseHandler for TransactionResponseHandler { - type Output = Result<()>; +struct TransactionResponseHandler; - fn handle(self, resp: Response>) -> Self::Output { +impl TransactionResponseHandler { + fn handle(resp: &Response>) -> Result<()> { if resp.status() == StatusCode::OK { Ok(()) } else { Err( - ResponseReport::with_msg("Unexpected transaction response", &resp) + ResponseReport::with_msg("Unexpected transaction response", resp) .unwrap_or_else(core::convert::identity) .into(), ) @@ -189,16 +192,12 @@ impl ResponseHandler for TransactionResponseHandler { #[derive(Clone, Copy)] pub struct StatusResponseHandler; -impl ResponseHandler for StatusResponseHandler { - type Output = Result; - - fn handle(self, resp: Response>) -> Self::Output { +impl StatusResponseHandler { + fn handle(resp: &Response>) -> Result { if resp.status() != StatusCode::OK { - return Err( - ResponseReport::with_msg("Unexpected status response", &resp) - .unwrap_or_else(core::convert::identity) - .into(), - ); + return Err(ResponseReport::with_msg("Unexpected status response", resp) + .unwrap_or_else(core::convert::identity) + .into()); } serde_json::from_slice(resp.body()).wrap_err("Failed to decode body") } @@ -212,10 +211,7 @@ impl ResponseReport { /// /// # Errors /// If response body isn't a valid utf-8 string - fn with_msg(msg: S, response: &Response>) -> Result - where - S: AsRef, - { + fn with_msg>(msg: S, response: &Response>) -> Result { let status = response.status(); let body = std::str::from_utf8(response.body()); let msg = msg.as_ref(); @@ -236,60 +232,99 @@ impl From for eyre::Report { } } -/// More convenient version of [`iroha_data_model::prelude::QueryResult`]. -/// The only difference is that this struct has `output` field extracted from the result -/// accordingly to the source query. -#[derive(Clone, Debug)] -pub struct ClientQueryRequest -where - R: Query + Debug, - >::Error: Into, -{ - /// Query output - pub output: R::Output, - /// See [`iroha_data_model::prelude::QueryResult`] - pub pagination: Pagination, - /// See [`iroha_data_model::prelude::QueryResult`] - pub sorting: Sorting, +/// Output of a query +pub trait QueryOutput: Into + TryFrom { + /// Type of the query output + type Target: Clone; + + /// Construct query output from query response + fn new(value: Self, query_request: QueryResponseHandler) -> Self::Target; +} + +/// Iterable query output +#[derive(Debug, Clone, serde::Serialize)] +pub struct ResultSet { + query_handler: QueryResponseHandler>, + + iter: Vec, + client_cursor: usize, } -impl ClientQueryRequest +impl Iterator for ResultSet where - R: Query + Debug, - >::Error: Into, + Vec: QueryOutput, + as TryFrom>::Error: Into, { - /// Extracts output as is - pub fn only_output(self) -> R::Output { - self.output + type Item = QueryResult; + + fn next(&mut self) -> Option { + if self.client_cursor >= self.iter.len() { + self.query_handler.query_request.server_cursor.get()?; + + let request = match self.query_handler.query_request.clone().assemble().build() { + Err(err) => return Some(Err(ClientQueryError::Other(err))), + Ok(ok) => ok, + }; + + let response = match request.send() { + Err(err) => return Some(Err(ClientQueryError::Other(err))), + Ok(ok) => ok, + }; + let value = match self.query_handler.handle(&response) { + Err(err) => return Some(Err(err)), + Ok(ok) => ok, + }; + self.iter = value; + self.client_cursor = 0; + } + + let item = Ok(self.iter.get(self.client_cursor).cloned()); + self.client_cursor += 1; + item.transpose() } } -impl TryFrom for ClientQueryRequest +impl QueryOutput for Vec where - R: Query + Debug, - >::Error: Into, + Self: Into + TryFrom, { - type Error = eyre::Report; - - fn try_from( - QueryResult { - result, - pagination, - sorting, - }: QueryResult, - ) -> Result { - let output = R::Output::try_from(result) - .map_err(Into::into) - .wrap_err("Unexpected type")?; + type Target = ResultSet; - Ok(Self { - output, - pagination, - sorting, - }) + fn new(value: Self, query_handler: QueryResponseHandler) -> Self::Target { + ResultSet { + query_handler, + iter: value, + client_cursor: 0, + } } } +macro_rules! impl_query_result { + ( $($ident:ty),+ $(,)? ) => { $( + impl QueryOutput for $ident { + type Target = Self; + + fn new(value: Self, _query_handler: QueryResponseHandler) -> Self::Target { + value + } + } )+ + }; +} +impl_query_result! { + bool, + iroha_data_model::Value, + iroha_data_model::numeric::NumericValue, + iroha_data_model::role::Role, + iroha_data_model::asset::Asset, + iroha_data_model::asset::AssetDefinition, + iroha_data_model::account::Account, + iroha_data_model::domain::Domain, + iroha_data_model::block::BlockHeader, + iroha_data_model::query::MetadataValue, + iroha_data_model::query::TransactionQueryOutput, + iroha_data_model::trigger::Trigger, +} + /// Iroha client #[derive(Clone, DebugCustom, Display)] #[debug( @@ -317,6 +352,42 @@ pub struct Client { add_transaction_nonce: bool, } +/// Query request +#[derive(Debug, Clone, serde::Serialize)] +pub struct QueryRequest { + torii_url: Url, + headers: HashMap, + request: Vec, + sorting: Sorting, + pagination: Pagination, + server_cursor: ForwardCursor, +} + +impl QueryRequest { + #[cfg(test)] + fn dummy() -> Self { + Self { + torii_url: uri::QUERY.parse().unwrap(), + headers: HashMap::new(), + request: Vec::new(), + sorting: Sorting::default(), + pagination: Pagination::default(), + server_cursor: ForwardCursor::default(), + } + } + fn assemble(self) -> DefaultRequestBuilder { + DefaultRequestBuilder::new( + HttpMethod::POST, + self.torii_url.join(uri::QUERY).expect("Valid URI"), + ) + .headers(self.headers) + .params(Vec::from(self.sorting)) + .params(Vec::from(self.pagination)) + .params(Vec::from(self.server_cursor)) + .body(self.request) + } +} + /// Representation of `Iroha` client. impl Client { /// Constructor for client from configuration @@ -411,7 +482,7 @@ impl Client { /// /// # Errors /// Fails if signature generation fails - pub fn sign_query(&self, query: QueryBuilder) -> Result { + pub fn sign_query(&self, query: QueryBuilder) -> Result { query .sign(self.key_pair.clone()) .wrap_err("Failed to sign query") @@ -422,10 +493,7 @@ impl Client { /// /// # Errors /// Fails if sending transaction to peer fails or if it response with error - pub fn submit( - &self, - instruction: impl Instruction + Debug, - ) -> Result> { + pub fn submit(&self, instruction: impl Instruction) -> Result> { let isi = instruction.into(); self.submit_all([isi]) } @@ -480,13 +548,12 @@ impl Client { transaction: &VersionedSignedTransaction, ) -> Result> { iroha_logger::trace!(tx=?transaction, "Submitting"); - let (req, hash, resp_handler) = - self.prepare_transaction_request::(transaction); + let (req, hash) = self.prepare_transaction_request::(transaction); let response = req .build()? .send() .wrap_err_with(|| format!("Failed to send transaction with hash {hash:?}"))?; - resp_handler.handle(response)?; + TransactionResponseHandler::handle(&response)?; Ok(hash) } @@ -589,10 +656,10 @@ impl Client { /// it is better to use a response handler anyway. It allows to abstract from implementation details. /// /// For general usage example see [`Client::prepare_query_request`]. - pub fn prepare_transaction_request( + fn prepare_transaction_request( &self, transaction: &VersionedSignedTransaction, - ) -> (B, HashOf, TransactionResponseHandler) { + ) -> (B, HashOf) { let transaction_bytes: Vec = transaction.encode_versioned(); ( @@ -603,7 +670,6 @@ impl Client { .headers(self.headers.clone()) .body(transaction_bytes), transaction.payload().hash(), - TransactionResponseHandler, ) } @@ -670,7 +736,7 @@ impl Client { /// ```ignore /// use eyre::Result; /// use iroha_client::{ - /// client::{Client, ResponseHandler}, + /// client::Client, /// http::{RequestBuilder, Response, Method}, /// }; /// use iroha_data_model::{predicate::PredicateBox, prelude::{Account, FindAllAccounts, Pagination}}; @@ -717,36 +783,34 @@ impl Client { /// // Handle response with the handler and get typed result /// let accounts = resp_handler.handle(resp)?; /// - /// Ok(accounts.only_output()) + /// Ok(accounts.output()) /// } /// ``` - pub fn prepare_query_request( + fn prepare_query_request( &self, request: R, filter: PredicateBox, pagination: Pagination, sorting: Sorting, - ) -> Result<(B, QueryResponseHandler)> + ) -> Result<(DefaultRequestBuilder, QueryResponseHandler)> where - R: Query + Debug, >::Error: Into, - B: RequestBuilder, { - let pagination: Vec<_> = pagination.into(); - let sorting: Vec<_> = sorting.into(); - let request = QueryBuilder::new(request, self.account_id.clone()).with_filter(filter); - let request: VersionedSignedQuery = self.sign_query(request)?.into(); + let query_builder = QueryBuilder::new(request, self.account_id.clone()).with_filter(filter); + let request = self.sign_query(query_builder)?.encode_versioned(); + + let query_request = QueryRequest { + torii_url: self.torii_url.clone(), + headers: self.headers.clone(), + request, + sorting, + pagination, + server_cursor: ForwardCursor::default(), + }; Ok(( - B::new( - HttpMethod::POST, - self.torii_url.join(uri::QUERY).expect("Valid URI"), - ) - .params(pagination) - .params(sorting) - .headers(self.headers.clone()) - .body(request.encode_versioned()), - QueryResponseHandler::default(), + query_request.clone().assemble(), + QueryResponseHandler::new(query_request), )) } @@ -754,37 +818,42 @@ impl Client { /// /// # Errors /// Fails if sending request fails - pub fn request_with_filter_and_pagination_and_sorting( + pub fn request_with_filter_and_pagination_and_sorting( &self, request: R, pagination: Pagination, sorting: Sorting, filter: PredicateBox, - ) -> QueryHandlerResult> + ) -> QueryResult<::Target> where - R: Query + Debug, - >::Error: Into, // Seems redundant + R::Output: QueryOutput, + >::Error: Into, { iroha_logger::trace!(?request, %pagination, ?sorting, ?filter); - let (req, resp_handler) = self.prepare_query_request::( - request, filter, pagination, sorting, - )?; - let response = req.build()?.send()?; - resp_handler.handle(response) + let (req, mut resp_handler) = + self.prepare_query_request::(request, filter, pagination, sorting)?; + + let kita = req.build()?; + //println!("Request: {kita:?}"); + let response = kita.send()?; + let value = resp_handler.handle(&response)?; + let output = QueryOutput::new(value, resp_handler); + + Ok(output) } /// Create a request with pagination and sorting. /// /// # Errors /// Fails if sending request fails - pub fn request_with_pagination_and_sorting( + pub fn request_with_pagination_and_sorting( &self, request: R, pagination: Pagination, sorting: Sorting, - ) -> QueryHandlerResult> + ) -> QueryResult<::Target> where - R: Query + Debug, + R::Output: QueryOutput, >::Error: Into, { self.request_with_filter_and_pagination_and_sorting( @@ -799,15 +868,15 @@ impl Client { /// /// # Errors /// Fails if sending request fails - pub fn request_with_filter_and_pagination( + pub fn request_with_filter_and_pagination( &self, request: R, pagination: Pagination, filter: PredicateBox, - ) -> QueryHandlerResult> + ) -> QueryResult<::Target> where - R: Query + Debug, - >::Error: Into, // Seems redundant + R::Output: QueryOutput, + >::Error: Into, { self.request_with_filter_and_pagination_and_sorting( request, @@ -821,15 +890,15 @@ impl Client { /// /// # Errors /// Fails if sending request fails - pub fn request_with_filter_and_sorting( + pub fn request_with_filter_and_sorting( &self, request: R, sorting: Sorting, filter: PredicateBox, - ) -> QueryHandlerResult> + ) -> QueryResult<::Target> where - R: Query + Debug, - >::Error: Into, // Seems redundant + R::Output: QueryOutput, + >::Error: Into, { self.request_with_filter_and_pagination_and_sorting( request, @@ -846,13 +915,13 @@ impl Client { /// /// # Errors /// Fails if sending request fails - pub fn request_with_filter( + pub fn request_with_filter( &self, request: R, filter: PredicateBox, - ) -> QueryHandlerResult> + ) -> QueryResult<::Target> where - R: Query + Debug, + R::Output: QueryOutput, >::Error: Into, { self.request_with_filter_and_pagination(request, Pagination::default(), filter) @@ -865,13 +934,13 @@ impl Client { /// /// # Errors /// Fails if sending request fails - pub fn request_with_pagination( + pub fn request_with_pagination( &self, request: R, pagination: Pagination, - ) -> QueryHandlerResult> + ) -> QueryResult<::Target> where - R: Query + Debug, + R::Output: QueryOutput, >::Error: Into, { self.request_with_filter_and_pagination(request, pagination, PredicateBox::default()) @@ -881,13 +950,13 @@ impl Client { /// /// # Errors /// Fails if sending request fails - pub fn request_with_sorting( + pub fn request_with_sorting( &self, request: R, sorting: Sorting, - ) -> QueryHandlerResult> + ) -> QueryResult<::Target> where - R: Query + Debug, + R::Output: QueryOutput, >::Error: Into, { self.request_with_pagination_and_sorting(request, Pagination::default(), sorting) @@ -897,13 +966,15 @@ impl Client { /// /// # Errors /// Fails if sending request fails - pub fn request(&self, request: R) -> QueryHandlerResult + pub fn request( + &self, + request: R, + ) -> QueryResult<::Target> where - R: Query + Debug, + R::Output: QueryOutput, >::Error: Into, { self.request_with_pagination(request, Pagination::default()) - .map(ClientQueryRequest::only_output) } /// Connect (through `WebSocket`) to listen for `Iroha` `pipeline` and `data` events. @@ -1131,9 +1202,9 @@ impl Client { /// # Errors /// Fails if sending request or decoding fails pub fn get_status(&self) -> Result { - let (req, resp_handler) = self.prepare_status_request::(); + let req = self.prepare_status_request::(); let resp = req.build()?.send()?; - resp_handler.handle(resp) + StatusResponseHandler::handle(&resp) } /// Prepares http-request to implement [`Self::get_status`] on your own. @@ -1142,18 +1213,12 @@ impl Client { /// /// # Errors /// Fails if request build fails - pub fn prepare_status_request(&self) -> (B, StatusResponseHandler) - where - B: RequestBuilder, - { - ( - B::new( - HttpMethod::GET, - self.telemetry_url.join(uri::STATUS).expect("Valid URI"), - ) - .headers(self.headers.clone()), - StatusResponseHandler, + pub fn prepare_status_request(&self) -> B { + B::new( + HttpMethod::GET, + self.telemetry_url.join(uri::STATUS).expect("Valid URI"), ) + .headers(self.headers.clone()) } } @@ -1256,11 +1321,10 @@ pub mod stream_api { /// - Sending failed /// - Message not received in stream during connection or subscription /// - Message is an error - pub async fn new(handler: I) -> Result> - where - I: Init + Send, - I::Next: Send, - { + #[allow(clippy::future_not_send)] + pub async fn new>( + handler: I, + ) -> Result> { trace!("Creating `AsyncStream`"); let InitData { first_message, @@ -1770,13 +1834,13 @@ mod tests { #[cfg(test)] mod query_errors_handling { use http::Response; - use iroha_data_model::{query::error::QueryExecutionFail, ValidationFail}; + use iroha_data_model::{asset::Asset, query::error::QueryExecutionFail, ValidationFail}; use super::*; #[test] fn certain_errors() -> Result<()> { - let sut = QueryResponseHandler::::default(); + let mut sut = QueryResponseHandler::>::new(QueryRequest::dummy()); let responses = vec![ ( StatusCode::UNAUTHORIZED, @@ -1796,7 +1860,7 @@ mod tests { for (status_code, err) in responses { let resp = Response::builder().status(status_code).body(err.encode())?; - match sut.handle(resp) { + match sut.handle(&resp) { Err(ClientQueryError::Validation(actual)) => { // PartialEq isn't implemented, so asserting by encoded repr assert_eq!(actual.encode(), err.encode()); @@ -1810,12 +1874,12 @@ mod tests { #[test] fn indeterminate() -> Result<()> { - let sut = QueryResponseHandler::::default(); + let mut sut = QueryResponseHandler::>::new(QueryRequest::dummy()); let response = Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) .body(Vec::::new())?; - match sut.handle(response) { + match sut.handle(&response) { Err(ClientQueryError::Other(_)) => Ok(()), x => Err(eyre!("Expected indeterminate, found: {:?}", x)), } diff --git a/client/src/http.rs b/client/src/http.rs index f1396f61a65..1a70a381c07 100644 --- a/client/src/http.rs +++ b/client/src/http.rs @@ -28,14 +28,14 @@ pub trait RequestBuilder { { for pair in params { let (k, v) = pair.borrow(); - self = self.param(k, v.to_string()); + self = self.param(k, v); } self } /// Add a single query param #[must_use] - fn param(self, key: K, value: V) -> Self + fn param(self, key: K, value: &V) -> Self where K: AsRef, V: ToString; @@ -52,14 +52,14 @@ pub trait RequestBuilder { { for pair in headers { let (k, v) = pair.borrow(); - self = self.header(k, v.to_string()); + self = self.header(k, v); } self } /// Add a single header #[must_use] - fn header(self, name: N, value: V) -> Self + fn header(self, name: N, value: &V) -> Self where N: AsRef, V: ToString; @@ -166,11 +166,11 @@ pub mod ws { /// todo!() /// } /// - /// fn param, V: ToString>(self, _: K, _: V) -> Self { + /// fn param, V: ?Sized + ToString>(self, _: K, _: &V) -> Self { /// todo!() /// } /// - /// fn header, V: ToString>(self, _: N, _: V) -> Self { + /// fn header, V: ?Sized + ToString>(self, _: N, _: &V) -> Self { /// todo!() /// } /// diff --git a/client/src/http_default.rs b/client/src/http_default.rs index 46530a9b45a..2147c9b61ce 100644 --- a/client/src/http_default.rs +++ b/client/src/http_default.rs @@ -25,6 +25,7 @@ fn header_name_from_str(str: &str) -> Result { } /// Default request builder implemented on top of `attohttpc` crate. +#[derive(Debug)] pub struct DefaultRequestBuilder { inner: Result, body: Option>, @@ -50,6 +51,7 @@ impl DefaultRequestBuilder { } /// Request built by [`DefaultRequestBuilder`]. +#[derive(Debug)] pub struct DefaultRequest(AttoHttpRequestBuilderWithBytes); impl DefaultRequest { @@ -80,7 +82,7 @@ impl RequestBuilder for DefaultRequestBuilder { } } - fn header(self, key: K, value: V) -> Self + fn header(self, key: K, value: &V) -> Self where K: AsRef, V: ToString, @@ -90,12 +92,12 @@ impl RequestBuilder for DefaultRequestBuilder { }) } - fn param(self, key: K, value: V) -> Self + fn param(self, key: K, value: &V) -> Self where K: AsRef, V: ToString, { - self.and_then(|b| Ok(b.param(key, value))) + self.and_then(|b| Ok(b.param(key, value.to_string()))) } fn body(self, data: Vec) -> Self { @@ -150,11 +152,11 @@ impl RequestBuilder for DefaultWebSocketRequestBuilder { .uri(url.as_ref()))) } - fn param(self, _key: K, _val: V) -> Self { + fn param(self, _key: K, _val: &V) -> Self { Self(self.0.and(Err(eyre!("No params expected")))) } - fn header(self, name: N, value: V) -> Self + fn header(self, name: N, value: &V) -> Self where N: AsRef, V: ToString, diff --git a/client/tests/integration/asset.rs b/client/tests/integration/asset.rs index 0e4f179eb49..f055537a75a 100644 --- a/client/tests/integration/asset.rs +++ b/client/tests/integration/asset.rs @@ -3,7 +3,7 @@ use std::{str::FromStr as _, thread}; use eyre::Result; -use iroha_client::client; +use iroha_client::client::{self, QueryResult}; use iroha_crypto::{KeyPair, PublicKey}; use iroha_data_model::prelude::*; use iroha_primitives::fixed::Fixed; @@ -31,7 +31,9 @@ fn client_register_asset_should_add_asset_once_but_not_twice() -> Result<()> { // Registering an asset to an account which doesn't have one // should result in asset being created test_client.poll_request(client::asset::by_account_id(account_id), |result| { - result.iter().any(|asset| { + let assets = result.collect::>>().expect("Valid"); + + assets.iter().any(|asset| { asset.id().definition_id == asset_definition_id && *asset.value() == AssetValue::Quantity(0) }) @@ -61,7 +63,9 @@ fn unregister_asset_should_remove_asset_from_account() -> Result<()> { // Wait for asset to be registered test_client.poll_request(client::asset::by_account_id(account_id.clone()), |result| { - result + let assets = result.collect::>>().expect("Valid"); + + assets .iter() .any(|asset| asset.id().definition_id == asset_definition_id) })?; @@ -70,7 +74,9 @@ fn unregister_asset_should_remove_asset_from_account() -> Result<()> { // ... and check that it is removed after Unregister test_client.poll_request(client::asset::by_account_id(account_id), |result| { - result + let assets = result.collect::>>().expect("Valid"); + + assets .iter() .all(|asset| asset.id().definition_id != asset_definition_id) })?; @@ -101,7 +107,9 @@ fn client_add_asset_quantity_to_existing_asset_should_increase_asset_amount() -> let tx = test_client.build_transaction(instructions, metadata)?; test_client.submit_transaction(&tx)?; test_client.poll_request(client::asset::by_account_id(account_id), |result| { - result.iter().any(|asset| { + let assets = result.collect::>>().expect("Valid"); + + assets.iter().any(|asset| { asset.id().definition_id == asset_definition_id && *asset.value() == AssetValue::Quantity(quantity) }) @@ -132,7 +140,9 @@ fn client_add_big_asset_quantity_to_existing_asset_should_increase_asset_amount( let tx = test_client.build_transaction(instructions, metadata)?; test_client.submit_transaction(&tx)?; test_client.poll_request(client::asset::by_account_id(account_id), |result| { - result.iter().any(|asset| { + let assets = result.collect::>>().expect("Valid"); + + assets.iter().any(|asset| { asset.id().definition_id == asset_definition_id && *asset.value() == AssetValue::BigQuantity(quantity) }) @@ -165,7 +175,9 @@ fn client_add_asset_with_decimal_should_increase_asset_amount() -> Result<()> { let tx = test_client.build_transaction(instructions, metadata)?; test_client.submit_transaction(&tx)?; test_client.poll_request(client::asset::by_account_id(account_id.clone()), |result| { - result.iter().any(|asset| { + let assets = result.collect::>>().expect("Valid"); + + assets.iter().any(|asset| { asset.id().definition_id == asset_definition_id && *asset.value() == AssetValue::Fixed(quantity) }) @@ -185,7 +197,9 @@ fn client_add_asset_with_decimal_should_increase_asset_amount() -> Result<()> { .checked_add(quantity2) .map_err(|e| eyre::eyre!("{}", e))?; test_client.submit_till(mint, client::asset::by_account_id(account_id), |result| { - result.iter().any(|asset| { + let assets = result.collect::>>().expect("Valid"); + + assets.iter().any(|asset| { asset.id().definition_id == asset_definition_id && *asset.value() == AssetValue::Fixed(sum) }) @@ -218,19 +232,22 @@ fn client_add_asset_with_name_length_more_than_limit_should_not_commit_transacti iroha_logger::info!("Creating another asset"); thread::sleep(pipeline_time * 4); - let asset_definition_ids = test_client + let mut asset_definition_ids = test_client .request(client::asset::all_definitions()) .expect("Failed to execute request.") + .collect::>>() + .expect("Failed to execute request.") .into_iter() - .map(|asset| asset.id().clone()) - .collect::>(); + .map(|asset| asset.id().clone()); iroha_logger::debug!( "Collected asset definitions ID's: {:?}", &asset_definition_ids ); - assert!(asset_definition_ids.contains(&normal_asset_definition_id)); - assert!(!asset_definition_ids.contains(&incorrect_asset_definition_id)); + assert!(asset_definition_ids + .any(|asset_definition_id| asset_definition_id == normal_asset_definition_id)); + assert!(!asset_definition_ids + .any(|asset_definition_id| asset_definition_id == incorrect_asset_definition_id)); Ok(()) } diff --git a/client/tests/integration/asset_propagation.rs b/client/tests/integration/asset_propagation.rs index 4160de579e9..ddd34ee81b3 100644 --- a/client/tests/integration/asset_propagation.rs +++ b/client/tests/integration/asset_propagation.rs @@ -3,7 +3,7 @@ use std::{str::FromStr as _, thread}; use eyre::Result; -use iroha_client::client; +use iroha_client::client::{self, QueryResult}; use iroha_crypto::KeyPair; use iroha_data_model::{ parameter::{default::MAX_TRANSACTIONS_IN_BLOCK, ParametersBuilder}, @@ -51,7 +51,9 @@ fn client_add_asset_quantity_to_existing_asset_should_increase_asset_amount_on_a client::Client::test(&peer.api_address, &peer.telemetry_address).poll_request( client::asset::by_account_id(account_id), |result| { - result.iter().any(|asset| { + let assets = result.collect::>>().expect("Valid"); + + assets.iter().any(|asset| { asset.id().definition_id == asset_definition_id && *asset.value() == AssetValue::Quantity(quantity) }) diff --git a/client/tests/integration/multiple_blocks_created.rs b/client/tests/integration/multiple_blocks_created.rs index d00c10e14f1..0cbb55fdffc 100644 --- a/client/tests/integration/multiple_blocks_created.rs +++ b/client/tests/integration/multiple_blocks_created.rs @@ -3,7 +3,7 @@ use std::thread; use eyre::Result; -use iroha_client::client::{self, Client}; +use iroha_client::client::{self, Client, QueryResult}; use iroha_crypto::KeyPair; use iroha_data_model::{ parameter::{default::MAX_TRANSACTIONS_IN_BLOCK, ParametersBuilder}, @@ -63,7 +63,9 @@ fn long_multiple_blocks_created() -> Result<()> { Client::test(&peer.api_address, &peer.telemetry_address).poll_request( client::asset::by_account_id(account_id), |result| { - result.iter().any(|asset| { + let assets = result.collect::>>().expect("Valid"); + + assets.iter().any(|asset| { asset.id().definition_id == asset_definition_id && *asset.value() == AssetValue::Quantity(account_has_quantity) }) diff --git a/client/tests/integration/multisignature_account.rs b/client/tests/integration/multisignature_account.rs index 84aea34170b..dd5f1454328 100644 --- a/client/tests/integration/multisignature_account.rs +++ b/client/tests/integration/multisignature_account.rs @@ -3,7 +3,7 @@ use std::thread; use eyre::Result; -use iroha_client::client::{self, Client}; +use iroha_client::client::{self, Client, QueryResult}; use iroha_crypto::KeyPair; use iroha_data_model::prelude::*; use test_network::*; @@ -42,7 +42,9 @@ fn transaction_signed_by_new_signatory_of_account_should_pass() -> Result<()> { mint_asset, client::asset::by_account_id(account_id), |result| { - result.iter().any(|asset| { + let assets = result.collect::>>().expect("Valid"); + + assets.iter().any(|asset| { asset.id().definition_id == asset_definition_id && *asset.value() == AssetValue::Quantity(quantity) }) diff --git a/client/tests/integration/multisignature_transaction.rs b/client/tests/integration/multisignature_transaction.rs index 01ae20e47e9..cb2abe8ad8a 100644 --- a/client/tests/integration/multisignature_transaction.rs +++ b/client/tests/integration/multisignature_transaction.rs @@ -3,7 +3,7 @@ use std::{str::FromStr as _, thread, time::Duration}; use eyre::Result; -use iroha_client::client::{self, Client}; +use iroha_client::client::{self, Client, QueryResult}; use iroha_config::client::Configuration as ClientConfiguration; use iroha_crypto::KeyPair; use iroha_data_model::{ @@ -79,8 +79,11 @@ fn multisignature_transactions_should_wait_for_all_signatures() -> Result<()> { .unwrap(); let client_1 = Client::new(&client_configuration).expect("Invalid client configuration"); let request = client::asset::by_account_id(alice_id); + let assets = client_1 + .request(request.clone())? + .collect::>>()?; assert_eq!( - client_1.request(request.clone())?.len(), + assets.len(), 2 // Alice has roses and cabbage from Genesis ); let (public_key2, private_key2) = key_pair_2.into(); @@ -94,7 +97,9 @@ fn multisignature_transactions_should_wait_for_all_signatures() -> Result<()> { .expect("Found no pending transaction for this account."); client_2.submit_transaction(&client_2.sign_transaction(transaction)?)?; thread::sleep(pipeline_time); - let assets = client_1.request(request)?; + let assets = client_1 + .request(request)? + .collect::>>()?; assert!(!assets.is_empty()); let camomile_asset = assets .iter() diff --git a/client/tests/integration/non_mintable.rs b/client/tests/integration/non_mintable.rs index 6371c25d08d..404ad8d3192 100644 --- a/client/tests/integration/non_mintable.rs +++ b/client/tests/integration/non_mintable.rs @@ -3,7 +3,7 @@ use std::str::FromStr as _; use eyre::Result; -use iroha_client::client; +use iroha_client::client::{self, QueryResult}; use iroha_data_model::{metadata::UnlimitedMetadata, prelude::*}; use test_network::*; @@ -34,7 +34,8 @@ fn non_mintable_asset_can_be_minted_once_but_not_twice() -> Result<()> { // We can register and mint the non-mintable token test_client.submit_transaction(&tx)?; test_client.poll_request(client::asset::by_account_id(account_id.clone()), |result| { - result.iter().any(|asset| { + let assets = result.collect::>>().expect("Valid"); + assets.iter().any(|asset| { asset.id().definition_id == asset_definition_id && *asset.value() == AssetValue::Quantity(200_u32) }) @@ -46,7 +47,8 @@ fn non_mintable_asset_can_be_minted_once_but_not_twice() -> Result<()> { // However, this will fail assert!(test_client .poll_request(client::asset::by_account_id(account_id), |result| { - result.iter().any(|asset| { + let assets = result.collect::>>().expect("Valid"); + assets.iter().any(|asset| { asset.id().definition_id == asset_definition_id && *asset.value() == AssetValue::Quantity(400_u32) }) @@ -72,7 +74,8 @@ fn non_mintable_asset_cannot_be_minted_if_registered_with_non_zero_value() -> Re // We can register the non-mintable token test_client.submit_all([create_asset, register_asset.clone()])?; test_client.poll_request(client::asset::by_account_id(account_id), |result| { - result.iter().any(|asset| { + let assets = result.collect::>>().expect("Valid"); + assets.iter().any(|asset| { asset.id().definition_id == asset_definition_id && *asset.value() == AssetValue::Quantity(1_u32) }) @@ -108,7 +111,8 @@ fn non_mintable_asset_can_be_minted_if_registered_with_zero_value() -> Result<() [create_asset.into(), register_asset.into(), mint.into()]; test_client.submit_all(instructions)?; test_client.poll_request(client::asset::by_account_id(account_id), |result| { - result.iter().any(|asset| { + let assets = result.collect::>>().expect("Valid"); + assets.iter().any(|asset| { asset.id().definition_id == asset_definition_id && *asset.value() == AssetValue::Quantity(1_u32) }) diff --git a/client/tests/integration/offline_peers.rs b/client/tests/integration/offline_peers.rs index 13ed021b960..ee20b58ca4e 100644 --- a/client/tests/integration/offline_peers.rs +++ b/client/tests/integration/offline_peers.rs @@ -1,7 +1,7 @@ #![allow(clippy::restriction)] use eyre::Result; -use iroha_client::client; +use iroha_client::client::{self, QueryResult}; use iroha_data_model::{ parameter::{default::MAX_TRANSACTIONS_IN_BLOCK, ParametersBuilder}, prelude::*, @@ -33,7 +33,9 @@ fn genesis_block_is_committed_with_some_offline_peers() -> Result<()> { let alice_has_roses = 13; //Then - let assets = client.request(client::asset::by_account_id(alice_id))?; + let assets = client + .request(client::asset::by_account_id(alice_id))? + .collect::>>()?; let asset = assets .iter() .find(|asset| asset.id().definition_id == roses) diff --git a/client/tests/integration/pagination.rs b/client/tests/integration/pagination.rs index afa827a511e..e50251eb980 100644 --- a/client/tests/integration/pagination.rs +++ b/client/tests/integration/pagination.rs @@ -1,8 +1,10 @@ #![allow(clippy::restriction)] +use std::num::{NonZeroU32, NonZeroU64}; + use eyre::Result; -use iroha_client::client::asset; -use iroha_data_model::prelude::*; +use iroha_client::client::{asset, QueryResult}; +use iroha_data_model::{asset::AssetDefinition, prelude::*, query::Pagination}; use test_network::*; #[test] @@ -20,8 +22,14 @@ fn client_add_asset_quantity_to_existing_asset_should_increase_asset_amount() -> client.submit_all_blocking(register)?; let vec = client - .request_with_pagination(asset::all_definitions(), Pagination::new(Some(5), Some(5)))? - .only_output(); + .request_with_pagination( + asset::all_definitions(), + Pagination { + limit: NonZeroU32::new(5), + start: NonZeroU64::new(5), + }, + )? + .collect::>>()?; assert_eq!(vec.len(), 5); Ok(()) } diff --git a/client/tests/integration/permissions.rs b/client/tests/integration/permissions.rs index f38d880b9c8..99de7c45f0a 100644 --- a/client/tests/integration/permissions.rs +++ b/client/tests/integration/permissions.rs @@ -3,7 +3,7 @@ use std::{str::FromStr as _, thread}; use eyre::Result; -use iroha_client::client::{self, Client}; +use iroha_client::client::{self, Client, QueryResult}; use iroha_data_model::prelude::*; use test_network::{PeerBuilder, *}; @@ -13,6 +13,8 @@ fn get_assets(iroha_client: &mut Client, id: &::Id) -> iroha_client .request(client::asset::by_account_id(id.clone())) .expect("Failed to execute request.") + .collect::>>() + .expect("Failed to execute request.") } #[ignore = "ignore, more in #2851"] diff --git a/client/tests/integration/queries/account.rs b/client/tests/integration/queries/account.rs index 5e839d24e00..f9a07b84560 100644 --- a/client/tests/integration/queries/account.rs +++ b/client/tests/integration/queries/account.rs @@ -3,7 +3,7 @@ use std::{collections::HashSet, str::FromStr as _}; use eyre::Result; -use iroha_client::client; +use iroha_client::client::{self, QueryResult}; use iroha_data_model::prelude::*; use test_network::*; @@ -65,7 +65,9 @@ fn find_accounts_with_asset() -> Result<()> { AssetValueType::Quantity ); - let found_accounts = test_client.request(client::account::all_with_asset(definition_id))?; + let found_accounts = test_client + .request(client::account::all_with_asset(definition_id))? + .collect::>>()?; let found_ids = found_accounts .into_iter() .map(|account| account.id().clone()) diff --git a/client/tests/integration/queries/role.rs b/client/tests/integration/queries/role.rs index d3d83bb663e..73521d46403 100644 --- a/client/tests/integration/queries/role.rs +++ b/client/tests/integration/queries/role.rs @@ -3,7 +3,7 @@ use std::collections::HashSet; use eyre::Result; -use iroha_client::client; +use iroha_client::client::{self, QueryResult}; use iroha_data_model::{prelude::*, query::error::QueryExecutionFail}; use test_network::*; @@ -37,11 +37,14 @@ fn find_roles() -> Result<()> { // Checking results let found_role_ids = test_client .request(client::role::all())? - .into_iter() - .map(|role| role.id().clone()) - .collect::>(); + .collect::>>()? + .into_iter(); - assert!(role_ids.is_subset(&found_role_ids)); + assert!(role_ids.is_subset( + &found_role_ids + .map(|role| role.id().clone()) + .collect::>() + )); Ok(()) } @@ -64,7 +67,9 @@ fn find_role_ids() -> Result<()> { let role_ids = HashSet::from(role_ids); // Checking results - let found_role_ids = test_client.request(client::role::all_ids())?; + let found_role_ids = test_client + .request(client::role::all_ids())? + .collect::>>()?; let found_role_ids = found_role_ids.into_iter().collect::>(); assert!(role_ids.is_subset(&found_role_ids)); @@ -150,7 +155,9 @@ fn find_roles_by_account_id() -> Result<()> { let role_ids = HashSet::from(role_ids); // Checking results - let found_role_ids = test_client.request(client::role::by_account_id(alice_id))?; + let found_role_ids = test_client + .request(client::role::by_account_id(alice_id))? + .collect::>>()?; let found_role_ids = found_role_ids.into_iter().collect::>(); assert!(role_ids.is_subset(&found_role_ids)); diff --git a/client/tests/integration/restart_peer.rs b/client/tests/integration/restart_peer.rs index 02bc937841c..dbc4f2cd082 100644 --- a/client/tests/integration/restart_peer.rs +++ b/client/tests/integration/restart_peer.rs @@ -3,7 +3,7 @@ use std::{str::FromStr, sync::Arc}; use eyre::Result; -use iroha_client::client; +use iroha_client::client::{self, QueryResult}; use iroha_data_model::prelude::*; use tempfile::TempDir; use test_network::*; @@ -46,8 +46,10 @@ fn restarted_peer_should_have_the_same_asset_amount() -> Result<()> { ); iroha_client.submit_blocking(mint_asset)?; - let asset = iroha_client + let assets = iroha_client .request(client::asset::by_account_id(account_id.clone()))? + .collect::>>()?; + let asset = assets .into_iter() .find(|asset| asset.id().definition_id == asset_definition_id) .expect("Asset not found"); @@ -65,19 +67,17 @@ fn restarted_peer_should_have_the_same_asset_amount() -> Result<()> { ); wait_for_genesis_committed(&vec![iroha_client.clone()], 0); - let account_asset = iroha_client - .poll_request(client::asset::by_account_id(account_id), |assets| { - iroha_logger::error!(?assets); - assets - .iter() - .any(|asset| asset.id().definition_id == asset_definition_id) - }) - .expect("Valid") - .into_iter() - .find(|asset| asset.id().definition_id == asset_definition_id) - .expect("Asset not found"); + iroha_client.poll_request(client::asset::by_account_id(account_id), |result| { + let assets = result.collect::>>().expect("Valid"); + iroha_logger::error!(?assets); + + let account_asset = assets + .into_iter() + .find(|asset| asset.id().definition_id == asset_definition_id) + .expect("Asset not found"); - assert_eq!(AssetValue::Quantity(quantity), *account_asset.value()); + AssetValue::Quantity(quantity) == *account_asset.value() + })? } Ok(()) } diff --git a/client/tests/integration/roles.rs b/client/tests/integration/roles.rs index b6be99ddb07..b11d8012ffa 100644 --- a/client/tests/integration/roles.rs +++ b/client/tests/integration/roles.rs @@ -3,7 +3,7 @@ use std::str::FromStr as _; use eyre::Result; -use iroha_client::client; +use iroha_client::client::{self, QueryResult}; use iroha_data_model::prelude::*; use test_network::*; @@ -88,7 +88,9 @@ fn register_and_grant_role_for_metadata_access() -> Result<()> { test_client.submit_blocking(set_key_value)?; // Making request to find Alice's roles - let found_role_ids = test_client.request(client::role::by_account_id(alice_id))?; + let found_role_ids = test_client + .request(client::role::by_account_id(alice_id))? + .collect::>>()?; assert!(found_role_ids.contains(&role_id)); Ok(()) @@ -121,7 +123,9 @@ fn unregistered_role_removed_from_account() -> Result<()> { test_client.submit_blocking(grant_role)?; // Check that Mouse has root role - let found_mouse_roles = test_client.request(client::role::by_account_id(mouse_id.clone()))?; + let found_mouse_roles = test_client + .request(client::role::by_account_id(mouse_id.clone()))? + .collect::>>()?; assert!(found_mouse_roles.contains(&role_id)); // Unregister root role @@ -129,7 +133,9 @@ fn unregistered_role_removed_from_account() -> Result<()> { test_client.submit_blocking(unregister_role)?; // Check that Mouse doesn't have the root role - let found_mouse_roles = test_client.request(client::role::by_account_id(mouse_id))?; + let found_mouse_roles = test_client + .request(client::role::by_account_id(mouse_id))? + .collect::>>()?; assert!(!found_mouse_roles.contains(&role_id)); Ok(()) diff --git a/client/tests/integration/set_parameter.rs b/client/tests/integration/set_parameter.rs index 24963610265..a9533f5f541 100644 --- a/client/tests/integration/set_parameter.rs +++ b/client/tests/integration/set_parameter.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use eyre::Result; -use iroha_client::client; +use iroha_client::client::{self, QueryResult}; use iroha_data_model::prelude::*; use test_network::*; @@ -16,7 +16,9 @@ fn can_change_parameter_value() -> Result<()> { let parameter_id = ParameterId::from_str("BlockTime")?; let param_box = SetParameterBox::new(parameter); - let old_params = test_client.request(client::parameter::all())?; + let old_params = test_client + .request(client::parameter::all())? + .collect::>>()?; let param_val_old = old_params .iter() .find(|param| param.id() == ¶meter_id) @@ -25,8 +27,9 @@ fn can_change_parameter_value() -> Result<()> { test_client.submit_blocking(param_box)?; - let new_params = test_client.request(client::parameter::all())?; - + let new_params = test_client + .request(client::parameter::all())? + .collect::>>()?; let param_val_new = new_params .iter() .find(|param| param.id() == ¶meter_id) diff --git a/client/tests/integration/sorting.rs b/client/tests/integration/sorting.rs index ae59bb2e643..bed460847a9 100644 --- a/client/tests/integration/sorting.rs +++ b/client/tests/integration/sorting.rs @@ -1,12 +1,18 @@ #![allow(clippy::restriction, clippy::pedantic)] -use std::{collections::HashSet, str::FromStr as _}; +use std::{ + collections::HashSet, + num::{NonZeroU32, NonZeroU64}, + str::FromStr as _, +}; use eyre::{Result, WrapErr as _}; -use iroha_client::client; +use iroha_client::client::{self, QueryResult}; use iroha_data_model::{ + account::Account, predicate::{string, value, PredicateBox}, prelude::*, + query::{Pagination, Sorting}, }; use test_network::*; @@ -21,7 +27,7 @@ fn correct_pagination_assets_after_creating_new_one() { let mut assets = vec![]; let mut instructions = vec![]; - for i in 0..10_u128 { + for i in 0..20_u128 { let asset_definition_id = AssetDefinitionId::from_str(&format!("xor{i}#wonderland")).expect("Valid"); let asset_definition = AssetDefinition::store(asset_definition_id.clone()); @@ -56,30 +62,31 @@ fn correct_pagination_assets_after_creating_new_one() { let res = test_client .request_with_pagination_and_sorting( client::asset::by_account_id(account_id.clone()), - Pagination::new(None, Some(5)), + Pagination { + limit: NonZeroU32::new(5), + start: None, + }, sorting.clone(), ) + .expect("Valid") + .collect::>>() .expect("Valid"); - assert_eq!( - res.output - .iter() - .map(|asset| asset.id().definition_id.name.clone()) - .collect::>(), - assets + assert!(res + .iter() + .map(|asset| &asset.id().definition_id.name) + .eq(assets .iter() .take(5) - .map(|asset| asset.id().definition_id.name.clone()) - .collect::>() - ); + .map(|asset| &asset.id().definition_id.name))); - let new_asset_definition_id = AssetDefinitionId::from_str("xor10#wonderland").expect("Valid"); + let new_asset_definition_id = AssetDefinitionId::from_str("xor20#wonderland").expect("Valid"); let new_asset_definition = AssetDefinition::store(new_asset_definition_id.clone()); let mut new_asset_metadata = Metadata::new(); new_asset_metadata .insert_with_limits( sort_by_metadata_key, - 10_u128.to_value(), + 20_u128.to_value(), MetadataLimits::new(10, 23), ) .expect("Valid"); @@ -98,25 +105,24 @@ fn correct_pagination_assets_after_creating_new_one() { let res = test_client .request_with_pagination_and_sorting( client::asset::by_account_id(account_id), - Pagination::new(Some(5), Some(6)), + Pagination { + limit: NonZeroU32::new(13), + start: NonZeroU64::new(8), + }, sorting, ) + .expect("Valid") + .collect::>>() .expect("Valid"); - let mut right = assets.into_iter().skip(5).take(5).collect::>(); - - right.push(new_asset); - - assert_eq!( - res.output - .into_iter() - .map(|asset| asset.id().definition_id.name.clone()) - .collect::>(), - right - .into_iter() - .map(|asset| asset.id().definition_id.name.clone()) - .collect::>() - ); + assert!(res + .iter() + .map(|asset| &asset.id().definition_id.name) + .eq(assets + .iter() + .skip(8) + .chain(core::iter::once(&new_asset)) + .map(|asset| &asset.id().definition_id.name))); } #[test] @@ -164,15 +170,15 @@ fn correct_sorting_of_entities() { string::StringPredicate::starts_with("xor_"), )), ) + .expect("Valid") + .collect::>>() .expect("Valid"); assert!(res - .output .iter() .map(Identifiable::id) .eq(asset_definitions.iter().rev())); assert!(res - .output .iter() .map(|asset_definition| asset_definition.metadata()) .eq(assets_metadata.iter().rev())); @@ -215,15 +221,12 @@ fn correct_sorting_of_entities() { string::StringPredicate::starts_with("charlie"), )), ) + .expect("Valid") + .collect::>>() .expect("Valid"); + assert!(res.iter().map(Identifiable::id).eq(accounts.iter().rev())); assert!(res - .output - .iter() - .map(Identifiable::id) - .eq(accounts.iter().rev())); - assert!(res - .output .iter() .map(|account| account.metadata()) .eq(accounts_metadata.iter().rev())); @@ -266,15 +269,12 @@ fn correct_sorting_of_entities() { string::StringPredicate::starts_with("neverland"), )), ) + .expect("Valid") + .collect::>>() .expect("Valid"); + assert!(res.iter().map(Identifiable::id).eq(domains.iter().rev())); assert!(res - .output - .iter() - .map(Identifiable::id) - .eq(domains.iter().rev())); - assert!(res - .output .iter() .map(|domain| domain.metadata()) .eq(domains_metadata.iter().rev())); @@ -316,14 +316,16 @@ fn correct_sorting_of_entities() { Sorting::by_metadata_key(sort_by_metadata_key), filter, ) + .expect("Valid") + .collect::>>() .expect("Valid"); - assert_eq!(res.output[0].id(), &domains[1]); - assert_eq!(res.output[1].id(), &domains[0]); - assert_eq!(res.output[2].id(), &domains[2]); - assert_eq!(res.output[0].metadata(), &domains_metadata[1]); - assert_eq!(res.output[1].metadata(), &domains_metadata[0]); - assert_eq!(res.output[2].metadata(), &domains_metadata[2]); + assert_eq!(res[0].id(), &domains[1]); + assert_eq!(res[1].id(), &domains[0]); + assert_eq!(res[2].id(), &domains[2]); + assert_eq!(res[0].metadata(), &domains_metadata[1]); + assert_eq!(res[1].metadata(), &domains_metadata[0]); + assert_eq!(res[2].metadata(), &domains_metadata[2]); } #[test] @@ -377,15 +379,11 @@ fn sort_only_elements_which_have_sorting_key() -> Result<()> { string::StringPredicate::starts_with("charlie"), )), ) - .wrap_err("Failed to submit request")?; + .wrap_err("Failed to submit request")? + .collect::>>()?; - let accounts = accounts_a.into_iter().rev().chain(accounts_b.into_iter()); - assert!(res - .output - .iter() - .map(Identifiable::id) - .cloned() - .eq(accounts)); + let accounts = accounts_a.iter().rev().chain(accounts_b.iter()); + assert!(res.iter().map(Identifiable::id).eq(accounts)); Ok(()) } diff --git a/client/tests/integration/transfer_asset.rs b/client/tests/integration/transfer_asset.rs index b7d8022b048..674a1fa405e 100644 --- a/client/tests/integration/transfer_asset.rs +++ b/client/tests/integration/transfer_asset.rs @@ -1,6 +1,6 @@ #![allow(clippy::restriction, clippy::pedantic)] -use iroha_client::client; +use iroha_client::client::{self, QueryResult}; use iroha_crypto::KeyPair; use iroha_data_model::{prelude::*, Registered}; use iroha_primitives::fixed::Fixed; @@ -90,7 +90,9 @@ fn simulate_transfer< transfer_asset, client::asset::by_account_id(mouse_id.clone()), |result| { - result.iter().any(|asset| { + let assets = result.collect::>>().expect("Valid"); + + assets.iter().any(|asset| { asset.id().definition_id == asset_definition_id && *asset.value() == amount_to_transfer.clone().into() && asset.id().account_id == mouse_id diff --git a/client/tests/integration/triggers/time_trigger.rs b/client/tests/integration/triggers/time_trigger.rs index 0543f4a7361..b2f77b8a600 100644 --- a/client/tests/integration/triggers/time_trigger.rs +++ b/client/tests/integration/triggers/time_trigger.rs @@ -3,7 +3,7 @@ use std::{str::FromStr as _, time::Duration}; use eyre::Result; -use iroha_client::client::{self, Client}; +use iroha_client::client::{self, Client, QueryResult}; use iroha_config::sumeragi::default::DEFAULT_CONSENSUS_ESTIMATION_MS; use iroha_data_model::{prelude::*, transaction::WasmSmartContract}; use iroha_logger::info; @@ -246,7 +246,9 @@ fn mint_nft_for_every_user_every_1_sec() -> Result<()> { for account_id in accounts { let start_pattern = "nft_number_"; let end_pattern = format!("_for_{}#{}", account_id.name, account_id.domain_id); - let assets = test_client.request(client::asset::by_account_id(account_id.clone()))?; + let assets = test_client + .request(client::asset::by_account_id(account_id.clone()))? + .collect::>>()?; let count: u64 = assets .into_iter() .filter(|asset| { diff --git a/client/tests/integration/tx_history.rs b/client/tests/integration/tx_history.rs index 45ea0a8eb26..af47084ca8f 100644 --- a/client/tests/integration/tx_history.rs +++ b/client/tests/integration/tx_history.rs @@ -1,10 +1,14 @@ #![allow(clippy::restriction)] -use std::{str::FromStr as _, thread}; +use std::{ + num::{NonZeroU32, NonZeroU64}, + str::FromStr as _, + thread, +}; use eyre::Result; -use iroha_client::client::transaction; -use iroha_data_model::prelude::*; +use iroha_client::client::{transaction, QueryResult}; +use iroha_data_model::{prelude::*, query::Pagination}; use test_network::*; use super::Configuration; @@ -52,9 +56,12 @@ fn client_has_rejected_and_acepted_txs_should_return_tx_history() -> Result<()> let transactions = client .request_with_pagination( transaction::by_account_id(account_id.clone()), - Pagination::new(Some(1), Some(50)), + Pagination { + limit: NonZeroU32::new(50), + start: NonZeroU64::new(1), + }, )? - .only_output(); + .collect::>>()?; assert_eq!(transactions.len(), 50); let mut prev_creation_time = core::time::Duration::from_millis(0); diff --git a/client/tests/integration/tx_rollback.rs b/client/tests/integration/tx_rollback.rs index 7d366f3f8bb..e65037e9d7d 100644 --- a/client/tests/integration/tx_rollback.rs +++ b/client/tests/integration/tx_rollback.rs @@ -3,7 +3,7 @@ use std::str::FromStr as _; use eyre::Result; -use iroha_client::client; +use iroha_client::client::{self, QueryResult}; use iroha_data_model::prelude::*; use test_network::*; @@ -30,11 +30,13 @@ fn client_sends_transaction_with_invalid_instruction_should_not_see_any_changes( //Then let request = client::asset::by_account_id(account_id); - let query_result = client.request(request)?; + let query_result = client.request(request)?.collect::>>()?; assert!(query_result .iter() .all(|asset| asset.id().definition_id != wrong_asset_definition_id)); - let definition_query_result = client.request(client::asset::all_definitions())?; + let definition_query_result = client + .request(client::asset::all_definitions())? + .collect::>>()?; assert!(definition_query_result .iter() .all(|asset| *asset.id() != wrong_asset_definition_id)); diff --git a/client/tests/integration/unregister_peer.rs b/client/tests/integration/unregister_peer.rs index e46a421a9cf..817e90ded4e 100644 --- a/client/tests/integration/unregister_peer.rs +++ b/client/tests/integration/unregister_peer.rs @@ -2,7 +2,7 @@ use std::thread; use eyre::Result; -use iroha_client::client; +use iroha_client::client::{self, QueryResult}; use iroha_crypto::KeyPair; use iroha_data_model::{ parameter::{default::MAX_TRANSACTIONS_IN_BLOCK, ParametersBuilder}, @@ -64,7 +64,9 @@ fn check_assets( Configuration::block_sync_gossip_time(), 15, |result| { - result.iter().any(|asset| { + let assets = result.collect::>>().expect("Valid"); + + assets.iter().any(|asset| { asset.id().definition_id == *asset_definition_id && *asset.value() == AssetValue::Quantity(quantity) }) diff --git a/client/tests/integration/unstable_network.rs b/client/tests/integration/unstable_network.rs index 79579f26c78..b14522b2f9b 100644 --- a/client/tests/integration/unstable_network.rs +++ b/client/tests/integration/unstable_network.rs @@ -3,7 +3,7 @@ use core::sync::atomic::Ordering; use std::thread; -use iroha_client::client::{self, Client}; +use iroha_client::client::{self, Client, QueryResult}; use iroha_data_model::prelude::*; use iroha_logger::Level; use rand::seq::SliceRandom; @@ -122,7 +122,9 @@ fn unstable_network( Configuration::pipeline_time(), 4, |result| { - result.iter().any(|asset| { + let assets = result.collect::>>().expect("Valid"); + + assets.iter().any(|asset| { asset.id().definition_id == asset_definition_id && *asset.value() == AssetValue::Quantity(account_has_quantity) }) diff --git a/client/tests/integration/upgrade.rs b/client/tests/integration/upgrade.rs index 278b6ca2c65..d79b90063dc 100644 --- a/client/tests/integration/upgrade.rs +++ b/client/tests/integration/upgrade.rs @@ -3,7 +3,7 @@ use std::path::Path; use eyre::Result; -use iroha_client::client::Client; +use iroha_client::client::{Client, QueryResult}; use iroha_crypto::KeyPair; use iroha_data_model::{prelude::*, query::permission::FindAllPermissionTokenDefinitions}; use iroha_logger::info; @@ -63,7 +63,7 @@ fn validator_upgrade_should_update_tokens() -> Result<()> { let definitions = client.request(FindAllPermissionTokenDefinitions)?; assert!(definitions .into_iter() - .any(|definition| definition.id() == &can_unregister_domain_token_id)); + .any(|definition| definition.unwrap().id() == &can_unregister_domain_token_id)); upgrade_validator( &client, @@ -71,7 +71,9 @@ fn validator_upgrade_should_update_tokens() -> Result<()> { )?; // Check that `can_unregister_domain` doesn't exist - let definitions = client.request(FindAllPermissionTokenDefinitions)?; + let definitions = client + .request(FindAllPermissionTokenDefinitions)? + .collect::>>()?; assert!(!definitions .iter() .any(|definition| definition.id() == &can_unregister_domain_token_id)); diff --git a/config/Cargo.toml b/config/Cargo.toml index 13879d1cab7..93dccade084 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -27,6 +27,7 @@ displaydoc = { workspace = true } derive_more = { workspace = true } cfg-if = { workspace = true } path-absolutize = { workspace = true } +once_cell = "1.16.0" [dev-dependencies] proptest = { workspace = true } diff --git a/config/src/torii.rs b/config/src/torii.rs index 81ad7d67701..1797d8e7e07 100644 --- a/config/src/torii.rs +++ b/config/src/torii.rs @@ -1,5 +1,7 @@ //! `Torii` configuration as well as the default values for the URLs used for the main endpoints: `p2p`, `telemetry`, but not `api`. #![allow(clippy::std_instead_of_core, clippy::arithmetic_side_effects)] +use std::num::NonZeroU64; + use iroha_config_base::derive::{Documented, Proxy}; use iroha_primitives::addr::{socket_addr, SocketAddr}; use serde::{Deserialize, Serialize}; @@ -12,6 +14,12 @@ pub const DEFAULT_TORII_TELEMETRY_ADDR: SocketAddr = socket_addr!(127.0.0.1:8180 pub const DEFAULT_TORII_MAX_TRANSACTION_SIZE: u32 = 2_u32.pow(15); /// Default upper bound on `content-length` specified in the HTTP request header pub const DEFAULT_TORII_MAX_CONTENT_LENGTH: u32 = 2_u32.pow(12) * 4000; +/// Default max size of a single batch of results from a query +pub static DEFAULT_TORII_FETCH_SIZE: once_cell::sync::Lazy = + once_cell::sync::Lazy::new(|| NonZeroU64::new(10).unwrap()); +/// Default max time a query can remain in the store unaccessed +pub static DEFAULT_TORII_QUERY_IDLE_TIME_MS: once_cell::sync::Lazy = + once_cell::sync::Lazy::new(|| NonZeroU64::new(30_000).unwrap()); /// Structure that defines the configuration parameters of `Torii` which is the routing module. /// For example the `p2p_addr`, which is used for consensus and block-synchronisation purposes, @@ -33,6 +41,10 @@ pub struct Configuration { pub max_transaction_size: u32, /// Maximum number of bytes in raw message. Used to prevent from DOS attacks. pub max_content_len: u32, + /// How many query results are returned in one batch + pub fetch_size: NonZeroU64, + /// Time query can remain in the store if unaccessed + pub query_idle_time_ms: NonZeroU64, } impl Default for ConfigurationProxy { @@ -43,6 +55,8 @@ impl Default for ConfigurationProxy { telemetry_url: None, max_transaction_size: Some(DEFAULT_TORII_MAX_TRANSACTION_SIZE), max_content_len: Some(DEFAULT_TORII_MAX_CONTENT_LENGTH), + fetch_size: Some(*DEFAULT_TORII_FETCH_SIZE), + query_idle_time_ms: Some(*DEFAULT_TORII_QUERY_IDLE_TIME_MS), } } } @@ -96,9 +110,11 @@ pub mod tests { telemetry_url in prop::option::of(Just(DEFAULT_TORII_TELEMETRY_ADDR)), max_transaction_size in prop::option::of(Just(DEFAULT_TORII_MAX_TRANSACTION_SIZE)), max_content_len in prop::option::of(Just(DEFAULT_TORII_MAX_CONTENT_LENGTH)), + fetch_size in prop::option::of(Just(*DEFAULT_TORII_FETCH_SIZE)), + query_idle_time_ms in prop::option::of(Just(*DEFAULT_TORII_QUERY_IDLE_TIME_MS)), ) -> ConfigurationProxy { - ConfigurationProxy { p2p_addr, api_url, telemetry_url, max_transaction_size, max_content_len } + ConfigurationProxy { p2p_addr, api_url, telemetry_url, max_transaction_size, max_content_len, fetch_size, query_idle_time_ms } } } } diff --git a/configs/peer/config.json b/configs/peer/config.json index 1737604b1b3..56c74756874 100644 --- a/configs/peer/config.json +++ b/configs/peer/config.json @@ -25,7 +25,9 @@ "API_URL": null, "TELEMETRY_URL": null, "MAX_TRANSACTION_SIZE": 32768, - "MAX_CONTENT_LEN": 16384000 + "MAX_CONTENT_LEN": 16384000, + "FETCH_SIZE": 10, + "QUERY_IDLE_TIME_MS": 30000 }, "BLOCK_SYNC": { "GOSSIP_PERIOD_MS": 10000, diff --git a/configs/peer/validator.wasm b/configs/peer/validator.wasm index cdb40f90b86..9bd5e976537 100644 Binary files a/configs/peer/validator.wasm and b/configs/peer/validator.wasm differ diff --git a/core/benches/apply_blocks/apply_blocks.rs b/core/benches/apply_blocks/apply_blocks.rs index 7c434066a69..917d29dee22 100644 --- a/core/benches/apply_blocks/apply_blocks.rs +++ b/core/benches/apply_blocks/apply_blocks.rs @@ -51,7 +51,7 @@ fn create_block( let pending_block = PendingBlock { header, transactions: vec![TransactionValue { - tx: transaction, + value: transaction, error: None, }], event_recommendations: Vec::new(), diff --git a/core/src/queue.rs b/core/src/queue.rs index ba80068cb1f..681a899bb3c 100644 --- a/core/src/queue.rs +++ b/core/src/queue.rs @@ -170,8 +170,8 @@ impl Queue { } /// Returns all pending transactions. - pub fn all_transactions<'q: 'wsv, 'wsv>( - &'q self, + pub fn all_transactions<'wsv>( + &'wsv self, wsv: &'wsv WorldStateView, ) -> impl Iterator + 'wsv { self.txs.iter().filter_map(|tx| { diff --git a/core/src/smartcontracts/isi/account.rs b/core/src/smartcontracts/isi/account.rs index 77f5d8b6a69..d6f2bf4f267 100644 --- a/core/src/smartcontracts/isi/account.rs +++ b/core/src/smartcontracts/isi/account.rs @@ -475,18 +475,20 @@ pub mod query { use eyre::{Result, WrapErr}; use iroha_data_model::{ - evaluate::ExpressionEvaluator, query::error::QueryExecutionFail as Error, + account::Account, + evaluate::ExpressionEvaluator, + permission::PermissionToken, + query::{error::QueryExecutionFail as Error, MetadataValue}, }; use super::*; - use crate::smartcontracts::query::Lazy; impl ValidQuery for FindRolesByAccountId { #[metrics(+"find_roles_by_account_id")] fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { let account_id = wsv .evaluate(&self.id) .wrap_err("Failed to evaluate account id") @@ -505,7 +507,7 @@ pub mod query { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { let account_id = wsv .evaluate(&self.id) .wrap_err("Failed to evaluate account id") @@ -522,7 +524,7 @@ pub mod query { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { Ok(Box::new( wsv.domains() .values() @@ -534,10 +536,7 @@ pub mod query { impl ValidQuery for FindAccountById { #[metrics(+"find_account_by_id")] - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + fn execute(&self, wsv: &WorldStateView) -> Result { let id = wsv .evaluate(&self.id) .wrap_err("Failed to get id") @@ -552,7 +551,7 @@ pub mod query { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { let name = wsv .evaluate(&self.name) .wrap_err("Failed to get account name") @@ -579,7 +578,7 @@ pub mod query { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { let id = wsv .evaluate(&self.domain_id) .wrap_err("Failed to get domain id") @@ -592,10 +591,7 @@ pub mod query { impl ValidQuery for FindAccountKeyValueByIdAndKey { #[metrics(+"find_account_key_value_by_id_and_key")] - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + fn execute(&self, wsv: &WorldStateView) -> Result { let id = wsv .evaluate(&self.id) .wrap_err("Failed to get account id") @@ -616,7 +612,7 @@ pub mod query { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { let asset_definition_id = wsv .evaluate(&self.asset_definition_id) .wrap_err("Failed to get asset id") diff --git a/core/src/smartcontracts/isi/asset.rs b/core/src/smartcontracts/isi/asset.rs index 36b58bb8571..62554ffdd38 100644 --- a/core/src/smartcontracts/isi/asset.rs +++ b/core/src/smartcontracts/isi/asset.rs @@ -436,19 +436,19 @@ pub mod isi { /// Asset-related query implementations. pub mod query { use eyre::{Result, WrapErr as _}; - use iroha_data_model::query::{ - asset::IsAssetDefinitionOwner, error::QueryExecutionFail as Error, + use iroha_data_model::{ + asset::{Asset, AssetDefinition}, + query::{asset::IsAssetDefinitionOwner, error::QueryExecutionFail as Error, MetadataValue}, }; use super::*; - use crate::smartcontracts::query::Lazy; impl ValidQuery for FindAllAssets { #[metrics(+"find_all_assets")] fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { Ok(Box::new( wsv.domains() .values() @@ -468,7 +468,7 @@ pub mod query { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { Ok(Box::new( wsv.domains() .values() @@ -480,10 +480,7 @@ pub mod query { impl ValidQuery for FindAssetById { #[metrics(+"find_asset_by_id")] - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + fn execute(&self, wsv: &WorldStateView) -> Result { let id = wsv .evaluate(&self.id) .wrap_err("Failed to get asset id") @@ -501,10 +498,7 @@ pub mod query { impl ValidQuery for FindAssetDefinitionById { #[metrics(+"find_asset_defintion_by_id")] - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + fn execute(&self, wsv: &WorldStateView) -> Result { let id = wsv .evaluate(&self.id) .wrap_err("Failed to get asset definition id") @@ -521,7 +515,7 @@ pub mod query { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { let name = wsv .evaluate(&self.name) .wrap_err("Failed to get asset name") @@ -552,13 +546,13 @@ pub mod query { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { let id = wsv .evaluate(&self.account_id) .wrap_err("Failed to get account id") .map_err(|e| Error::Evaluate(e.to_string()))?; iroha_logger::trace!(%id); - Ok(Box::new(wsv.account_assets(&id)?)) + Ok(Box::new(wsv.account_assets(&id)?.cloned())) } } @@ -567,7 +561,7 @@ pub mod query { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { let id = wsv .evaluate(&self.asset_definition_id) .wrap_err("Failed to get asset definition id") @@ -598,7 +592,7 @@ pub mod query { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { let id = wsv .evaluate(&self.domain_id) .wrap_err("Failed to get domain id") @@ -619,7 +613,7 @@ pub mod query { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { let domain_id = wsv .evaluate(&self.domain_id) .wrap_err("Failed to get domain id") @@ -654,10 +648,7 @@ pub mod query { impl ValidQuery for FindAssetQuantityById { #[metrics(+"find_asset_quantity_by_id")] - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + fn execute(&self, wsv: &WorldStateView) -> Result { let id = wsv .evaluate(&self.id) .wrap_err("Failed to get asset id") @@ -681,10 +672,7 @@ pub mod query { impl ValidQuery for FindTotalAssetQuantityByAssetDefinitionId { #[metrics(+"find_total_asset_quantity_by_asset_definition_id")] - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + fn execute(&self, wsv: &WorldStateView) -> Result { let id = wsv .evaluate(&self.id) .wrap_err("Failed to get asset definition id") @@ -697,10 +685,7 @@ pub mod query { impl ValidQuery for FindAssetKeyValueByIdAndKey { #[metrics(+"find_asset_key_value_by_id_and_key")] - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + fn execute(&self, wsv: &WorldStateView) -> Result { let id = wsv .evaluate(&self.id) .wrap_err("Failed to get asset id") @@ -732,10 +717,7 @@ pub mod query { impl ValidQuery for IsAssetDefinitionOwner { #[metrics("is_asset_definition_owner")] - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + fn execute(&self, wsv: &WorldStateView) -> Result { let asset_definition_id = wsv .evaluate(&self.asset_definition_id) .wrap_err("Failed to get asset definition id") diff --git a/core/src/smartcontracts/isi/block.rs b/core/src/smartcontracts/isi/block.rs index 43ffd893a17..017f03a4a6d 100644 --- a/core/src/smartcontracts/isi/block.rs +++ b/core/src/smartcontracts/isi/block.rs @@ -1,6 +1,7 @@ //! This module contains trait implementations related to block queries use eyre::{Result, WrapErr}; use iroha_data_model::{ + block::{BlockHeader, VersionedCommittedBlock}, evaluate::ExpressionEvaluator, query::{ block::FindBlockHeaderByHash, @@ -10,14 +11,13 @@ use iroha_data_model::{ use iroha_telemetry::metrics; use super::*; -use crate::smartcontracts::query::Lazy; impl ValidQuery for FindAllBlocks { #[metrics(+"find_all_blocks")] fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, QueryExecutionFail> { + ) -> Result + 'wsv>, QueryExecutionFail> { Ok(Box::new( wsv.all_blocks().rev().map(|block| Clone::clone(&*block)), )) @@ -29,7 +29,7 @@ impl ValidQuery for FindAllBlockHeaders { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, QueryExecutionFail> { + ) -> Result + 'wsv>, QueryExecutionFail> { Ok(Box::new( wsv.all_blocks() .rev() @@ -40,10 +40,7 @@ impl ValidQuery for FindAllBlockHeaders { impl ValidQuery for FindBlockHeaderByHash { #[metrics(+"find_block_header")] - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, QueryExecutionFail> { + fn execute(&self, wsv: &WorldStateView) -> Result { let hash = wsv .evaluate(&self.hash) .wrap_err("Failed to evaluate hash") diff --git a/core/src/smartcontracts/isi/domain.rs b/core/src/smartcontracts/isi/domain.rs index e208457a9dc..2f82fec7c3c 100644 --- a/core/src/smartcontracts/isi/domain.rs +++ b/core/src/smartcontracts/isi/domain.rs @@ -288,27 +288,26 @@ pub mod isi { /// Query module provides [`Query`] Domain related implementations. pub mod query { use eyre::{Result, WrapErr}; - use iroha_data_model::query::error::QueryExecutionFail as Error; + use iroha_data_model::{ + domain::Domain, + query::{error::QueryExecutionFail as Error, MetadataValue}, + }; use super::*; - use crate::smartcontracts::query::Lazy; impl ValidQuery for FindAllDomains { #[metrics(+"find_all_domains")] fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { Ok(Box::new(wsv.domains().values().cloned())) } } impl ValidQuery for FindDomainById { #[metrics(+"find_domain_by_id")] - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + fn execute(&self, wsv: &WorldStateView) -> Result { let id = wsv .evaluate(&self.id) .wrap_err("Failed to get domain id") @@ -320,10 +319,7 @@ pub mod query { impl ValidQuery for FindDomainKeyValueByIdAndKey { #[metrics(+"find_domain_key_value_by_id_and_key")] - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + fn execute(&self, wsv: &WorldStateView) -> Result { let id = wsv .evaluate(&self.id) .wrap_err("Failed to get domain id") @@ -341,10 +337,7 @@ pub mod query { impl ValidQuery for FindAssetDefinitionKeyValueByIdAndKey { #[metrics(+"find_asset_definition_key_value_by_id_and_key")] - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + fn execute(&self, wsv: &WorldStateView) -> Result { let id = wsv .evaluate(&self.id) .wrap_err("Failed to get asset definition id") diff --git a/core/src/smartcontracts/isi/query.rs b/core/src/smartcontracts/isi/query.rs index 7ff9d8737bd..72dcc09aa11 100644 --- a/core/src/smartcontracts/isi/query.rs +++ b/core/src/smartcontracts/isi/query.rs @@ -42,7 +42,7 @@ macro_rules! impl_lazy { } impl_lazy! { bool, - NumericValue, + iroha_data_model::numeric::NumericValue, iroha_data_model::role::Role, iroha_data_model::asset::Asset, iroha_data_model::asset::AssetDefinition, @@ -50,12 +50,13 @@ impl_lazy! { iroha_data_model::domain::Domain, iroha_data_model::block::BlockHeader, iroha_data_model::query::MetadataValue, - iroha_data_model::query::TransactionQueryResult, + iroha_data_model::query::TransactionQueryOutput, iroha_data_model::trigger::Trigger, } /// Query Request statefully validated on the Iroha node side. #[derive(Debug, Decode, Encode)] +#[repr(transparent)] pub struct ValidQueryRequest(VersionedSignedQuery); impl ValidQueryRequest { @@ -110,10 +111,7 @@ impl ValidQueryRequest { } impl ValidQuery for QueryBox { - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + fn execute<'wsv>(&self, wsv: &'wsv WorldStateView) -> Result, Error> { iroha_logger::debug!(query=%self, "Executing"); macro_rules! match_all { @@ -474,7 +472,7 @@ mod tests { if found_accepted.transaction.error.is_none() { assert_eq!( va_tx.hash().transmute(), - found_accepted.transaction.tx.hash() + found_accepted.transaction.value.hash() ) } Ok(()) diff --git a/core/src/smartcontracts/isi/triggers/mod.rs b/core/src/smartcontracts/isi/triggers/mod.rs index d45693ce5c1..f2397a4a60a 100644 --- a/core/src/smartcontracts/isi/triggers/mod.rs +++ b/core/src/smartcontracts/isi/triggers/mod.rs @@ -195,27 +195,31 @@ pub mod isi { pub mod query { //! Queries associated to triggers. - use iroha_data_model::query::error::QueryExecutionFail as Error; + use iroha_data_model::{ + events::FilterBox, + query::{error::QueryExecutionFail as Error, MetadataValue}, + trigger::{OptimizedExecutable, Trigger, TriggerId}, + }; use super::*; - use crate::{prelude::*, smartcontracts::query::Lazy}; + use crate::prelude::*; impl ValidQuery for FindAllActiveTriggerIds { #[metrics(+"find_all_active_triggers")] fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { Ok(Box::new(wsv.triggers().ids().cloned())) } } impl ValidQuery for FindTriggerById { #[metrics(+"find_trigger_by_id")] - fn execute<'wsv>( + fn execute( &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + wsv: &WorldStateView, + ) -> Result, Error> { let id = wsv .evaluate(&self.id) .map_err(|e| Error::Evaluate(format!("Failed to evaluate trigger id. {e}")))?; @@ -243,10 +247,7 @@ pub mod query { impl ValidQuery for FindTriggerKeyValueByIdAndKey { #[metrics(+"find_trigger_key_value_by_id_and_key")] - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + fn execute(&self, wsv: &WorldStateView) -> Result { let id = wsv .evaluate(&self.id) .map_err(|e| Error::Evaluate(format!("Failed to evaluate trigger id. {e}")))?; @@ -272,7 +273,10 @@ pub mod query { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> eyre::Result<::Lazy<'wsv>, Error> { + ) -> eyre::Result< + Box> + 'wsv>, + Error, + > { let domain_id = wsv .evaluate(&self.domain_id) .map_err(|e| Error::Evaluate(format!("Failed to evaluate domain id. {e}")))?; diff --git a/core/src/smartcontracts/isi/triggers/set.rs b/core/src/smartcontracts/isi/triggers/set.rs index a3bffebae01..396975b3418 100644 --- a/core/src/smartcontracts/isi/triggers/set.rs +++ b/core/src/smartcontracts/isi/triggers/set.rs @@ -208,54 +208,48 @@ impl Set { /// Apply `f` to triggers that belong to the given [`DomainId`] /// /// Return an empty list if [`Set`] doesn't contain any triggers belonging to [`DomainId`]. - pub fn inspect_by_domain_id( - &self, + pub fn inspect_by_domain_id<'a, F: 'a, R>( + &'a self, domain_id: &DomainId, f: F, - ) -> impl ExactSizeIterator + ) -> impl Iterator + '_ where F: Fn(&TriggerId, &dyn ActionTrait) -> R, { - self.ids - .iter() - .filter_map(|(id, event_type)| { - let trigger_domain_id = id.domain_id.as_ref()?; + let domain_id = domain_id.clone(); - if trigger_domain_id != domain_id { - return None; - } + self.ids.iter().filter_map(move |(id, event_type)| { + let trigger_domain_id = id.domain_id.as_ref()?; - let result = match event_type { - EventType::Data => self - .data_triggers - .get(id) - .map(|trigger| f(id, trigger)) - .expect("`Set::data_triggers` doesn't contain required id. This is a bug"), - EventType::Pipeline => self - .pipeline_triggers - .get(id) - .map(|trigger| f(id, trigger)) - .expect( - "`Set::pipeline_triggers` doesn't contain required id. This is a bug", - ), - EventType::Time => self - .time_triggers - .get(id) - .map(|trigger| f(id, trigger)) - .expect("`Set::time_triggers` doesn't contain required id. This is a bug"), - EventType::ExecuteTrigger => self - .by_call_triggers - .get(id) - .map(|trigger| f(id, trigger)) - .expect( - "`Set::by_call_triggers` doesn't contain required id. This is a bug", - ), - }; - - Some(result) - }) - .collect::>() - .into_iter() + if *trigger_domain_id != domain_id { + return None; + } + + let result = match event_type { + EventType::Data => self + .data_triggers + .get(id) + .map(|trigger| f(id, trigger)) + .expect("`Set::data_triggers` doesn't contain required id. This is a bug"), + EventType::Pipeline => self + .pipeline_triggers + .get(id) + .map(|trigger| f(id, trigger)) + .expect("`Set::pipeline_triggers` doesn't contain required id. This is a bug"), + EventType::Time => self + .time_triggers + .get(id) + .map(|trigger| f(id, trigger)) + .expect("`Set::time_triggers` doesn't contain required id. This is a bug"), + EventType::ExecuteTrigger => self + .by_call_triggers + .get(id) + .map(|trigger| f(id, trigger)) + .expect("`Set::by_call_triggers` doesn't contain required id. This is a bug"), + }; + + Some(result) + }) } /// Apply `f` to the trigger identified by `id`. diff --git a/core/src/smartcontracts/isi/tx.rs b/core/src/smartcontracts/isi/tx.rs index 2c87fa781cb..894c965333e 100644 --- a/core/src/smartcontracts/isi/tx.rs +++ b/core/src/smartcontracts/isi/tx.rs @@ -10,13 +10,13 @@ use iroha_data_model::{ prelude::*, query::{ error::{FindError, QueryExecutionFail}, - TransactionQueryResult, + TransactionQueryOutput, }, transaction::TransactionValue, }; use iroha_telemetry::metrics; -use super::{query::Lazy, *}; +use super::*; pub(crate) struct BlockTransactionIter(Arc, usize); pub(crate) struct BlockTransactionRef(Arc, usize); @@ -61,11 +61,11 @@ impl ValidQuery for FindAllTransactions { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, QueryExecutionFail> { + ) -> Result + 'wsv>, QueryExecutionFail> { Ok(Box::new( wsv.all_blocks() .flat_map(BlockTransactionIter::new) - .map(|tx| TransactionQueryResult { + .map(|tx| TransactionQueryOutput { block_hash: tx.block_hash(), transaction: tx.value(), }), @@ -78,7 +78,7 @@ impl ValidQuery for FindTransactionsByAccountId { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, QueryExecutionFail> { + ) -> Result + 'wsv>, QueryExecutionFail> { let account_id = wsv .evaluate(&self.account_id) .wrap_err("Failed to get account id") @@ -88,7 +88,7 @@ impl ValidQuery for FindTransactionsByAccountId { wsv.all_blocks() .flat_map(BlockTransactionIter::new) .filter(move |tx| *tx.authority() == account_id) - .map(|tx| TransactionQueryResult { + .map(|tx| TransactionQueryOutput { block_hash: tx.block_hash(), transaction: tx.value(), }), @@ -98,10 +98,7 @@ impl ValidQuery for FindTransactionsByAccountId { impl ValidQuery for FindTransactionByHash { #[metrics(+"find_transaction_by_hash")] - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, QueryExecutionFail> { + fn execute(&self, wsv: &WorldStateView) -> Result { let tx_hash = wsv .evaluate(&self.hash) .wrap_err("Failed to get hash") @@ -122,7 +119,7 @@ impl ValidQuery for FindTransactionByHash { .iter() .find(|transaction| transaction.value.hash() == tx_hash) .cloned() - .map(|transaction| TransactionQueryResult { + .map(|transaction| TransactionQueryOutput { block_hash, transaction, }) diff --git a/core/src/smartcontracts/isi/world.rs b/core/src/smartcontracts/isi/world.rs index 51222761155..13df421a02f 100644 --- a/core/src/smartcontracts/isi/world.rs +++ b/core/src/smartcontracts/isi/world.rs @@ -278,7 +278,7 @@ pub mod isi { for account_id in account_ids { accounts_with_token.insert( account_id.clone(), - wsv.account_inherent_permission_tokens(account_id)? + wsv.account_inherent_permission_tokens(account_id) .filter(|token| token.definition_id == *target_definition_id) .cloned() .collect::>(), @@ -413,22 +413,25 @@ pub mod isi { pub mod query { use eyre::Result; use iroha_data_model::{ + parameter::Parameter, + peer::Peer, + permission::PermissionTokenDefinition, prelude::*, query::{ error::{FindError, QueryExecutionFail as Error}, permission::DoesAccountHavePermissionToken, }, + role::{Role, RoleId}, }; use super::*; - use crate::smartcontracts::query::Lazy; impl ValidQuery for FindAllRoles { #[metrics(+"find_all_roles")] fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { Ok(Box::new(wsv.world.roles.values().cloned())) } } @@ -438,7 +441,7 @@ pub mod query { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { Ok(Box::new(wsv .world .roles @@ -451,10 +454,7 @@ pub mod query { impl ValidQuery for FindRoleByRoleId { #[metrics(+"find_role_by_role_id")] - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + fn execute(&self, wsv: &WorldStateView) -> Result { let role_id = wsv .evaluate(&self.id) .map_err(|e| Error::Evaluate(e.to_string()))?; @@ -472,7 +472,7 @@ pub mod query { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { Ok(Box::new(wsv.peers().cloned().map(Peer::new))) } } @@ -482,7 +482,7 @@ pub mod query { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { Ok(Box::new( wsv.permission_token_definitions().values().cloned(), )) @@ -494,17 +494,14 @@ pub mod query { fn execute<'wsv>( &self, wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + ) -> Result + 'wsv>, Error> { Ok(Box::new(wsv.parameters().cloned())) } } impl ValidQuery for DoesAccountHavePermissionToken { #[metrics("does_account_have_permission")] - fn execute<'wsv>( - &self, - wsv: &'wsv WorldStateView, - ) -> Result<::Lazy<'wsv>, Error> { + fn execute(&self, wsv: &WorldStateView) -> Result { let authority = wsv .evaluate(&self.account_id) .map_err(|e| Error::Evaluate(e.to_string()))?; diff --git a/core/src/smartcontracts/mod.rs b/core/src/smartcontracts/mod.rs index ebab9f86afe..056dc8a6ab8 100644 --- a/core/src/smartcontracts/mod.rs +++ b/core/src/smartcontracts/mod.rs @@ -28,7 +28,7 @@ pub trait Execute { } /// This trait should be implemented for all Iroha Queries. -pub trait ValidQuery: Query +pub trait ValidQuery: iroha_data_model::query::Query where Self::Output: Lazy, { @@ -76,8 +76,8 @@ impl iroha_data_model::evaluate::Context for Context<'_> { .execute(self.wsv) .map(|value| match value { LazyValue::Value(value) => value, - // NOTE: This will only be executed from the validator/executor. - // Handing out references to the host system is a security risk + // NOTE: This will only be executed when evaluating an expression for an + // instruction, i.e. it will only be executed from the validator/executor. LazyValue::Iter(iter) => Value::Vec(iter.collect()), }) .map_err(Into::into) diff --git a/core/src/smartcontracts/wasm.rs b/core/src/smartcontracts/wasm.rs index d398d1613bd..95fe1f37cbc 100644 --- a/core/src/smartcontracts/wasm.rs +++ b/core/src/smartcontracts/wasm.rs @@ -685,8 +685,7 @@ impl<'wrld, S: state::GetCommon<'wrld>, R: DefaultExecute> ExecuteOperations<'wr .map_err(Into::into) .map(|lazy_value| match lazy_value { LazyValue::Value(value) => value, - // NOTE: Returning references to the host system is a security risk - LazyValue::Iter(iter) => Value::Vec(iter.collect::>()), + LazyValue::Iter(iter) => Value::Vec(iter.collect()), }) } @@ -868,8 +867,7 @@ impl<'wrld> ExecuteOperations<'wrld, state::Validator<'wrld>> for Runtime value, - // NOTE: Returning references to the host system is a security risk - LazyValue::Iter(iter) => Value::Vec(iter.collect::>()), + LazyValue::Iter(iter) => Value::Vec(iter.collect()), }) } diff --git a/core/src/sumeragi/main_loop.rs b/core/src/sumeragi/main_loop.rs index ec2835fb9d8..c2536ec3598 100644 --- a/core/src/sumeragi/main_loop.rs +++ b/core/src/sumeragi/main_loop.rs @@ -384,7 +384,6 @@ impl Sumeragi { // https://github.com/hyperledger/iroha/issues/3396 // Kura should store the block only upon successful application to the internal WSV to avoid storing a corrupted block. // Public-facing WSV update should happen after that and be followed by `BlockCommited` event to prevent client access to uncommitted data. - // TODO: Redundant clone Strategy::kura_store_block(&self.kura, committed_block); // Update WSV copy that is public facing diff --git a/core/src/wsv.rs b/core/src/wsv.rs index 2dbda577b00..77b25def56d 100644 --- a/core/src/wsv.rs +++ b/core/src/wsv.rs @@ -158,8 +158,8 @@ impl WorldStateView { pub fn account_assets( &self, id: &AccountId, - ) -> Result + '_, QueryExecutionFail> { - self.map_account(id, |account| account.assets.values().cloned()) + ) -> Result, QueryExecutionFail> { + self.map_account(id, |account| account.assets.values()) } /// Return a set of all permission tokens granted to this account. @@ -174,7 +174,7 @@ impl WorldStateView { let account = self.account(account_id)?; let mut tokens = self - .account_inherent_permission_tokens(account_id)? + .account_inherent_permission_tokens(account_id) .collect::>(); for role_id in &account.roles { @@ -194,12 +194,11 @@ impl WorldStateView { pub fn account_inherent_permission_tokens( &self, account_id: &AccountId, - ) -> Result, FindError> { + ) -> impl ExactSizeIterator { self.world .account_permission_tokens .get(account_id) - .ok_or_else(|| FindError::Account(account_id.clone())) - .map(std::collections::BTreeSet::iter) + .map_or_else(Default::default, std::collections::BTreeSet::iter) } /// Return `true` if [`Account`] contains a permission token not associated with any role. diff --git a/core/test_network/Cargo.toml b/core/test_network/Cargo.toml index cba81346fb7..713c1e3f596 100644 --- a/core/test_network/Cargo.toml +++ b/core/test_network/Cargo.toml @@ -9,6 +9,7 @@ license.workspace = true [dependencies] iroha = { workspace = true, features = ["test-network"] } +iroha_crypto = { workspace = true } iroha_client = { workspace = true } iroha_core = { workspace = true } iroha_config = { workspace = true } diff --git a/core/test_network/src/lib.rs b/core/test_network/src/lib.rs index 2ad7cbe6058..08e3fc981ae 100644 --- a/core/test_network/src/lib.rs +++ b/core/test_network/src/lib.rs @@ -9,10 +9,10 @@ use std::{ thread, }; -use eyre::{Error, Result}; +use eyre::Result; use futures::{prelude::*, stream::FuturesUnordered}; use iroha::Iroha; -use iroha_client::client::Client; +use iroha_client::client::{Client, QueryOutput}; use iroha_config::{ base::proxy::{LoadFromEnv, Override}, client::Configuration as ClientConfiguration, @@ -20,8 +20,8 @@ use iroha_config::{ sumeragi::Configuration as SumeragiConfiguration, torii::Configuration as ToriiConfiguration, }; -use iroha_core::{prelude::*, smartcontracts::query::Lazy}; -use iroha_data_model::{isi::Instruction, peer::Peer as DataModelPeer, prelude::*}; +use iroha_crypto::prelude::*; +use iroha_data_model::{isi::Instruction, peer::Peer as DataModelPeer, prelude::*, query::Query}; use iroha_genesis::{GenesisNetwork, RawGenesisBlock}; use iroha_logger::{Configuration as LoggerConfiguration, InstrumentFutures}; use iroha_primitives::addr::{socket_addr, SocketAddr}; @@ -660,7 +660,7 @@ impl PeerBuilder { type PeerWithRuntimeAndClient = (Runtime, Peer, Client); fn local_unique_port() -> Result { - Ok(socket_addr!(127.0.0.1: unique_port::get_unique_free_port().map_err(Error::msg)?)) + Ok(socket_addr!(127.0.0.1: unique_port::get_unique_free_port().map_err(eyre::Error::msg)?)) } /// Runtime used for testing. @@ -708,61 +708,61 @@ pub trait TestClient: Sized { /// /// # Errors /// If predicate is not satisfied, after maximum retries. - fn submit_till( + fn submit_till( &mut self, - instruction: impl Instruction + Debug, + instruction: impl Instruction + Debug + Clone, request: R, - f: impl Fn(&R::Output) -> bool, - ) -> eyre::Result + f: impl Fn(::Target) -> bool, + ) -> eyre::Result<()> where - R: ValidQuery + Into + Debug + Clone, - >::Error: Into, - R::Output: Lazy + Clone + Debug; + R::Output: QueryOutput, + ::Target: core::fmt::Debug, + >::Error: Into; /// Submits instructions with polling /// /// # Errors /// If predicate is not satisfied, after maximum retries. - fn submit_all_till( + fn submit_all_till( &mut self, instructions: Vec, request: R, - f: impl Fn(&R::Output) -> bool, - ) -> eyre::Result + f: impl Fn(::Target) -> bool, + ) -> eyre::Result<()> where - R: ValidQuery + Into + Debug + Clone, - >::Error: Into, - R::Output: Lazy + Clone + Debug; + R::Output: QueryOutput, + ::Target: core::fmt::Debug, + >::Error: Into; /// Polls request till predicate `f` is satisfied, with default period and max attempts. /// /// # Errors /// If predicate is not satisfied after maximum retries. - fn poll_request( + fn poll_request( &mut self, request: R, - f: impl Fn(&R::Output) -> bool, - ) -> eyre::Result + f: impl Fn(::Target) -> bool, + ) -> eyre::Result<()> where - R: ValidQuery + Into + Debug + Clone, - >::Error: Into, - R::Output: Lazy + Clone + Debug; + R::Output: QueryOutput, + ::Target: core::fmt::Debug, + >::Error: Into; /// Polls request till predicate `f` is satisfied with `period` and `max_attempts` supplied. /// /// # Errors /// If predicate is not satisfied after maximum retries. - fn poll_request_with_period( + fn poll_request_with_period( &mut self, request: R, period: Duration, max_attempts: u32, - f: impl Fn(&R::Output) -> bool, - ) -> eyre::Result + f: impl Fn(::Target) -> bool, + ) -> eyre::Result<()> where - R: ValidQuery + Into + Debug + Clone, - >::Error: Into, - R::Output: Lazy + Clone + Debug; + R::Output: QueryOutput, + ::Target: core::fmt::Debug, + >::Error: Into; } impl TestRuntime for Runtime { @@ -848,54 +848,54 @@ impl TestClient for Client { } } - fn submit_till( + fn submit_till( &mut self, - instruction: impl Instruction + Debug, + instruction: impl Instruction + Debug + Clone, request: R, - f: impl Fn(&R::Output) -> bool, - ) -> eyre::Result + f: impl Fn(::Target) -> bool, + ) -> eyre::Result<()> where - R: ValidQuery + Into + Debug + Clone, - >::Error: Into, - R::Output: Lazy + Clone + Debug, + R::Output: QueryOutput, + ::Target: core::fmt::Debug, + >::Error: Into, { self.submit(instruction) .expect("Failed to submit instruction."); self.poll_request(request, f) } - fn submit_all_till( + fn submit_all_till( &mut self, instructions: Vec, request: R, - f: impl Fn(&R::Output) -> bool, - ) -> eyre::Result + f: impl Fn(::Target) -> bool, + ) -> eyre::Result<()> where - R: ValidQuery + Into + Debug + Clone, - >::Error: Into, - R::Output: Lazy + Clone + Debug, + R::Output: QueryOutput, + ::Target: core::fmt::Debug, + >::Error: Into, { self.submit_all(instructions) .expect("Failed to submit instruction."); self.poll_request(request, f) } - fn poll_request_with_period( + fn poll_request_with_period( &mut self, request: R, period: Duration, max_attempts: u32, - f: impl Fn(&R::Output) -> bool, - ) -> eyre::Result + f: impl Fn(::Target) -> bool, + ) -> eyre::Result<()> where - R: ValidQuery + Into + Debug + Clone, - >::Error: Into, - R::Output: Lazy + Clone + Debug, + R::Output: QueryOutput, + ::Target: core::fmt::Debug, + >::Error: Into, { let mut query_result = None; for _ in 0..max_attempts { query_result = match self.request(request.clone()) { - Ok(result) if f(&result) => return Ok(result), + Ok(result) if f(result.clone()) => return Ok(()), result => Some(result), }; thread::sleep(period); @@ -903,15 +903,15 @@ impl TestClient for Client { Err(eyre::eyre!("Failed to wait for query request completion that would satisfy specified closure. Got this query result instead: {:?}", &query_result)) } - fn poll_request( + fn poll_request( &mut self, request: R, - f: impl Fn(&R::Output) -> bool, - ) -> eyre::Result + f: impl Fn(::Target) -> bool, + ) -> eyre::Result<()> where - R: ValidQuery + Into + Debug + Clone, - >::Error: Into, - R::Output: Lazy + Clone + Debug, + R::Output: QueryOutput, + ::Target: core::fmt::Debug, + >::Error: Into, { self.poll_request_with_period(request, Configuration::pipeline_time() / 2, 10, f) } diff --git a/data_model/cbindgen.toml b/data_model/cbindgen.toml new file mode 100644 index 00000000000..5d6b21a6ac3 --- /dev/null +++ b/data_model/cbindgen.toml @@ -0,0 +1,3 @@ +[parse.expand] +crates = ["iroha_data_model"] +features = ["ffi_export"] diff --git a/data_model/derive/tests/ui_fail/transparent_api_private_item.stderr b/data_model/derive/tests/ui_fail/transparent_api_private_item.stderr index 2ff8feb4121..74adf898403 100644 --- a/data_model/derive/tests/ui_fail/transparent_api_private_item.stderr +++ b/data_model/derive/tests/ui_fail/transparent_api_private_item.stderr @@ -5,7 +5,7 @@ error[E0603]: struct `QueryPayload` is private | ^^^^^^^^^^^^ private struct | note: the struct `QueryPayload` is defined here - --> $WORKSPACE/data_model/src/query.rs + --> $WORKSPACE/data_model/src/query/mod.rs | | pub use self::model::*; | ^^^^^^^^^^^ diff --git a/data_model/src/lib.rs b/data_model/src/lib.rs index b8a1e1dcf50..9d052542140 100644 --- a/data_model/src/lib.rs +++ b/data_model/src/lib.rs @@ -38,7 +38,6 @@ use evaluate::Evaluate; use events::FilterBox; use getset::Getters; use iroha_crypto::{HashOf, PublicKey}; -pub use iroha_crypto::{SignatureOf, SignaturesOf}; use iroha_data_model_derive::{ model, IdEqOrdHash, PartiallyTaggedDeserialize, PartiallyTaggedSerialize, VariantDiscriminant, }; @@ -50,7 +49,7 @@ use iroha_primitives::{ use iroha_schema::IntoSchema; pub use numeric::model::NumericValue; use parity_scale_codec::{Decode, Encode}; -use prelude::{Executable, TransactionQueryResult}; +use prelude::{Executable, TransactionQueryOutput}; use serde::{Deserialize, Serialize}; use serde_with::{DeserializeFromStr, SerializeDisplay}; use strum::EnumDiscriminants; @@ -71,16 +70,12 @@ pub mod isi; pub mod metadata; pub mod name; pub mod numeric; -#[cfg(feature = "http")] -pub mod pagination; pub mod peer; pub mod permission; #[cfg(feature = "http")] pub mod predicate; pub mod query; pub mod role; -#[cfg(feature = "http")] -pub mod sorting; pub mod transaction; pub mod trigger; pub mod validator; @@ -829,7 +824,7 @@ pub mod model { Identifiable(IdentifiableBox), PublicKey(PublicKey), SignatureCheckCondition(SignatureCheckCondition), - TransactionQueryResult(TransactionQueryResult), + TransactionQueryOutput(TransactionQueryOutput), PermissionToken(permission::PermissionToken), Hash(HashValue), Block(VersionedCommittedBlockWrapper), @@ -1114,7 +1109,7 @@ impl fmt::Display for Value { Value::Identifiable(v) => fmt::Display::fmt(&v, f), Value::PublicKey(v) => fmt::Display::fmt(&v, f), Value::SignatureCheckCondition(v) => fmt::Display::fmt(&v, f), - Value::TransactionQueryResult(_) => write!(f, "TransactionQueryResult"), + Value::TransactionQueryOutput(_) => write!(f, "TransactionQueryOutput"), Value::PermissionToken(v) => fmt::Display::fmt(&v, f), Value::Hash(v) => fmt::Display::fmt(&v, f), Value::Block(v) => fmt::Display::fmt(&**v, f), @@ -1143,7 +1138,7 @@ impl Value { | Identifiable(_) | String(_) | Name(_) - | TransactionQueryResult(_) + | TransactionQueryOutput(_) | PermissionToken(_) | Hash(_) | Block(_) @@ -1941,6 +1936,4 @@ pub mod prelude { LengthLimits, NumericValue, PredicateTrait, RegistrableBox, ToValue, TriggerBox, TryAsMut, TryAsRef, TryToValue, UpgradableBox, ValidationFail, ValidatorDeny, Value, }; - #[cfg(feature = "http")] - pub use super::{pagination::prelude::*, sorting::prelude::*}; } diff --git a/data_model/src/numeric.rs b/data_model/src/numeric.rs index 8164d5a8c34..f85a7131eb1 100644 --- a/data_model/src/numeric.rs +++ b/data_model/src/numeric.rs @@ -17,7 +17,7 @@ use serde::{ Deserializer, }; -use self::model::NumericValue; +pub use self::model::*; use super::{ DebugCustom, Decode, Deserialize, Display, Encode, FromVariant, IntoSchema, Serialize, }; diff --git a/data_model/src/pagination.rs b/data_model/src/pagination.rs deleted file mode 100644 index 44dfdaf831f..00000000000 --- a/data_model/src/pagination.rs +++ /dev/null @@ -1,122 +0,0 @@ -//! Structures and traits related to pagination. - -#[cfg(not(feature = "std"))] -use alloc::{ - borrow::ToOwned as _, - collections::btree_map, - format, - string::{String, ToString as _}, - vec, - vec::Vec, -}; -#[cfg(feature = "std")] -use std::collections::btree_map; - -use derive_more::{Constructor, Display}; -use iroha_data_model_derive::model; -use iroha_schema::IntoSchema; -use iroha_version::{Decode, Encode}; -use serde::{Deserialize, Serialize}; -use warp::{ - http::StatusCode, - reply::{self, Response}, - Reply, -}; - -pub use self::model::*; - -const PAGINATION_START: &str = "start"; -const PAGINATION_LIMIT: &str = "limit"; - -#[model] -pub mod model { - use super::*; - - /// Structure for pagination requests - #[derive( - Debug, - Display, - Clone, - Copy, - PartialEq, - Eq, - Default, - Constructor, - Deserialize, - Serialize, - Decode, - Encode, - IntoSchema, - )] - #[display( - fmt = "{}--{}", - "start.unwrap_or(0)", - "limit.map_or(\".inf\".to_owned(), |n| n.to_string())" - )] - pub struct Pagination { - /// start of indexing - pub start: Option, - /// limit of indexing - pub limit: Option, - } -} - -/// Error for pagination -#[derive(Debug, Display, Clone, Eq, PartialEq)] -#[display(fmt = "Failed to decode pagination. Error: {_0}")] -pub struct PaginateError(pub core::num::ParseIntError); - -#[cfg(feature = "std")] -impl std::error::Error for PaginateError {} - -impl Reply for PaginateError { - fn into_response(self) -> Response { - reply::with_status(self.to_string(), StatusCode::BAD_REQUEST).into_response() - } -} - -impl From for btree_map::BTreeMap { - fn from(pagination: Pagination) -> Self { - let mut query_params = Self::new(); - if let Some(start) = pagination.start { - query_params.insert(String::from(PAGINATION_START), start.to_string()); - } - if let Some(limit) = pagination.limit { - query_params.insert(String::from(PAGINATION_LIMIT), limit.to_string()); - } - query_params - } -} - -impl From for Vec<(&'static str, usize)> { - fn from(pagination: Pagination) -> Self { - match (pagination.start, pagination.limit) { - (Some(start), Some(limit)) => { - vec![ - ( - PAGINATION_START, - start.try_into().expect("u32 should always fit in usize"), - ), - ( - PAGINATION_LIMIT, - limit.try_into().expect("u32 should always fit in usize"), - ), - ] - } - (Some(start), None) => vec![( - PAGINATION_START, - start.try_into().expect("u32 should always fit in usize"), - )], - (None, Some(limit)) => vec![( - PAGINATION_LIMIT, - limit.try_into().expect("u32 should always fit in usize"), - )], - (None, None) => Vec::new(), - } - } -} - -pub mod prelude { - //! Prelude: re-export most commonly used traits, structs and macros from this module. - pub use super::*; -} diff --git a/data_model/src/predicate.rs b/data_model/src/predicate.rs index 49f89440b7a..a14c75de318 100644 --- a/data_model/src/predicate.rs +++ b/data_model/src/predicate.rs @@ -10,7 +10,7 @@ use crate::{IdBox, Name, Value}; mod nontrivial { use super::*; /// Struct representing a sequence with at least three elements. - #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, IntoSchema)] + #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] pub struct NonTrivial(Vec); impl NonTrivial { @@ -73,7 +73,7 @@ macro_rules! nontrivial { } /// Predicate combinator enum. -#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, IntoSchema)] +#[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] // Ideally we would enforce `P: PredicateTrait` here, but I // couldn't find a way to do it without polluting everything // downstream with explicit lifetimes, since we would need to @@ -282,7 +282,7 @@ pub mod string { use super::*; /// Predicate useful for processing [`String`]s and [`Name`]s. - #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, IntoSchema)] + #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] pub enum StringPredicate { /// Forward to [`str::contains()`] Contains(String), @@ -559,7 +559,7 @@ pub mod numerical { use super::*; /// A lower-inclusive range predicate. - #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, IntoSchema)] + #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] pub struct SemiInterval { /// The start of the range (inclusive) start: T, @@ -583,7 +583,7 @@ pub mod numerical { impl Copy for SemiInterval {} /// A both-inclusive range predicate - #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, IntoSchema)] + #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] pub struct Interval { /// The start of the range (inclusive) start: T, @@ -624,7 +624,7 @@ pub mod numerical { /// [`Self`] only applies to `Values` that are variants of /// compatible types. If the [`Range`] variant and the [`Value`] /// variant don't match defaults to `false`. - #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, IntoSchema)] + #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] pub enum SemiRange { /// 32-bit U32(SemiInterval), @@ -642,7 +642,7 @@ pub mod numerical { /// [`Self`] only applies to `Values` that are variants of /// compatible types. If the [`Range`] variant and the [`Value`] /// variant don't match defaults to `false`. - #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, IntoSchema)] + #[derive(Debug, Clone, Decode, Encode, Deserialize, Serialize, IntoSchema)] pub enum Range { /// 32-bit U32(Interval), @@ -971,7 +971,7 @@ pub mod value { use super::*; /// A predicate designed for general processing of `Value`. - #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, IntoSchema)] + #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] pub enum ValuePredicate { /// Apply predicate to the [`Identifiable::Id`] and/or [`IdBox`]. Identifiable(string::StringPredicate), @@ -1107,14 +1107,14 @@ pub mod value { } /// A predicate that targets the particular `index` of a collection. - #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, IntoSchema)] + #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] pub struct AtIndex { index: u32, predicate: Box, } /// A predicate that targets the particular `key` of a collection. - #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, IntoSchema)] + #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] pub struct ValueOfKey { key: Name, predicate: Box, @@ -1124,7 +1124,7 @@ pub mod value { /// working with containers. Currently only /// [`Metadata`](crate::metadata::Metadata) and [`Vec`] are /// supported. - #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, IntoSchema)] + #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] pub enum Container { /// Forward to [`Iterator::any`] Any(Box), @@ -1267,7 +1267,9 @@ pub mod ip_addr { /// A Predicate containing independent octuplet masks to be /// applied to all elements of an IP version 4 address. - #[derive(Debug, Clone, Copy, Encode, Decode, IntoSchema, Serialize, Deserialize)] + #[derive( + Debug, Clone, Copy, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema, + )] pub struct Ipv4Predicate([Mask; 4]); impl PredicateTrait for Ipv4Predicate { @@ -1302,7 +1304,9 @@ pub mod ip_addr { /// A Predicate containing independent _hexadecuplets_ (u16 /// groups) masks to be applied to all elements of an IP version 6 /// address. - #[derive(Debug, Clone, Copy, Encode, Decode, IntoSchema, Serialize, Deserialize)] + #[derive( + Debug, Clone, Copy, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema, + )] pub struct Ipv6Predicate([Mask; 8]); impl PredicateTrait for Ipv6Predicate { diff --git a/data_model/src/query/cursor.rs b/data_model/src/query/cursor.rs new file mode 100644 index 00000000000..331adb73701 --- /dev/null +++ b/data_model/src/query/cursor.rs @@ -0,0 +1,57 @@ +//! Structures and traits related to server-side cursor. + +use core::num::{NonZeroU64, NonZeroUsize}; + +use iroha_data_model_derive::model; +use iroha_schema::IntoSchema; +use parity_scale_codec::{Decode, Encode}; +use serde::{Deserialize, Serialize}; + +pub use self::model::*; + +const CURSOR: &str = "cursor"; + +#[model] +pub mod model { + use super::*; + + /// Forward-only (a.k.a non-scrollable) cursor + #[derive( + Debug, + Clone, + Copy, + PartialEq, + Eq, + Default, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] + pub struct ForwardCursor { + pub cursor: Option, + } +} + +impl ForwardCursor { + /// Get cursor position + pub fn get(self) -> Option { + self.cursor + } +} + +impl From for Vec<(&'static str, NonZeroU64)> { + fn from(cursor: ForwardCursor) -> Self { + if let Some(cursor) = cursor.cursor { + return vec![(CURSOR, cursor)]; + } + + Vec::new() + } +} + +pub mod prelude { + //! Prelude: re-export most commonly used traits, structs and macros from this module. + pub use super::*; +} diff --git a/data_model/src/query.rs b/data_model/src/query/mod.rs similarity index 94% rename from data_model/src/query.rs rename to data_model/src/query/mod.rs index cff8fd721ff..7014edce06f 100644 --- a/data_model/src/query.rs +++ b/data_model/src/query/mod.rs @@ -6,14 +6,20 @@ use alloc::{boxed::Box, format, string::String, vec::Vec}; use core::cmp::Ordering; +#[cfg(feature = "http")] +pub use cursor::ForwardCursor; use derive_more::Display; -use iroha_crypto::SignatureOf; +use iroha_crypto::{PublicKey, SignatureOf}; use iroha_data_model_derive::model; use iroha_macro::FromVariant; use iroha_schema::IntoSchema; use iroha_version::prelude::*; +#[cfg(feature = "http")] +pub use pagination::Pagination; use parity_scale_codec::{Decode, Encode}; use serde::{Deserialize, Serialize}; +#[cfg(feature = "http")] +pub use sorting::Sorting; pub use self::model::*; use self::{ @@ -28,6 +34,13 @@ use crate::{ Identifiable, Value, }; +#[cfg(feature = "http")] +pub mod cursor; +#[cfg(feature = "http")] +pub mod pagination; +#[cfg(feature = "http")] +pub mod sorting; + macro_rules! queries { ($($($meta:meta)* $item:item)+) => { pub use self::model::*; @@ -170,24 +183,40 @@ pub mod model { )] #[getset(get = "pub")] #[ffi_type] - pub struct TransactionQueryResult { + pub struct TransactionQueryOutput { /// Transaction pub transaction: TransactionValue, /// The hash of the block to which `tx` belongs to pub block_hash: HashOf, } -} -/// Type returned from [`Metadata`] queries -pub struct MetadataValue(Value); + /// Type returned from [`Metadata`] queries + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] + #[ffi_type] + pub struct MetadataValue(pub Value); +} impl From for Value { + #[inline] fn from(source: MetadataValue) -> Self { source.0 } } impl From for MetadataValue { + #[inline] fn from(source: Value) -> Self { Self(source) } @@ -197,7 +226,7 @@ impl Query for QueryBox { type Output = Value; } -impl TransactionQueryResult { +impl TransactionQueryOutput { #[inline] /// Return payload of the transaction pub fn payload(&self) -> &TransactionPayload { @@ -205,14 +234,14 @@ impl TransactionQueryResult { } } -impl PartialOrd for TransactionQueryResult { +impl PartialOrd for TransactionQueryOutput { #[inline] fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl Ord for TransactionQueryResult { +impl Ord for TransactionQueryOutput { #[inline] fn cmp(&self, other: &Self) -> Ordering { self.payload() @@ -229,6 +258,7 @@ pub mod role { use derive_more::Display; + use super::Query; use crate::prelude::*; queries! { @@ -315,6 +345,7 @@ pub mod permission { use derive_more::Display; + use super::Query; use crate::{permission, prelude::*}; queries! { @@ -399,7 +430,7 @@ pub mod account { use derive_more::Display; - use super::MetadataValue; + use super::{MetadataValue, Query}; use crate::prelude::*; queries! { @@ -561,7 +592,7 @@ pub mod asset { use iroha_data_model_derive::model; pub use self::model::*; - use super::MetadataValue; + use super::{MetadataValue, Query}; use crate::prelude::*; queries! { @@ -910,7 +941,7 @@ pub mod domain { use derive_more::Display; - use super::MetadataValue; + use super::{MetadataValue, Query}; use crate::prelude::*; queries! { @@ -1151,7 +1182,7 @@ pub mod transaction { use derive_more::Display; use iroha_crypto::HashOf; - use super::{Query, TransactionQueryResult}; + use super::{Query, TransactionQueryOutput}; use crate::{ account::AccountId, expression::EvaluatesTo, prelude::Account, transaction::VersionedSignedTransaction, @@ -1190,15 +1221,15 @@ pub mod transaction { } impl Query for FindAllTransactions { - type Output = Vec; + type Output = Vec; } impl Query for FindTransactionsByAccountId { - type Output = Vec; + type Output = Vec; } impl Query for FindTransactionByHash { - type Output = TransactionQueryResult; + type Output = TransactionQueryOutput; } impl FindTransactionsByAccountId { @@ -1296,19 +1327,23 @@ pub mod block { pub mod http { //! Structures related to sending queries over HTTP + use getset::Getters; use iroha_data_model_derive::model; pub use self::model::*; use super::*; - use crate::{ - account::AccountId, pagination::prelude::*, predicate::PredicateBox, sorting::prelude::*, - }; + use crate::{account::AccountId, predicate::PredicateBox}; + + // TODO: Could we make a variant of `Value` that holds only query results? + type QueryResult = Value; declare_versioned_with_scale!(VersionedSignedQuery 1..2, Debug, Clone, iroha_macro::FromVariant, IntoSchema); - declare_versioned_with_scale!(VersionedQueryResult 1..2, Debug, Clone, iroha_macro::FromVariant, IntoSchema); + declare_versioned_with_scale!(VersionedQueryResponse 1..2, Debug, Clone, iroha_macro::FromVariant, IntoSchema); #[model] pub mod model { + use core::num::NonZeroU64; + use super::*; /// I/O ready structure to send queries. @@ -1321,15 +1356,17 @@ pub mod http { } /// Payload of a query. - #[derive(Debug, Clone, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[derive( + Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema, + )] pub(crate) struct QueryPayload { /// Timestamp of the query creation. #[codec(compact)] pub timestamp_ms: u128, - /// Query definition. - pub query: QueryBox, /// Account id of the user who will sign this query. pub authority: AccountId, + /// Query definition. + pub query: QueryBox, /// The filter applied to the result on the server-side. pub filter: PredicateBox, } @@ -1338,10 +1375,23 @@ pub mod http { #[derive(Debug, Clone, Encode, Serialize, IntoSchema)] #[version_with_scale(n = 1, versioned = "VersionedSignedQuery")] pub struct SignedQuery { - /// Payload - pub payload: QueryPayload, /// Signature of the client who sends this query. pub signature: SignatureOf, + /// Payload + pub payload: QueryPayload, + } + + /// [`SignedQuery`] response + #[derive(Debug, Clone, Getters, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[version_with_scale(n = 1, versioned = "VersionedQueryResponse")] + #[getset(get = "pub")] + pub struct QueryResponse { + /// The result of the query execution. + #[getset(skip)] + pub result: QueryResult, + /// Index of the next element in the result set. Client will use this value + /// in the next request to continue fetching results of the original query + pub cursor: cursor::ForwardCursor, } } @@ -1352,8 +1402,8 @@ pub mod http { #[derive(Decode, Deserialize)] struct SignedQueryCandidate { - payload: QueryPayload, signature: SignatureOf, + payload: QueryPayload, } impl SignedQueryCandidate { @@ -1369,6 +1419,7 @@ pub mod http { }) } } + impl Decode for SignedQuery { fn decode(input: &mut I) -> Result { SignedQueryCandidate::decode(input)? @@ -1376,6 +1427,7 @@ pub mod http { .map_err(Into::into) } } + impl<'de> Deserialize<'de> for SignedQuery { fn deserialize(deserializer: D) -> Result where @@ -1414,19 +1466,6 @@ pub mod http { } } - /// Paginated Query Result - // TODO: This is the only structure whose inner fields are exposed. Wrap it in model macro? - #[derive(Debug, Clone, Decode, Encode, Deserialize, Serialize, IntoSchema)] - #[version_with_scale(n = 1, versioned = "VersionedQueryResult")] - pub struct QueryResult { - /// The result of the query execution. - pub result: Value, - /// pagination - pub pagination: Pagination, - /// sorting - pub sorting: Sorting, - } - impl QueryBuilder { /// Construct a new request with the `query`. pub fn new(query: impl Into, authority: AccountId) -> Self { @@ -1457,11 +1496,20 @@ pub mod http { pub fn sign( self, key_pair: iroha_crypto::KeyPair, - ) -> Result { - SignatureOf::new(key_pair, &self.payload).map(|signature| SignedQuery { - payload: self.payload, - signature, - }) + ) -> Result { + SignatureOf::new(key_pair, &self.payload) + .map(|signature| SignedQuery { + payload: self.payload, + signature, + }) + .map(Into::into) + } + } + + impl From for Value { + #[inline] + fn from(source: QueryResponse) -> Self { + source.result } } @@ -1469,7 +1517,7 @@ pub mod http { //! The prelude re-exports most commonly used traits, structs and macros from this crate. pub use super::{ - QueryBuilder, QueryResult, SignedQuery, VersionedQueryResult, VersionedSignedQuery, + QueryBuilder, QueryResponse, SignedQuery, VersionedQueryResponse, VersionedSignedQuery, }; } } @@ -1618,6 +1666,6 @@ pub mod prelude { pub use super::{ account::prelude::*, asset::prelude::*, block::prelude::*, domain::prelude::*, peer::prelude::*, permission::prelude::*, role::prelude::*, transaction::*, - trigger::prelude::*, Query, QueryBox, TransactionQueryResult, + trigger::prelude::*, QueryBox, TransactionQueryOutput, }; } diff --git a/data_model/src/query/pagination.rs b/data_model/src/query/pagination.rs new file mode 100644 index 00000000000..71a12d95f8c --- /dev/null +++ b/data_model/src/query/pagination.rs @@ -0,0 +1,60 @@ +//! Structures and traits related to pagination. + +#[cfg(not(feature = "std"))] +use alloc::{ + borrow::ToOwned as _, + collections::btree_map, + format, + string::{String, ToString as _}, + vec, + vec::Vec, +}; +use core::num::{NonZeroU32, NonZeroU64, NonZeroUsize}; +#[cfg(feature = "std")] +use std::collections::btree_map; + +use derive_more::{Constructor, Display}; +use iroha_data_model_derive::model; +use parity_scale_codec::{Decode, Encode}; +use serde::{Deserialize, Serialize}; +use warp::{ + http::StatusCode, + reply::{self, Response}, + Reply, +}; + +const PAGINATION_START: &str = "start"; +const PAGINATION_LIMIT: &str = "limit"; + +/// Structure for pagination requests +#[derive(Debug, Display, Clone, Copy, Default, Decode, Encode, Deserialize, Serialize)] +#[display( + fmt = "{}--{}", + "start.map(NonZeroU64::get).unwrap_or(0)", + "limit.map_or(\".inf\".to_owned(), |n| n.to_string())" +)] +pub struct Pagination { + /// limit of indexing + pub limit: Option, + /// start of indexing + // TODO: Rename to offset + pub start: Option, +} + +impl From for Vec<(&'static str, NonZeroU64)> { + fn from(pagination: Pagination) -> Self { + match (pagination.start, pagination.limit) { + (Some(start), Some(limit)) => { + vec![(PAGINATION_LIMIT, limit.into()), (PAGINATION_START, start)] + } + (Some(start), None) => vec![(PAGINATION_START, start)], + (None, Some(limit)) => vec![(PAGINATION_LIMIT, limit.into())], + (None, None) => Vec::new(), + } + } +} + +pub mod prelude { + //! Prelude: re-export most commonly used traits, structs and macros from this module. + pub use super::*; +} diff --git a/data_model/src/sorting.rs b/data_model/src/query/sorting.rs similarity index 77% rename from data_model/src/sorting.rs rename to data_model/src/query/sorting.rs index 0ceac5a86e2..9ccbc83c610 100644 --- a/data_model/src/sorting.rs +++ b/data_model/src/query/sorting.rs @@ -8,12 +8,11 @@ use alloc::{ }; use iroha_data_model_derive::model; -use iroha_schema::IntoSchema; -use iroha_version::{Decode, Encode}; +use parity_scale_codec::{Decode, Encode}; use serde::{Deserialize, Serialize}; pub use self::model::*; -use crate::prelude::*; +use crate::{name::Name, prelude::*}; const SORT_BY_KEY: &str = "sort_by_metadata_key"; @@ -21,8 +20,8 @@ const SORT_BY_KEY: &str = "sort_by_metadata_key"; pub mod model { use super::*; - /// Enum for sorting requests - #[derive(Debug, Clone, Default, Decode, Encode, Deserialize, Serialize, IntoSchema)] + /// Struct for sorting requests + #[derive(Debug, Clone, Default, Decode, Encode, Deserialize, Serialize)] pub struct Sorting { /// Sort query result using [`Name`] of the key in [`Asset`]'s metadata. pub sort_by_metadata_key: Option, @@ -38,13 +37,13 @@ impl Sorting { } } -impl From for Vec<(&'static str, String)> { +impl From for Vec<(&'static str, Name)> { fn from(sorting: Sorting) -> Self { - let mut vec = Vec::new(); if let Some(key) = sorting.sort_by_metadata_key { - vec.push((SORT_BY_KEY, key.to_string())); + return vec![(SORT_BY_KEY, key)]; } - vec + + Vec::new() } } diff --git a/data_model/src/transaction.rs b/data_model/src/transaction.rs index 482051477e5..43551f1b44f 100644 --- a/data_model/src/transaction.rs +++ b/data_model/src/transaction.rs @@ -102,20 +102,20 @@ pub mod model { #[getset(get = "pub")] #[ffi_type] pub struct TransactionPayload { - /// Account ID of transaction creator. - pub authority: AccountId, /// Creation timestamp (unix time in milliseconds). #[getset(skip)] pub creation_time_ms: u64, + /// Account ID of transaction creator. + pub authority: AccountId, + /// ISI or a `WebAssembly` smartcontract. + pub instructions: Executable, + /// If transaction is not committed by this time it will be dropped. + #[getset(skip)] + pub time_to_live_ms: Option, /// Random value to make different hashes for transactions which occur repeatedly and simultaneously. // TODO: Only temporary #[getset(skip)] pub nonce: Option, - /// If transaction is not committed by this time it will be dropped. - #[getset(skip)] - pub time_to_live_ms: Option, - /// ISI or a `WebAssembly` smartcontract. - pub instructions: Executable, /// Store for additional information. #[getset(skip)] pub metadata: UnlimitedMetadata, @@ -163,10 +163,10 @@ pub mod model { #[ffi_type] // TODO: All fields in this struct should be private pub struct SignedTransaction { - /// [`Transaction`] payload. - pub payload: TransactionPayload, /// [`iroha_crypto::SignatureOf`]<[`TransactionPayload`]>. pub signatures: SignaturesOf, + /// [`Transaction`] payload. + pub payload: TransactionPayload, } /// Transaction Value used in Instructions and Queries @@ -374,8 +374,8 @@ mod candidate { #[derive(Decode, Deserialize)] struct SignedTransactionCandidate { - payload: TransactionPayload, signatures: SignaturesOf, + payload: TransactionPayload, } impl SignedTransactionCandidate { diff --git a/data_model/src/visit.rs b/data_model/src/visit.rs index 3f60589144a..18416c7a732 100644 --- a/data_model/src/visit.rs +++ b/data_model/src/visit.rs @@ -4,6 +4,8 @@ #[cfg(not(feature = "std"))] use alloc::format; +use iroha_crypto::PublicKey; + use crate::{evaluate::ExpressionEvaluator, prelude::*, NumericValue}; macro_rules! delegate { diff --git a/docs/source/references/config.md b/docs/source/references/config.md index 4b781ccfbde..463433b3a81 100644 --- a/docs/source/references/config.md +++ b/docs/source/references/config.md @@ -56,7 +56,9 @@ The following is the default configuration used by Iroha. "API_URL": null, "TELEMETRY_URL": null, "MAX_TRANSACTION_SIZE": 32768, - "MAX_CONTENT_LEN": 16384000 + "MAX_CONTENT_LEN": 16384000, + "FETCH_SIZE": 10, + "QUERY_IDLE_TIME_MS": 30000 }, "BLOCK_SYNC": { "GOSSIP_PERIOD_MS": 10000, @@ -624,9 +626,11 @@ Has type `Option`[^1]. Can be configured via environm ```json { "API_URL": null, + "FETCH_SIZE": 10, "MAX_CONTENT_LEN": 16384000, "MAX_TRANSACTION_SIZE": 32768, "P2P_ADDR": null, + "QUERY_IDLE_TIME_MS": 30000, "TELEMETRY_URL": null } ``` @@ -641,6 +645,16 @@ Has type `Option`[^1]. Can be configured via environment variable `T null ``` +### `torii.fetch_size` + +How many query results are returned in one batch + +Has type `Option`[^1]. Can be configured via environment variable `TORII_FETCH_SIZE` + +```json +10 +``` + ### `torii.max_content_len` Maximum number of bytes in raw message. Used to prevent from DOS attacks. @@ -671,6 +685,16 @@ Has type `Option`[^1]. Can be configured via environment variable `T null ``` +### `torii.query_idle_time_ms` + +Time query can remain in the store if unaccessed + +Has type `Option`[^1]. Can be configured via environment variable `TORII_QUERY_IDLE_TIME_MS` + +```json +30000 +``` + ### `torii.telemetry_url` Torii address for reporting internal status and metrics for administration. diff --git a/docs/source/references/schema.json b/docs/source/references/schema.json index 725369c0324..810f9700839 100644 --- a/docs/source/references/schema.json +++ b/docs/source/references/schema.json @@ -2067,6 +2067,14 @@ "decimal_places": 9 } }, + "ForwardCursor": { + "Struct": [ + { + "name": "cursor", + "type": "Option>" + } + ] + }, "GenericPredicateBox": { "Enum": [ { @@ -2998,9 +3006,6 @@ "Option": { "Option": "IpfsPath" }, - "Option": { - "Option": "Name" - }, "Option>": { "Option": "NonZero" }, @@ -3019,9 +3024,6 @@ "Option": { "Option": "TransactionRejectionReason" }, - "Option": { - "Option": "u32" - }, "Or": { "Struct": [ { @@ -3041,18 +3043,6 @@ "OriginFilter": "PeerId", "OriginFilter": "RoleId", "OriginFilter": "TriggerId", - "Pagination": { - "Struct": [ - { - "name": "start", - "type": "Option" - }, - { - "name": "limit", - "type": "Option" - } - ] - }, "Pair": { "Struct": [ { @@ -3564,33 +3554,29 @@ "name": "timestamp_ms", "type": "Compact" }, - { - "name": "query", - "type": "QueryBox" - }, { "name": "authority", "type": "AccountId" }, + { + "name": "query", + "type": "QueryBox" + }, { "name": "filter", "type": "GenericPredicateBox" } ] }, - "QueryResult": { + "QueryResponse": { "Struct": [ { "name": "result", "type": "Value" }, { - "name": "pagination", - "type": "Pagination" - }, - { - "name": "sorting", - "type": "Sorting" + "name": "cursor", + "type": "ForwardCursor" } ] }, @@ -3914,25 +3900,25 @@ }, "SignedQuery": { "Struct": [ - { - "name": "payload", - "type": "QueryPayload" - }, { "name": "signature", "type": "SignatureOf" + }, + { + "name": "payload", + "type": "QueryPayload" } ] }, "SignedTransaction": { "Struct": [ - { - "name": "payload", - "type": "TransactionPayload" - }, { "name": "signatures", "type": "SignaturesOf" + }, + { + "name": "payload", + "type": "TransactionPayload" } ] }, @@ -4060,14 +4046,6 @@ "SortedVec>": { "Vec": "SignatureOf" }, - "Sorting": { - "Struct": [ - { - "name": "sort_by_metadata_key", - "type": "Option" - } - ] - }, "String": "String", "StringPredicate": { "Enum": [ @@ -4152,25 +4130,25 @@ }, "TransactionPayload": { "Struct": [ - { - "name": "authority", - "type": "AccountId" - }, { "name": "creation_time_ms", "type": "u64" }, { - "name": "nonce", - "type": "Option>" + "name": "authority", + "type": "AccountId" + }, + { + "name": "instructions", + "type": "Executable" }, { "name": "time_to_live_ms", "type": "Option>" }, { - "name": "instructions", - "type": "Executable" + "name": "nonce", + "type": "Option>" }, { "name": "metadata", @@ -4178,7 +4156,7 @@ } ] }, - "TransactionQueryResult": { + "TransactionQueryOutput": { "Struct": [ { "name": "transaction", @@ -4230,7 +4208,7 @@ "TransactionValue": { "Struct": [ { - "name": "tx", + "name": "value", "type": "VersionedSignedTransaction" }, { @@ -4537,9 +4515,9 @@ "type": "SignatureCheckCondition" }, { - "tag": "TransactionQueryResult", + "tag": "TransactionQueryOutput", "discriminant": 12, - "type": "TransactionQueryResult" + "type": "TransactionQueryOutput" }, { "tag": "PermissionToken", @@ -4634,7 +4612,7 @@ "discriminant": 11 }, { - "tag": "TransactionQueryResult", + "tag": "TransactionQueryOutput", "discriminant": 12 }, { @@ -4795,12 +4773,12 @@ } ] }, - "VersionedQueryResult": { + "VersionedQueryResponse": { "Enum": [ { "tag": "V1", "discriminant": 1, - "type": "QueryResult" + "type": "QueryResponse" } ] }, diff --git a/lints.toml b/lints.toml index 6548fba5b6a..b36eb51c845 100644 --- a/lints.toml +++ b/lints.toml @@ -59,16 +59,8 @@ allow = [ 'clippy::let_underscore_must_use', 'clippy::match_wildcard_for_single_variants', 'clippy::missing_docs_in_private_items', - # Not all public items should be inline. We only inline **trivial** functions. - 'clippy::missing_inline_in_public_items', 'clippy::module_name_repetitions', - 'clippy::must_use_candidate', 'clippy::pattern_type_mismatch', - 'clippy::semicolon_if_nothing_returned', - 'clippy::non-ascii-literal', - 'clippy::wildcard_enum_match_arm', - 'clippy::wildcard_imports', - 'clippy::pub_use', 'clippy::shadow_reuse', 'clippy::shadow_same', @@ -76,14 +68,11 @@ allow = [ 'clippy::unwrap_in_result', 'clippy::expect_used', 'clippy::unreachable', - 'clippy::use_self', 'clippy::wildcard_enum_match_arm', 'clippy::wildcard_imports', - 'elided_lifetimes_in_paths', # Our preferred style. 'clippy::non-ascii-literal', 'clippy::std_instead_of_core', - 'clippy::uninlined_format_args', # This lint could be useful in theory. The trade-off of making # refactoring away from references difficult isn't worth it in all diff --git a/macro/derive/src/lib.rs b/macro/derive/src/lib.rs index 54f548203b1..acc2406b009 100644 --- a/macro/derive/src/lib.rs +++ b/macro/derive/src/lib.rs @@ -176,9 +176,9 @@ fn try_into_variant( quote! { impl #impl_generics TryFrom<#enum_ty #ty_generics> for #variant_ty #where_clause { - type Error = iroha_macro::error::ErrorTryFromEnum<#enum_ty, Self>; + type Error = iroha_macro::error::ErrorTryFromEnum<#enum_ty #ty_generics, Self>; - fn try_from(origin: #enum_ty) -> core::result::Result { + fn try_from(origin: #enum_ty #ty_generics) -> core::result::Result { if let #enum_ty :: #variant(variant) = origin { Ok(variant) } else { diff --git a/macro/utils/src/lib.rs b/macro/utils/src/lib.rs index 6cf0d0eda78..9fdfd48e247 100644 --- a/macro/utils/src/lib.rs +++ b/macro/utils/src/lib.rs @@ -1,9 +1,7 @@ //! Module for various functions and structs to build macros in iroha. -use syn::parse::Parse; - /// Trait for attribute parsing generalization -pub trait AttrParser { +pub trait AttrParser { /// Attribute identifier `#[IDENT...]` const IDENT: &'static str; diff --git a/schema/gen/src/lib.rs b/schema/gen/src/lib.rs index 8543817b32b..e10bd37fa65 100644 --- a/schema/gen/src/lib.rs +++ b/schema/gen/src/lib.rs @@ -47,7 +47,7 @@ pub fn build_schemas() -> MetaMap { VersionedBlockSubscriptionRequest, VersionedEventMessage, VersionedEventSubscriptionRequest, - VersionedQueryResult, + VersionedQueryResponse, VersionedSignedQuery, // Never referenced, but present in type signature. Like `PhantomData` @@ -282,8 +282,7 @@ types!( OriginFilter, OriginFilter, OriginFilter, - QueryResult, - Pagination, + QueryResponse, Pair, Parameter, ParameterId, @@ -337,7 +336,6 @@ types!( SignaturesOf, SignedQuery, SignedTransaction, - Sorting, String, StringPredicate, Subtract, @@ -348,7 +346,7 @@ types!( TransactionLimitError, TransactionLimits, TransactionPayload, - TransactionQueryResult, + TransactionQueryOutput, TransactionRejectionReason, TransactionValue, TransferBox, @@ -378,7 +376,7 @@ types!( VersionedCommittedBlockWrapper, VersionedEventMessage, VersionedEventSubscriptionRequest, - VersionedQueryResult, + VersionedQueryResponse, VersionedSignedQuery, VersionedSignedTransaction, WasmExecutionFail, diff --git a/tools/kagami/src/docs.rs b/tools/kagami/src/docs.rs index 2c6ac4d5ae4..b734e9c1726 100644 --- a/tools/kagami/src/docs.rs +++ b/tools/kagami/src/docs.rs @@ -29,8 +29,8 @@ where { fn get_markdown(writer: &mut W) -> color_eyre::Result<()> { let Value::Object(docs) = Self::get_docs() else { - unreachable!("As top level structure is always object") - }; + unreachable!("As top level structure is always object") + }; let mut vec = Vec::new(); let defaults = serde_json::to_string_pretty(&Self::default())?; diff --git a/version/derive/src/lib.rs b/version/derive/src/lib.rs index eacafabf91f..91d7867260b 100644 --- a/version/derive/src/lib.rs +++ b/version/derive/src/lib.rs @@ -112,13 +112,18 @@ pub fn declare_versioned_with_json(input: TokenStream) -> TokenStream { } fn impl_version(args: Vec, item: TokenStream) -> TokenStream2 { - let (item, struct_name) = if let Ok(item_struct) = syn::parse::(item.clone()) { - (quote!(#item_struct), item_struct.ident) - } else if let Ok(item_enum) = syn::parse::(item) { - (quote!(#item_enum), item_enum.ident) - } else { - abort_call_site!("The attribute should be attached to either struct or enum."); - }; + let (item, struct_name, generics) = + if let Ok(item_struct) = syn::parse::(item.clone()) { + ( + quote!(#item_struct), + item_struct.ident, + item_struct.generics, + ) + } else if let Ok(item_enum) = syn::parse::(item) { + (quote!(#item_enum), item_enum.ident, item_enum.generics) + } else { + abort_call_site!("The attribute should be attached to either struct or enum."); + }; let args_map: FxHashMap<_, _> = args .into_iter() .filter_map(|meta| { @@ -173,10 +178,12 @@ fn impl_version(args: Vec, item: TokenStream) -> TokenStream2 { ) }; let alias_type_name = format_ident!("_{}V{}", versioned_struct_name, version_number); + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + quote!( /// Autogenerated alias type to link versioned item to its container. #[allow(clippy::redundant_pub_crate)] - pub(crate) type #alias_type_name = #struct_name; + pub(crate) type #alias_type_name #impl_generics = #struct_name #ty_generics #where_clause; #item ) @@ -236,10 +243,24 @@ impl Parse for DeclareVersionedArgs { } fn impl_decode_versioned(enum_name: &Ident, generics: &syn::Generics) -> proc_macro2::TokenStream { - let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let mut decode_where_clause = generics + .where_clause + .clone() + .unwrap_or_else(|| syn::parse_quote!(where)); + decode_where_clause + .predicates + .push(syn::parse_quote!(Self: parity_scale_codec::DecodeAll)); + let mut encode_where_clause = generics + .where_clause + .clone() + .unwrap_or_else(|| syn::parse_quote!(where)); + encode_where_clause + .predicates + .push(syn::parse_quote!(Self: parity_scale_codec::Encode)); + let (impl_generics, ty_generics, _) = generics.split_for_impl(); quote! ( - impl #impl_generics iroha_version::scale::DecodeVersioned for #enum_name #ty_generics #where_clause { + impl #impl_generics iroha_version::scale::DecodeVersioned for #enum_name #ty_generics #decode_where_clause { fn decode_all_versioned(input: &[u8]) -> iroha_version::error::Result { use iroha_version::{error::Error, Version, UnsupportedVersion, RawVersioned}; use parity_scale_codec::DecodeAll; @@ -260,7 +281,7 @@ fn impl_decode_versioned(enum_name: &Ident, generics: &syn::Generics) -> proc_ma } } - impl #impl_generics iroha_version::scale::EncodeVersioned for #enum_name #ty_generics #where_clause { + impl #impl_generics iroha_version::scale::EncodeVersioned for #enum_name #ty_generics #encode_where_clause { fn encode_versioned(&self) -> Vec { use parity_scale_codec::Encode; diff --git a/version/src/lib.rs b/version/src/lib.rs index 8299e01a9e9..841197968f8 100644 --- a/version/src/lib.rs +++ b/version/src/lib.rs @@ -197,12 +197,12 @@ pub mod scale { #[cfg(not(feature = "std"))] use alloc::vec::Vec; - use parity_scale_codec::{Decode, Encode}; + use parity_scale_codec::{DecodeAll, Encode}; use super::{error::Result, Version}; /// [`Decode`] versioned analog. - pub trait DecodeVersioned: Decode + Version { + pub trait DecodeVersioned: DecodeAll + Version { /// Use this function for versioned objects instead of `decode_all`. /// /// # Errors diff --git a/wasm/src/lib.rs b/wasm/src/lib.rs index 96b5b4f2762..c79d3a4b1ea 100644 --- a/wasm/src/lib.rs +++ b/wasm/src/lib.rs @@ -14,7 +14,12 @@ extern crate alloc; use alloc::{boxed::Box, collections::BTreeMap, format, vec::Vec}; use core::ops::RangeFrom; -use data_model::{isi::Instruction, prelude::*, query::QueryBox, validator::NeedsValidationBox}; +use data_model::{ + isi::Instruction, + prelude::*, + query::{Query, QueryBox}, + validator::NeedsValidationBox, +}; use debug::DebugExpectExt as _; pub use iroha_data_model as data_model; pub use iroha_wasm_derive::main; diff --git a/wasm/validator/derive/src/validate.rs b/wasm/validator/derive/src/validate.rs index ae8f9ee74a2..881a47294bc 100644 --- a/wasm/validator/derive/src/validate.rs +++ b/wasm/validator/derive/src/validate.rs @@ -58,7 +58,9 @@ impl ValidateAttribute { continue; } - let Some(proc_macro2::TokenTree::Group(group))= attribute.tokens.clone().into_iter().next() else { + let Some(proc_macro2::TokenTree::Group(group)) = + attribute.tokens.clone().into_iter().next() + else { panic!("Expected parentheses group"); }; assert!(