diff --git a/.changelog/v1.5.0/improvements/3341-chain-runtime.md b/.changelog/v1.5.0/improvements/3341-chain-runtime.md new file mode 100644 index 0000000000..80bf148902 --- /dev/null +++ b/.changelog/v1.5.0/improvements/3341-chain-runtime.md @@ -0,0 +1,3 @@ +- Emit (g)RPC queries concurrently for increased throughput when + relaying on multiple chains/channels with a single Hermes instance + ([\#3341](https://github.com/informalsystems/hermes/issues/3341)) \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 02a3d79b95..64b8e99b6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,18 +58,18 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" dependencies = [ "memchr", ] [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "arc-swap" @@ -96,18 +96,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.29", ] [[package]] name = "async-trait" -version = "0.1.72" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.29", ] [[package]] @@ -145,9 +145,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", @@ -275,9 +275,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "block-buffer" @@ -360,9 +360,9 @@ checksum = "e6e9e01327e6c86e92ec72b1c798d4a94810f147209bbe3ffab6a86954937a6f" [[package]] name = "cargo-platform" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" +checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" dependencies = [ "serde", ] @@ -382,9 +382,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -488,9 +491,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "contracts" @@ -643,7 +646,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.29", ] [[package]] @@ -674,14 +677,20 @@ dependencies = [ [[package]] name = "der" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", ] +[[package]] +name = "deranged" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" + [[package]] name = "derivation-path" version = "0.2.0" @@ -755,15 +764,15 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "304e6508efa593091e97a9abbc10f90aa7ca635b6d2784feff3c89d41dd12272" +checksum = "bbfc4744c1b8f2a09adc0e55242f60b1af195d88596bd8700be74418c056c555" [[package]] name = "ecdsa" -version = "0.16.7" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", "digest 0.10.7", @@ -825,9 +834,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" @@ -884,18 +893,18 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "erased-serde" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da96524cc884f6558f1769b6c46686af2fe8e8b4cd253bd5a3cdba8181b8e070" +checksum = "fc978899517288e3ebbd1a3bfc1d9537dbb87eeab149e53ea490e63bcdff561a" dependencies = [ "serde", ] [[package]] name = "errno" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" dependencies = [ "errno-dragonfly", "libc", @@ -933,12 +942,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.9.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "ff" @@ -1053,7 +1059,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.29", ] [[package]] @@ -1296,9 +1302,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" @@ -1333,7 +1339,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -1386,7 +1392,7 @@ dependencies = [ "futures-util", "http", "hyper", - "rustls 0.21.5", + "rustls 0.21.6", "tokio", "tokio-rustls 0.24.1", ] @@ -1490,6 +1496,7 @@ dependencies = [ "num-bigint", "num-rational", "once_cell", + "parking_lot", "prost", "regex", "retry", @@ -1502,6 +1509,7 @@ dependencies = [ "serial_test", "sha2 0.10.7", "signature", + "std-semaphore", "strum", "subtle-encoding", "tendermint", @@ -1519,7 +1527,7 @@ dependencies = [ "tonic", "tracing", "tracing-subscriber", - "uuid 1.4.0", + "uuid 1.4.1", ] [[package]] @@ -1665,14 +1673,14 @@ dependencies = [ [[package]] name = "ics23" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af9e8f569c5cc88e08b8d076dc207e0748aa1f52d4b84910ec919c8f2bed6ea7" +checksum = "442d4bab37956e76f739c864f246c825d87c0bb7f9afa65660c57833c91bf6d4" dependencies = [ "anyhow", "bytes", "hex", - "pbjson", + "informalsystems-pbjson", "prost", "ripemd", "serde", @@ -1732,23 +1740,13 @@ dependencies = [ ] [[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.11" +name = "informalsystems-pbjson" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +checksum = "b4eecd90f87bea412eac91c6ef94f6b1e390128290898cbe14f2b926787ae1fb" dependencies = [ - "hermit-abi 0.3.2", - "libc", - "windows-sys 0.48.0", + "base64 0.13.1", + "serde", ] [[package]] @@ -1764,7 +1762,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.2", - "rustix 0.38.4", + "rustix", "windows-sys 0.48.0", ] @@ -1779,9 +1777,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" @@ -1827,15 +1825,9 @@ checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "linux-raw-sys" -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" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] name = "lock_api" @@ -1849,9 +1841,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "mach2" @@ -1873,9 +1865,9 @@ dependencies = [ [[package]] name = "matchit" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" +checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" [[package]] name = "maybe-uninit" @@ -1943,7 +1935,7 @@ dependencies = [ "tagptr", "thiserror", "triomphe", - "uuid 1.4.0", + "uuid 1.4.1", ] [[package]] @@ -2004,9 +1996,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] @@ -2152,24 +2144,14 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec", - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] name = "paste" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" - -[[package]] -name = "pbjson" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "048f9ac93c1eab514f9470c4bc8d97ca2a0a236b84f45cc19d69a59fc11467f6" -dependencies = [ - "base64 0.13.1", - "serde", -] +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pbkdf2" @@ -2215,29 +2197,29 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.29", ] [[package]] name = "pin-project-lite" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" +checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" [[package]] name = "pin-utils" @@ -2304,9 +2286,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.64" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -2393,9 +2375,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.29" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -2470,13 +2452,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.2", + "regex-automata 0.3.6", "regex-syntax 0.7.4", ] @@ -2491,9 +2473,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.2" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" dependencies = [ "aho-corasick", "memchr", @@ -2535,7 +2517,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.5", + "rustls 0.21.6", "rustls-pemfile", "serde", "serde_json", @@ -2614,28 +2596,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.23" +version = "0.38.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" +checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "errno", - "io-lifetimes", "libc", - "linux-raw-sys 0.3.8", - "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", - "libc", - "linux-raw-sys 0.4.3", + "linux-raw-sys", "windows-sys 0.48.0", ] @@ -2666,9 +2634,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.5" +version = "0.21.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36" +checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" dependencies = [ "log", "ring", @@ -2711,9 +2679,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.1" +version = "0.101.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e" +checksum = "261e9e0888cba427c3316e6322805653c9425240b6fd96cee7cb671ab70ab8d0" dependencies = [ "ring", "untrusted", @@ -2721,15 +2689,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "safe-proc-macro2" @@ -2807,9 +2775,9 @@ dependencies = [ [[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 = "sct" @@ -2833,9 +2801,9 @@ dependencies = [ [[package]] name = "sec1" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -2878,9 +2846,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -2891,9 +2859,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -2901,27 +2869,27 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.171" +version = "1.0.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" +checksum = "be9b6f69f1dfd54c3b568ffa45c310d6973a5e5148fd40cf515acaf38cf5bc31" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.11" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a16be4fe5320ade08736447e3198294a5ea9a6d44dde6f35f0a5e06859c427a" +checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" dependencies = [ "serde", ] @@ -2938,20 +2906,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.171" +version = "1.0.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" +checksum = "dc59dfdcbad1437773485e0367fea4b090a2e0a16d9ffc46af47764536a298ec" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.29", ] [[package]] name = "serde_json" -version = "1.0.102" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5062a995d481b2308b6064e9af76011f2921c35f97b0468811ed9f6cd91dfed" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" dependencies = [ "itoa", "ryu", @@ -2960,9 +2928,9 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc4422959dd87a76cb117c191dcbffc20467f06c9100b76721dab370f24d3a" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" dependencies = [ "itoa", "serde", @@ -2970,13 +2938,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.14" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d89a8107374290037607734c0b73a85db7ed80cae314b3c5791f192a496e731" +checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.29", ] [[package]] @@ -3002,9 +2970,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.22" +version = "0.9.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "452e67b9c20c37fa79df53201dc03839651086ed9bbe92b3ca585ca9fdaa7d85" +checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574" dependencies = [ "indexmap 2.0.0", "itoa", @@ -3035,7 +3003,7 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.29", ] [[package]] @@ -3173,6 +3141,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "spin" version = "0.5.2" @@ -3195,6 +3173,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "std-semaphore" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ae9eec00137a8eed469fb4148acd9fc6ac8c3f9b110f52cd34698c8b5bfa0e" + [[package]] name = "strsim" version = "0.10.0" @@ -3212,15 +3196,15 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.25.1" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6069ca09d878a33f883cc06aaa9718ede171841d3832450354410b718b097232" +checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" dependencies = [ "heck", "proc-macro2", "quote", "rustversion", - "syn 2.0.25", + "syn 2.0.29", ] [[package]] @@ -3257,9 +3241,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.25" +version = "2.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" +checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" dependencies = [ "proc-macro2", "quote", @@ -3292,15 +3276,14 @@ checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" [[package]] name = "tempfile" -version = "3.6.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ - "autocfg", "cfg-if 1.0.0", "fastrand", "redox_syscall 0.3.5", - "rustix 0.37.23", + "rustix", "windows-sys 0.48.0", ] @@ -3509,22 +3492,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.29", ] [[package]] @@ -3539,10 +3522,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.22" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" dependencies = [ + "deranged", "serde", "time-core", "time-macros", @@ -3556,9 +3540,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" dependencies = [ "time-core", ] @@ -3608,11 +3592,10 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.29.1" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ - "autocfg", "backtrace", "bytes", "libc", @@ -3621,7 +3604,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.3", "tokio-macros", "windows-sys 0.48.0", ] @@ -3644,7 +3627,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.29", ] [[package]] @@ -3675,7 +3658,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.5", + "rustls 0.21.6", "tokio", ] @@ -3736,9 +3719,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.12" +version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ "indexmap 2.0.0", "serde", @@ -3832,7 +3815,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.29", ] [[package]] @@ -3965,9 +3948,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-normalization" @@ -3992,9 +3975,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[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 = "untrusted" @@ -4015,9 +3998,9 @@ dependencies = [ [[package]] name = "urlencoding" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "utf-8" @@ -4039,9 +4022,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "uuid" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ "getrandom", ] @@ -4113,7 +4096,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.29", "wasm-bindgen-shared", ] @@ -4147,7 +4130,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.29", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4252,7 +4235,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -4272,17 +4255,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -4293,9 +4276,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" @@ -4305,9 +4288,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" @@ -4317,9 +4300,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" @@ -4329,9 +4312,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" @@ -4341,9 +4324,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" @@ -4353,9 +4336,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" @@ -4365,15 +4348,15 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.4.9" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529" +checksum = "d09770118a7eb1ccaf4a594a221334119a44a814fcb0d31c5b85e83e97227a97" dependencies = [ "memchr", ] @@ -4404,5 +4387,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.29", ] diff --git a/config.toml b/config.toml index e2a0720448..bd07242ac4 100644 --- a/config.toml +++ b/config.toml @@ -176,6 +176,15 @@ event_source = { mode = 'push', url = 'ws://127.0.0.1:26657/websocket', batch_de # Hermes uses a large preconfigured timeout (on the order of minutes). rpc_timeout = '10s' +# The maximum number of requests which can be issued to the chain concurrently. +# Higher number may increase throughput when relaying on multiple channels +# or between multiple chains but may also overload the node. +# If this value is set to 0, then the maximum amount of concurrency as +# determined by the system will be used, effectively disabling the limit. +# Doing this may completely overload the node. +# Default: 50 +max_concurrency = 50 + # Experimental: Whether or not the full node is trusted. # # If not trusted, Hermes will verify headers included in the `ClientUpdate` message using the light client. diff --git a/crates/relayer-cli/src/chain_registry.rs b/crates/relayer-cli/src/chain_registry.rs index 305a8d615a..f5f011e980 100644 --- a/crates/relayer-cli/src/chain_registry.rs +++ b/crates/relayer-cli/src/chain_registry.rs @@ -130,6 +130,7 @@ where batch_delay: default::batch_delay(), }, rpc_timeout: default::rpc_timeout(), + max_concurrency: default::max_concurrency(), trusted_node: default::trusted_node(), genesis_restart: None, account_prefix: chain_data.bech32_prefix, diff --git a/crates/relayer/Cargo.toml b/crates/relayer/Cargo.toml index 8aff2745c7..23262ceaec 100644 --- a/crates/relayer/Cargo.toml +++ b/crates/relayer/Cargo.toml @@ -69,6 +69,8 @@ secp256k1 = { version = "0.27.0", features = ["rand-std"] } strum = { version = "0.25", features = ["derive"] } tokio-stream = "0.1.14" once_cell = "1.17.1" +parking_lot = "0.12.1" +std-semaphore = "0.1" [dependencies.byte-unit] version = "4.0.19" diff --git a/crates/relayer/src/chain.rs b/crates/relayer/src/chain.rs index 958a3922d1..e250929730 100644 --- a/crates/relayer/src/chain.rs +++ b/crates/relayer/src/chain.rs @@ -4,7 +4,6 @@ pub mod counterparty; pub mod endpoint; pub mod handle; pub mod requests; -pub mod runtime; pub mod tracking; use serde::{de::Error, Deserialize, Serialize}; diff --git a/crates/relayer/src/chain/client.rs b/crates/relayer/src/chain/client.rs index b791c9d199..56abb2cf2f 100644 --- a/crates/relayer/src/chain/client.rs +++ b/crates/relayer/src/chain/client.rs @@ -1,7 +1,11 @@ //! Data structures and logic to set up IBC client's parameters. +use std::time::Duration; + +use ibc_relayer_types::core::ics02_client::trust_threshold::TrustThreshold; +use ibc_relayer_types::core::ics24_host::identifier::ChainId; + use crate::chain::cosmos; -use crate::config::ChainConfig; use crate::foreign_client::CreateOptions; /// Client parameters for the `build_create_client` operation. @@ -18,16 +22,22 @@ impl ClientSettings { /// and the destination chain. pub fn for_create_command( options: CreateOptions, - src_chain_config: &ChainConfig, - dst_chain_config: &ChainConfig, + src_clock_drift: Duration, + src_trust_threshold: TrustThreshold, + dst_clock_drift: Duration, + dst_max_block_time: Duration, + dst_chain_id: &ChainId, ) -> Self { // Currently, only Tendermint chain pairs are supported by // ForeignClient::build_create_client_and_send. Support for // heterogeneous chains is left for future revisions. ClientSettings::Tendermint(cosmos::client::Settings::for_create_command( options, - src_chain_config, - dst_chain_config, + src_clock_drift, + src_trust_threshold, + dst_clock_drift, + dst_max_block_time, + dst_chain_id, )) } } diff --git a/crates/relayer/src/chain/cosmos.rs b/crates/relayer/src/chain/cosmos.rs index ba67840dd1..c901caceed 100644 --- a/crates/relayer/src/chain/cosmos.rs +++ b/crates/relayer/src/chain/cosmos.rs @@ -10,9 +10,10 @@ use futures::future::join_all; use num_bigint::BigInt; use std::{cmp::Ordering, thread}; +use parking_lot::{Mutex, RwLock}; use tokio::runtime::Runtime as TokioRuntime; -use tonic::codegen::http::Uri; -use tonic::metadata::AsciiMetadataValue; +use tokio::sync::RwLock as AsyncRwLock; +use tonic::{codegen::http::Uri, metadata::AsciiMetadataValue}; use tracing::{error, info, instrument, trace, warn}; use ibc_proto::cosmos::{ @@ -147,12 +148,17 @@ pub struct CosmosSdkChain { grpc_addr: Uri, light_client: TmLightClient, rt: Arc, - keybase: KeyRing, + + /// The max block time, fetched from chain + max_block_time: RwLock, + + /// The keyring for this chain + keybase: RwLock>, /// A cached copy of the account information - account: Option, + account: AsyncRwLock>, - tx_monitor_cmd: Option, + tx_monitor_cmd: Mutex>, } impl CosmosSdkChain { @@ -167,7 +173,8 @@ impl CosmosSdkChain { } fn key(&self) -> Result { - self.keybase() + self.keybase + .read() .get_key(&self.config.key_name) .map_err(Error::key_base) } @@ -192,7 +199,7 @@ impl CosmosSdkChain { /// /// Emits a log warning in case any error is encountered and /// exits early without doing subsequent validations. - pub fn validate_params(&mut self) -> Result<(), Error> { + pub fn validate_params(&self) -> Result<(), Error> { let unbonding_period = self.unbonding_period()?; let trusting_period = self.trusting_period(unbonding_period); @@ -291,13 +298,16 @@ impl CosmosSdkChain { match self.block_on(self.rpc_client.genesis::()) { Ok(genesis_reponse) => { let old_max_block_time = self.config.max_block_time; - self.config.max_block_time = + let new_max_block_time = Duration::from_nanos(genesis_reponse.app_state.max_expected_time_per_block()); + info!( "Updated `max_block_time` using /genesis endpoint. Old value: `{}s`, new value: `{}s`", old_max_block_time.as_secs(), - self.config.max_block_time.as_secs() + new_max_block_time.as_secs() ); + + *self.max_block_time.write() = new_max_block_time; } Err(e) => { warn!( @@ -305,12 +315,12 @@ impl CosmosSdkChain { self.config.max_block_time.as_secs() ); } - } + }; Ok(()) } - fn init_event_source(&mut self) -> Result { + fn init_event_source(&self) -> Result { crate::time!( "init_event_source", { @@ -668,7 +678,7 @@ impl CosmosSdkChain { ), )] async fn do_send_messages_and_wait_commit( - &mut self, + &self, tracked_msgs: TrackedMsgs, ) -> Result, Error> { crate::time!( @@ -683,8 +693,10 @@ impl CosmosSdkChain { let key_pair = self.key()?; let key_account = key_pair.account(); - let account = - get_or_fetch_account(&self.grpc_addr, &key_account, &mut self.account).await?; + // Take a write lock on the current account, + // excluding anybody from sending txs until we are done. + let mut opt_account = self.account.write().await; + let account = get_or_fetch_account(&self.grpc_addr, &key_account, &mut opt_account).await?; if self.config.sequential_batch_tx { sequential_send_batched_messages_and_wait_commit( @@ -719,7 +731,7 @@ impl CosmosSdkChain { ), )] async fn do_send_messages_and_wait_check_tx( - &mut self, + &self, tracked_msgs: TrackedMsgs, ) -> Result, Error> { crate::time!( @@ -734,8 +746,10 @@ impl CosmosSdkChain { let key_pair = self.key()?; let key_account = key_pair.account(); - let account = - get_or_fetch_account(&self.grpc_addr, &key_account, &mut self.account).await?; + // Take a write lock on the current account, + // excluding anybody from sending txs until we are done. + let mut opt_account = self.account.write().await; + let account = get_or_fetch_account(&self.grpc_addr, &key_account, &mut opt_account).await?; send_batched_messages_and_wait_check_tx( &self.rpc_client, @@ -748,6 +762,33 @@ impl CosmosSdkChain { .await } + async fn do_maybe_register_counterparty_payee( + &self, + channel_id: &ChannelId, + port_id: &PortId, + counterparty_payee: &Signer, + ) -> Result<(), Error> { + let address = self.get_signer()?; + let key_pair = self.key()?; + + // Take a write lock on the current account, + // excluding anybody from sending txs until we are done. + let mut opt_account = self.account.write().await; + + maybe_register_counterparty_payee( + &self.rpc_client, + &self.tx_config, + &key_pair, + &mut opt_account, + &self.config.memo_prefix, + channel_id, + port_id, + &address, + counterparty_payee, + ) + .await + } + fn query_packet_from_block( &self, request: &QueryPacketEventDataRequest, @@ -900,6 +941,7 @@ impl ChainEndpoint for CosmosSdkChain { .map_err(|e| Error::invalid_uri(config.grpc_addr.to_string(), e))?; let tx_config = TxConfig::try_from(&config)?; + let max_block_time = config.max_block_time; // Retrieve the version specification of this chain @@ -910,38 +952,55 @@ impl ChainEndpoint for CosmosSdkChain { grpc_addr, light_client, rt, - keybase, tx_config, - account: None, - tx_monitor_cmd: None, + max_block_time: RwLock::new(max_block_time), + keybase: RwLock::new(keybase), + account: AsyncRwLock::new(None), + tx_monitor_cmd: Mutex::new(None), }; Ok(chain) } - fn shutdown(self) -> Result<(), Error> { - if let Some(monitor_tx) = self.tx_monitor_cmd { + fn shutdown(&self) -> Result<(), Error> { + let cmd = self.tx_monitor_cmd.lock(); + + if let Some(monitor_tx) = cmd.as_ref() { monitor_tx.shutdown().map_err(Error::event_source)?; } Ok(()) } - fn keybase(&self) -> &KeyRing { - &self.keybase + fn get_key(&self) -> Result { + // Get the key from key seed file + let key_pair = self + .keybase + .read() + .get_key(&self.config().key_name) + .map_err(|e| Error::key_not_found(self.config().key_name.clone(), e))?; + + Ok(key_pair) } - fn keybase_mut(&mut self) -> &mut KeyRing { - &mut self.keybase + fn add_key(&self, key_name: &str, key_pair: Self::SigningKeyPair) -> Result<(), Error> { + self.keybase + .write() + .add_key(key_name, key_pair) + .map_err(Error::key_base)?; + + Ok(()) } - fn subscribe(&mut self) -> Result { - let tx_monitor_cmd = match &self.tx_monitor_cmd { + fn subscribe(&self) -> Result { + let mut cmd = self.tx_monitor_cmd.lock(); + + let tx_monitor_cmd = match cmd.as_ref() { Some(tx_monitor_cmd) => tx_monitor_cmd, None => { let tx_monitor_cmd = self.init_event_source()?; - self.tx_monitor_cmd = Some(tx_monitor_cmd); - self.tx_monitor_cmd.as_ref().unwrap() + *cmd = Some(tx_monitor_cmd); + cmd.as_ref().unwrap() } }; @@ -960,7 +1019,7 @@ impl ChainEndpoint for CosmosSdkChain { /// Emits a log warning in case anything is amiss. /// Exits early if any health check fails, without doing any /// further checks. - fn health_check(&mut self) -> Result { + fn health_check(&self) -> Result { if let Err(e) = do_health_check(self) { warn!("Health checkup for chain '{}' failed", self.id()); warn!(" Reason: {}", e.detail()); @@ -982,7 +1041,7 @@ impl ChainEndpoint for CosmosSdkChain { /// Fetch a header from the chain at the given height and verify it. fn verify_header( - &mut self, + &self, trusted: ICSHeight, target: ICSHeight, client_state: &AnyClientState, @@ -1003,7 +1062,7 @@ impl ChainEndpoint for CosmosSdkChain { /// Perform misbehavior detection for the given client state and update event. fn check_misbehaviour( - &mut self, + &self, update: &UpdateClient, client_state: &AnyClientState, ) -> Result, Error> { @@ -1031,7 +1090,7 @@ impl ChainEndpoint for CosmosSdkChain { /// TODO - more work is required here for a smarter split maybe iteratively accumulating/ evaluating /// msgs in a Tx until any of the max size, max num msgs, max fee are exceeded. fn send_messages_and_wait_commit( - &mut self, + &self, tracked_msgs: TrackedMsgs, ) -> Result, Error> { let runtime = self.rt.clone(); @@ -1040,7 +1099,7 @@ impl ChainEndpoint for CosmosSdkChain { } fn send_messages_and_wait_check_tx( - &mut self, + &self, tracked_msgs: TrackedMsgs, ) -> Result, Error> { let runtime = self.rt.clone(); @@ -1063,6 +1122,10 @@ impl ChainEndpoint for CosmosSdkChain { &self.config } + fn max_block_time(&self) -> Duration { + *self.max_block_time.read() + } + fn ibc_version(&self) -> Result, Error> { let version_specs = self.block_on(fetch_version_specs(self.id(), &self.grpc_addr))?; Ok(version_specs.ibc_go) @@ -1072,9 +1135,14 @@ impl ChainEndpoint for CosmosSdkChain { // If a key_name is given, extract the account hash. // Else retrieve the account from the configuration file. let key = match key_name { - Some(key_name) => self.keybase().get_key(key_name).map_err(Error::key_base)?, None => self.key()?, + Some(key_name) => self + .keybase + .read() + .get_key(key_name) + .map_err(Error::key_base)?, }; + let account = key.account(); let denom = denom.unwrap_or(&self.config.gas_price.denom); @@ -1087,9 +1155,14 @@ impl ChainEndpoint for CosmosSdkChain { // If a key_name is given, extract the account hash. // Else retrieve the account from the configuration file. let key = match key_name { - Some(key_name) => self.keybase().get_key(key_name).map_err(Error::key_base)?, None => self.key()?, + Some(key_name) => self + .keybase + .read() + .get_key(key_name) + .map_err(Error::key_base)?, }; + let account = key.account(); let balance = self.block_on(query_all_balances(&self.grpc_addr, &account))?; @@ -2164,7 +2237,7 @@ impl ChainEndpoint for CosmosSdkChain { } fn build_header( - &mut self, + &self, trusted_height: ICSHeight, target_height: ICSHeight, client_state: &AnyClientState, @@ -2190,23 +2263,14 @@ impl ChainEndpoint for CosmosSdkChain { } fn maybe_register_counterparty_payee( - &mut self, + &self, channel_id: &ChannelId, port_id: &PortId, counterparty_payee: &Signer, ) -> Result<(), Error> { - let address = self.get_signer()?; - let key_pair = self.key()?; - - self.rt.block_on(maybe_register_counterparty_payee( - &self.rpc_client, - &self.tx_config, - &key_pair, - &mut self.account, - &self.config.memo_prefix, + self.rt.block_on(self.do_maybe_register_counterparty_payee( channel_id, port_id, - &address, counterparty_payee, )) } diff --git a/crates/relayer/src/chain/cosmos/client.rs b/crates/relayer/src/chain/cosmos/client.rs index 9196a93f87..0226b16c81 100644 --- a/crates/relayer/src/chain/cosmos/client.rs +++ b/crates/relayer/src/chain/cosmos/client.rs @@ -5,13 +5,13 @@ use core::time::Duration; use tracing::warn; use ibc_relayer_types::core::ics02_client::trust_threshold::TrustThreshold; +use ibc_relayer_types::core::ics24_host::identifier::ChainId; -use crate::config::ChainConfig; use crate::foreign_client::CreateOptions; use crate::util::pretty::PrettyDuration; /// Cosmos-specific client parameters for the `build_client_state` operation. -#[derive(Clone, Debug, Default)] +#[derive(Copy, Clone, Debug, Default)] pub struct Settings { pub max_clock_drift: Duration, pub trusting_period: Option, @@ -21,32 +21,33 @@ pub struct Settings { impl Settings { pub fn for_create_command( options: CreateOptions, - src_chain_config: &ChainConfig, - dst_chain_config: &ChainConfig, + src_clock_drift: Duration, + src_trust_threshold: TrustThreshold, + dst_clock_drift: Duration, + dst_max_block_time: Duration, + dst_chain_id: &ChainId, ) -> Self { let max_clock_drift = match options.max_clock_drift { - None => calculate_client_state_drift(src_chain_config, dst_chain_config), + None => { + calculate_client_state_drift(src_clock_drift, dst_clock_drift, dst_max_block_time) + } Some(user_value) => { - if user_value > dst_chain_config.max_block_time { + if user_value > dst_max_block_time { warn!( "user specified max_clock_drift ({}) exceeds max_block_time \ of the destination chain {}", PrettyDuration(&user_value), - dst_chain_config.id, + dst_chain_id, ); } user_value } }; - let trust_threshold = options - .trust_threshold - .unwrap_or_else(|| src_chain_config.trust_threshold.into()); - Settings { max_clock_drift, trusting_period: options.trusting_period, - trust_threshold, + trust_threshold: options.trust_threshold.unwrap_or(src_trust_threshold), } } } @@ -55,8 +56,9 @@ impl Settings { /// chain block frequency and clock drift on source and dest. /// https://github.com/informalsystems/hermes/issues/1445 fn calculate_client_state_drift( - src_chain_config: &ChainConfig, - dst_chain_config: &ChainConfig, + src_clock_drift: Duration, + dst_clock_drift: Duration, + dst_max_block_time: Duration, ) -> Duration { - src_chain_config.clock_drift + dst_chain_config.clock_drift + dst_chain_config.max_block_time + src_clock_drift + dst_clock_drift + dst_max_block_time } diff --git a/crates/relayer/src/chain/cosmos/query/consensus_state.rs b/crates/relayer/src/chain/cosmos/query/consensus_state.rs index 3949045757..9625b3789b 100644 --- a/crates/relayer/src/chain/cosmos/query/consensus_state.rs +++ b/crates/relayer/src/chain/cosmos/query/consensus_state.rs @@ -88,16 +88,16 @@ pub async fn query_consensus_state_heights( } pub async fn query_consensus_states( - chain_id: &ChainId, + _chain_id: &ChainId, grpc_addr: &Uri, request: QueryConsensusStatesRequest, ) -> Result, Error> { - crate::telemetry!(query, chain_id, "query_consensus_states"); + crate::telemetry!(query, _chain_id, "query_consensus_states"); crate::time!( "query_consensus_states", { - "src_chain": chain_id, + "src_chain": _chain_id, } ); diff --git a/crates/relayer/src/chain/endpoint.rs b/crates/relayer/src/chain/endpoint.rs index 5d2f70ab10..1e640de4e1 100644 --- a/crates/relayer/src/chain/endpoint.rs +++ b/crates/relayer/src/chain/endpoint.rs @@ -1,5 +1,6 @@ use alloc::sync::Arc; use core::convert::TryFrom; +use std::time::Duration; use tokio::runtime::Runtime as TokioRuntime; @@ -43,7 +44,7 @@ use crate::consensus_state::AnyConsensusState; use crate::denom::DenomTrace; use crate::error::Error; use crate::event::IbcEventWithHeight; -use crate::keyring::{AnySigningKeyPair, KeyRing, SigningKeyPairSized}; +use crate::keyring::{AnySigningKeyPair, SigningKeyPairSized}; use crate::light_client::AnyHeader; use crate::misbehaviour::MisbehaviourEvidence; @@ -95,42 +96,29 @@ pub trait ChainEndpoint: Sized { fn bootstrap(config: ChainConfig, rt: Arc) -> Result; /// Shutdown the chain runtime - fn shutdown(self) -> Result<(), Error>; + fn shutdown(&self) -> Result<(), Error>; /// Perform a health check - fn health_check(&mut self) -> Result; + fn health_check(&self) -> Result; // Events - fn subscribe(&mut self) -> Result; + fn subscribe(&self) -> Result; - // Keyring + // Misc - /// Returns the chain's keybase - fn keybase(&self) -> &KeyRing; + /// Return the max block time for this chain + fn max_block_time(&self) -> Duration; - /// Returns the chain's keybase, mutably - fn keybase_mut(&mut self) -> &mut KeyRing; + // Keyring + /// Get the signer from the keyring fn get_signer(&self) -> Result; - /// Get the signing key pair - fn get_key(&mut self) -> Result { - // Get the key from key seed file - let key_pair = self - .keybase() - .get_key(&self.config().key_name) - .map_err(|e| Error::key_not_found(self.config().key_name.clone(), e))?; - - Ok(key_pair) - } - - fn add_key(&mut self, key_name: &str, key_pair: Self::SigningKeyPair) -> Result<(), Error> { - self.keybase_mut() - .add_key(key_name, key_pair) - .map_err(Error::key_base)?; + /// Get the signing key pair from the keyring + fn get_key(&self) -> Result; - Ok(()) - } + // Add a new key to the keyring + fn add_key(&self, key_name: &str, key_pair: Self::SigningKeyPair) -> Result<(), Error>; // Versioning @@ -142,20 +130,20 @@ pub trait ChainEndpoint: Sized { /// Sends one or more transactions with `msgs` to chain and /// synchronously wait for it to be committed. fn send_messages_and_wait_commit( - &mut self, + &self, tracked_msgs: TrackedMsgs, ) -> Result, Error>; /// Sends one or more transactions with `msgs` to chain. /// Non-blocking alternative to `send_messages_and_wait_commit` interface. fn send_messages_and_wait_check_tx( - &mut self, + &self, tracked_msgs: TrackedMsgs, ) -> Result, Error>; /// Fetch a header from the chain at the given height and verify it. fn verify_header( - &mut self, + &self, trusted: ICSHeight, target: ICSHeight, client_state: &AnyClientState, @@ -164,7 +152,7 @@ pub trait ChainEndpoint: Sized { /// Given a client update event that includes the header used in a client update, /// look for misbehaviour by fetching a header at same or latest height. fn check_misbehaviour( - &mut self, + &self, update: &UpdateClient, client_state: &AnyClientState, ) -> Result, Error>; @@ -382,7 +370,7 @@ pub trait ChainEndpoint: Sized { /// Returns all the supporting headers that were need to verify the target /// header, for use when building a `ClientUpdate` message. fn build_header( - &mut self, + &self, trusted_height: ICSHeight, target_height: ICSHeight, client_state: &AnyClientState, @@ -671,7 +659,7 @@ pub trait ChainEndpoint: Sized { } fn maybe_register_counterparty_payee( - &mut self, + &self, channel_id: &ChannelId, port_id: &PortId, counterparty_payee: &Signer, diff --git a/crates/relayer/src/chain/handle.rs b/crates/relayer/src/chain/handle.rs index be905173cb..b4cd1b70e2 100644 --- a/crates/relayer/src/chain/handle.rs +++ b/crates/relayer/src/chain/handle.rs @@ -1,8 +1,8 @@ use alloc::sync::Arc; use core::fmt::{self, Debug, Display}; +use std::time::Duration; use crossbeam_channel as channel; -use tracing::Span; use ibc_proto::ibc::apps::fee::v1::{ QueryIncentivizedPacketRequest, QueryIncentivizedPacketResponse, @@ -90,287 +90,10 @@ impl Debug for ChainHandlePair>>; -pub type ReplyTo = channel::Sender>; -pub type Reply = channel::Receiver>; - -pub fn reply_channel() -> (ReplyTo, Reply) { - channel::bounded(1) -} - -/// Requests that a `ChainHandle` may send to a `ChainRuntime`. -#[derive(Clone, Debug)] -#[allow(clippy::large_enum_variant)] -pub enum ChainRequest { - Shutdown { - reply_to: ReplyTo<()>, - }, - - HealthCheck { - reply_to: ReplyTo, - }, - - Subscribe { - reply_to: ReplyTo, - }, - - SendMessagesAndWaitCommit { - tracked_msgs: TrackedMsgs, - reply_to: ReplyTo>, - }, - - SendMessagesAndWaitCheckTx { - tracked_msgs: TrackedMsgs, - reply_to: ReplyTo>, - }, - - Config { - reply_to: ReplyTo, - }, - - Signer { - reply_to: ReplyTo, - }, - - GetKey { - reply_to: ReplyTo, - }, - - AddKey { - key_name: String, - key: AnySigningKeyPair, - reply_to: ReplyTo<()>, - }, - - IbcVersion { - reply_to: ReplyTo>, - }, - - QueryBalance { - key_name: Option, - denom: Option, - reply_to: ReplyTo, - }, - - QueryAllBalances { - key_name: Option, - reply_to: ReplyTo>, - }, - - QueryDenomTrace { - hash: String, - reply_to: ReplyTo, - }, - - QueryApplicationStatus { - reply_to: ReplyTo, - }, - - QueryClients { - request: QueryClientStatesRequest, - reply_to: ReplyTo>, - }, - - BuildHeader { - trusted_height: Height, - target_height: Height, - client_state: AnyClientState, - reply_to: ReplyTo<(AnyHeader, Vec)>, - }, - - BuildClientState { - height: Height, - settings: ClientSettings, - reply_to: ReplyTo, - }, - - BuildConsensusState { - trusted: Height, - target: Height, - client_state: AnyClientState, - reply_to: ReplyTo, - }, - - BuildMisbehaviour { - client_state: AnyClientState, - update_event: UpdateClient, - reply_to: ReplyTo>, - }, - - BuildConnectionProofsAndClientState { - message_type: ConnectionMsgType, - connection_id: ConnectionId, - client_id: ClientId, - height: Height, - reply_to: ReplyTo<(Option, Proofs)>, - }, - - QueryClientState { - request: QueryClientStateRequest, - include_proof: IncludeProof, - reply_to: ReplyTo<(AnyClientState, Option)>, - }, - - QueryClientConnections { - request: QueryClientConnectionsRequest, - reply_to: ReplyTo>, - }, - - QueryConsensusState { - request: QueryConsensusStateRequest, - include_proof: IncludeProof, - reply_to: ReplyTo<(AnyConsensusState, Option)>, - }, - - QueryConsensusStateHeights { - request: QueryConsensusStateHeightsRequest, - reply_to: ReplyTo>, - }, - - QueryUpgradedClientState { - request: QueryUpgradedClientStateRequest, - reply_to: ReplyTo<(AnyClientState, MerkleProof)>, - }, - - QueryUpgradedConsensusState { - request: QueryUpgradedConsensusStateRequest, - reply_to: ReplyTo<(AnyConsensusState, MerkleProof)>, - }, - - QueryCommitmentPrefix { - reply_to: ReplyTo, - }, - - QueryCompatibleVersions { - reply_to: ReplyTo>, - }, - - QueryConnection { - request: QueryConnectionRequest, - include_proof: IncludeProof, - reply_to: ReplyTo<(ConnectionEnd, Option)>, - }, - - QueryConnections { - request: QueryConnectionsRequest, - reply_to: ReplyTo>, - }, - - QueryConnectionChannels { - request: QueryConnectionChannelsRequest, - reply_to: ReplyTo>, - }, - - QueryChannels { - request: QueryChannelsRequest, - reply_to: ReplyTo>, - }, - - QueryChannel { - request: QueryChannelRequest, - include_proof: IncludeProof, - reply_to: ReplyTo<(ChannelEnd, Option)>, - }, - - QueryChannelClientState { - request: QueryChannelClientStateRequest, - reply_to: ReplyTo>, - }, - - QueryNextSequenceReceive { - request: QueryNextSequenceReceiveRequest, - include_proof: IncludeProof, - reply_to: ReplyTo<(Sequence, Option)>, - }, - - BuildChannelProofs { - port_id: PortId, - channel_id: ChannelId, - height: Height, - reply_to: ReplyTo, - }, - - BuildPacketProofs { - packet_type: PacketMsgType, - port_id: PortId, - channel_id: ChannelId, - sequence: Sequence, - height: Height, - reply_to: ReplyTo, - }, - - QueryPacketCommitment { - request: QueryPacketCommitmentRequest, - include_proof: IncludeProof, - reply_to: ReplyTo<(Vec, Option)>, - }, - - QueryPacketCommitments { - request: QueryPacketCommitmentsRequest, - reply_to: ReplyTo<(Vec, Height)>, - }, - - QueryPacketReceipt { - request: QueryPacketReceiptRequest, - include_proof: IncludeProof, - reply_to: ReplyTo<(Vec, Option)>, - }, - - QueryUnreceivedPackets { - request: QueryUnreceivedPacketsRequest, - reply_to: ReplyTo>, - }, - - QueryPacketAcknowledgement { - request: QueryPacketAcknowledgementRequest, - include_proof: IncludeProof, - reply_to: ReplyTo<(Vec, Option)>, - }, - - QueryPacketAcknowledgements { - request: QueryPacketAcknowledgementsRequest, - reply_to: ReplyTo<(Vec, Height)>, - }, - - QueryUnreceivedAcknowledgement { - request: QueryUnreceivedAcksRequest, - reply_to: ReplyTo>, - }, - - QueryPacketEventDataFromTxs { - request: QueryTxRequest, - reply_to: ReplyTo>, - }, - - QueryPacketEventData { - request: QueryPacketEventDataRequest, - reply_to: ReplyTo>, - }, - - QueryHostConsensusState { - request: QueryHostConsensusStateRequest, - reply_to: ReplyTo, - }, - - MaybeRegisterCounterpartyPayee { - channel_id: ChannelId, - port_id: PortId, - counterparty_payee: Signer, - reply_to: ReplyTo<()>, - }, - - CrossChainQuery { - request: Vec, - reply_to: ReplyTo>, - }, - - QueryIncentivizedPacket { - request: QueryIncentivizedPacketRequest, - reply_to: ReplyTo, - }, -} +pub type ChainImpl = crate::spawn::ChainImpl; pub trait ChainHandle: Clone + Display + Send + Sync + Debug + 'static { - fn new(chain_id: ChainId, sender: channel::Sender<(Span, ChainRequest)>) -> Self; + fn new(chain: Arc) -> Self; /// Get the [`ChainId`] of this chain. fn id(&self) -> ChainId; @@ -404,6 +127,8 @@ pub trait ChainHandle: Clone + Display + Send + Sync + Debug + 'static { fn config(&self) -> Result; + fn max_block_time(&self) -> Duration; + fn get_key(&self) -> Result; fn add_key(&self, key_name: String, key: AnySigningKeyPair) -> Result<(), Error>; diff --git a/crates/relayer/src/chain/handle/base.rs b/crates/relayer/src/chain/handle/base.rs index 2c2264f55c..4afe0cd8c9 100644 --- a/crates/relayer/src/chain/handle/base.rs +++ b/crates/relayer/src/chain/handle/base.rs @@ -1,7 +1,5 @@ -use core::fmt::{Debug, Display, Error as FmtError, Formatter}; - -use crossbeam_channel as channel; -use tracing::Span; +use core::fmt::{self, Debug, Display, Error as FmtError, Formatter}; +use std::{sync::Arc, time::Duration}; use ibc_proto::ibc::apps::fee::v1::{ QueryIncentivizedPacketRequest, QueryIncentivizedPacketResponse, @@ -23,10 +21,16 @@ use ibc_relayer_types::{ signer::Signer, Height, }; +use std_semaphore::Semaphore; use crate::{ account::Balance, - chain::{client::ClientSettings, endpoint::ChainStatus, requests::*, tracking::TrackedMsgs}, + chain::{ + client::ClientSettings, + endpoint::{ChainEndpoint, ChainStatus}, + requests::*, + tracking::TrackedMsgs, + }, client_state::{AnyClientState, IdentifiedAnyClientState}, config::ChainConfig, connection::ConnectionMsgType, @@ -39,114 +43,136 @@ use crate::{ misbehaviour::MisbehaviourEvidence, }; -use super::{reply_channel, ChainHandle, ChainRequest, HealthCheck, ReplyTo, Subscription}; +use super::{ChainHandle, ChainImpl, HealthCheck, Subscription}; /// A basic chain handle implementation. /// For use in interactive CLIs, e.g., `query`, `tx`, etc. -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct BaseChainHandle { - /// Chain identifier - chain_id: ChainId, + /// The chain implementation + chain: Arc, - /// The handle's channel for sending requests to the runtime - runtime_sender: channel::Sender<(Span, ChainRequest)>, + /// A semaphore to limit the number of concurrent requests to the chain + semaphore: Arc, } -impl BaseChainHandle { - pub fn new(chain_id: ChainId, sender: channel::Sender<(Span, ChainRequest)>) -> Self { - Self { - chain_id, - runtime_sender: sender, - } - } - - fn send(&self, f: F) -> Result - where - F: FnOnce(ReplyTo) -> ChainRequest, - O: Debug, - { - let (sender, receiver) = reply_channel(); - - let span = Span::current(); - let input = f(sender); - - self.runtime_sender - .send((span, input)) - .map_err(Error::send)?; - - receiver.recv().map_err(Error::channel_receive)? +impl Debug for BaseChainHandle { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("BaseChainHandle") + .field("chain_id", &self.id()) + .finish() } } impl Display for BaseChainHandle { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { - write!(f, "BaseChainHandle {{ chain_id: {} }}", self.chain_id) + write!(f, "BaseChainHandle {{ chain_id: {} }}", self.id()) + } +} + +impl BaseChainHandle { + pub fn new(chain: Arc) -> Self { + // The semaphore is initialized with the maximum number of concurrent requests. + // If that number was specified as 0, then we use the maximum amount of concurrency, + // and effectively disable the limit. + let max_concurrency = Some(chain.config().max_concurrency) + .filter(|&n| n > 0) + .unwrap_or(u16::MAX); + + Self { + chain, + semaphore: Arc::new(Semaphore::new(max_concurrency as isize)), + } } } impl ChainHandle for BaseChainHandle { - fn new(chain_id: ChainId, sender: channel::Sender<(Span, ChainRequest)>) -> Self { - Self::new(chain_id, sender) + fn new(chain: Arc) -> Self { + Self::new(chain) } fn id(&self) -> ChainId { - self.chain_id.clone() + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.id().clone(), + } } fn health_check(&self) -> Result { - self.send(|reply_to| ChainRequest::HealthCheck { reply_to }) + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.health_check(), + } } fn shutdown(&self) -> Result<(), Error> { - self.send(|reply_to| ChainRequest::Shutdown { reply_to }) + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.shutdown(), + } } fn subscribe(&self) -> Result { - self.send(|reply_to| ChainRequest::Subscribe { reply_to }) + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.subscribe(), + } } fn send_messages_and_wait_commit( &self, tracked_msgs: TrackedMsgs, ) -> Result, Error> { - self.send(|reply_to| ChainRequest::SendMessagesAndWaitCommit { - tracked_msgs, - reply_to, - }) + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.send_messages_and_wait_commit(tracked_msgs), + } } fn send_messages_and_wait_check_tx( &self, tracked_msgs: TrackedMsgs, ) -> Result, Error> { - self.send(|reply_to| ChainRequest::SendMessagesAndWaitCheckTx { - tracked_msgs, - reply_to, - }) + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.send_messages_and_wait_check_tx(tracked_msgs), + } } fn get_signer(&self) -> Result { - self.send(|reply_to| ChainRequest::Signer { reply_to }) + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.get_signer(), + } } fn config(&self) -> Result { - self.send(|reply_to| ChainRequest::Config { reply_to }) + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => Ok(chain.config().clone()), // FIXME + } + } + + fn max_block_time(&self) -> Duration { + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.max_block_time(), + } } fn get_key(&self) -> Result { - self.send(|reply_to| ChainRequest::GetKey { reply_to }) + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.get_key().map(Into::into), + } } fn add_key(&self, key_name: String, key: AnySigningKeyPair) -> Result<(), Error> { - self.send(|reply_to| ChainRequest::AddKey { - key_name, - key, - reply_to, - }) + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => { + let key = key + .downcast() + .ok_or_else(|| Error::invalid_key_type(key.key_type()))?; + + chain.add_key(&key_name, key) // FIXME + } + } } fn ibc_version(&self) -> Result, Error> { - self.send(|reply_to| ChainRequest::IbcVersion { reply_to }) + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.ibc_version(), + } } fn query_balance( @@ -154,30 +180,48 @@ impl ChainHandle for BaseChainHandle { key_name: Option, denom: Option, ) -> Result { - self.send(|reply_to| ChainRequest::QueryBalance { - key_name, - denom, - reply_to, - }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => { + chain.query_balance(key_name.as_deref(), denom.as_deref()) + } // FIXME + } } fn query_all_balances(&self, key_name: Option) -> Result, Error> { - self.send(|reply_to| ChainRequest::QueryAllBalances { key_name, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_all_balances(key_name.as_deref()), // FIXME + } } fn query_denom_trace(&self, hash: String) -> Result { - self.send(|reply_to| ChainRequest::QueryDenomTrace { hash, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_denom_trace(hash), + } } fn query_application_status(&self) -> Result { - self.send(|reply_to| ChainRequest::QueryApplicationStatus { reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_application_status(), + } } fn query_clients( &self, request: QueryClientStatesRequest, ) -> Result, Error> { - self.send(|reply_to| ChainRequest::QueryClients { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_clients(request), + } } fn query_client_state( @@ -185,25 +229,33 @@ impl ChainHandle for BaseChainHandle { request: QueryClientStateRequest, include_proof: IncludeProof, ) -> Result<(AnyClientState, Option), Error> { - self.send(|reply_to| ChainRequest::QueryClientState { - request, - include_proof, - reply_to, - }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_client_state(request, include_proof), + } } fn query_client_connections( &self, request: QueryClientConnectionsRequest, ) -> Result, Error> { - self.send(|reply_to| ChainRequest::QueryClientConnections { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_client_connections(request), + } } fn query_consensus_state_heights( &self, request: QueryConsensusStateHeightsRequest, ) -> Result, Error> { - self.send(|reply_to| ChainRequest::QueryConsensusStateHeights { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_consensus_state_heights(request), + } } fn query_consensus_state( @@ -211,33 +263,49 @@ impl ChainHandle for BaseChainHandle { request: QueryConsensusStateRequest, include_proof: IncludeProof, ) -> Result<(AnyConsensusState, Option), Error> { - self.send(|reply_to| ChainRequest::QueryConsensusState { - request, - include_proof, - reply_to, - }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_consensus_state(request, include_proof), + } } fn query_upgraded_client_state( &self, request: QueryUpgradedClientStateRequest, ) -> Result<(AnyClientState, MerkleProof), Error> { - self.send(|reply_to| ChainRequest::QueryUpgradedClientState { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_upgraded_client_state(request), + } } fn query_upgraded_consensus_state( &self, request: QueryUpgradedConsensusStateRequest, ) -> Result<(AnyConsensusState, MerkleProof), Error> { - self.send(|reply_to| ChainRequest::QueryUpgradedConsensusState { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_upgraded_consensus_state(request), + } } fn query_commitment_prefix(&self) -> Result { - self.send(|reply_to| ChainRequest::QueryCommitmentPrefix { reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_commitment_prefix(), + } } fn query_compatible_versions(&self) -> Result, Error> { - self.send(|reply_to| ChainRequest::QueryCompatibleVersions { reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_compatible_versions(), + } } fn query_connection( @@ -245,25 +313,33 @@ impl ChainHandle for BaseChainHandle { request: QueryConnectionRequest, include_proof: IncludeProof, ) -> Result<(ConnectionEnd, Option), Error> { - self.send(|reply_to| ChainRequest::QueryConnection { - request, - include_proof, - reply_to, - }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_connection(request, include_proof), + } } fn query_connections( &self, request: QueryConnectionsRequest, ) -> Result, Error> { - self.send(|reply_to| ChainRequest::QueryConnections { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_connections(request), + } } fn query_connection_channels( &self, request: QueryConnectionChannelsRequest, ) -> Result, Error> { - self.send(|reply_to| ChainRequest::QueryConnectionChannels { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_connection_channels(request), + } } fn query_next_sequence_receive( @@ -271,18 +347,24 @@ impl ChainHandle for BaseChainHandle { request: QueryNextSequenceReceiveRequest, include_proof: IncludeProof, ) -> Result<(Sequence, Option), Error> { - self.send(|reply_to| ChainRequest::QueryNextSequenceReceive { - request, - include_proof, - reply_to, - }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => { + chain.query_next_sequence_receive(request, include_proof) + } + } } fn query_channels( &self, request: QueryChannelsRequest, ) -> Result, Error> { - self.send(|reply_to| ChainRequest::QueryChannels { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_channels(request), + } } fn query_channel( @@ -290,18 +372,22 @@ impl ChainHandle for BaseChainHandle { request: QueryChannelRequest, include_proof: IncludeProof, ) -> Result<(ChannelEnd, Option), Error> { - self.send(|reply_to| ChainRequest::QueryChannel { - request, - include_proof, - reply_to, - }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_channel(request, include_proof), + } } fn query_channel_client_state( &self, request: QueryChannelClientStateRequest, ) -> Result, Error> { - self.send(|reply_to| ChainRequest::QueryChannelClientState { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_channel_client_state(request), + } } fn build_header( @@ -310,12 +396,15 @@ impl ChainHandle for BaseChainHandle { target_height: Height, client_state: AnyClientState, ) -> Result<(AnyHeader, Vec), Error> { - self.send(|reply_to| ChainRequest::BuildHeader { - trusted_height, - target_height, - client_state, - reply_to, - }) + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain + .build_header(trusted_height, target_height, &client_state) // FIXME + .map(|(header, support)| { + let header = header.into(); + let support = support.into_iter().map(|h| h.into()).collect(); + (header, support) + }), + } } fn build_client_state( @@ -323,11 +412,11 @@ impl ChainHandle for BaseChainHandle { height: Height, settings: ClientSettings, ) -> Result { - self.send(|reply_to| ChainRequest::BuildClientState { - height, - settings, - reply_to, - }) + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain + .build_client_state(height, settings) + .map(|cs| cs.into()), + } } fn build_consensus_state( @@ -336,12 +425,15 @@ impl ChainHandle for BaseChainHandle { target: Height, client_state: AnyClientState, ) -> Result { - self.send(|reply_to| ChainRequest::BuildConsensusState { - trusted, - target, - client_state, - reply_to, - }) + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => { + let verified = chain.verify_header(trusted, target, &client_state)?; + + chain + .build_consensus_state(verified) // FIXME + .map(|cs| cs.into()) + } + } } fn check_misbehaviour( @@ -349,11 +441,9 @@ impl ChainHandle for BaseChainHandle { update_event: UpdateClient, client_state: AnyClientState, ) -> Result, Error> { - self.send(|reply_to| ChainRequest::BuildMisbehaviour { - client_state, - update_event, - reply_to, - }) + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.check_misbehaviour(&update_event, &client_state), // FIXME + } } fn build_connection_proofs_and_client_state( @@ -363,15 +453,14 @@ impl ChainHandle for BaseChainHandle { client_id: &ClientId, height: Height, ) -> Result<(Option, Proofs), Error> { - self.send( - |reply_to| ChainRequest::BuildConnectionProofsAndClientState { + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.build_connection_proofs_and_client_state( message_type, - connection_id: connection_id.clone(), - client_id: client_id.clone(), + connection_id, + client_id, height, - reply_to, - }, - ) + ), + } } fn build_channel_proofs( @@ -380,12 +469,9 @@ impl ChainHandle for BaseChainHandle { channel_id: &ChannelId, height: Height, ) -> Result { - self.send(|reply_to| ChainRequest::BuildChannelProofs { - port_id: port_id.clone(), - channel_id: channel_id.clone(), - height, - reply_to, - }) + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.build_channel_proofs(port_id, channel_id, height), + } } fn build_packet_proofs( @@ -396,14 +482,15 @@ impl ChainHandle for BaseChainHandle { sequence: Sequence, height: Height, ) -> Result { - self.send(|reply_to| ChainRequest::BuildPacketProofs { - packet_type, - port_id: port_id.clone(), - channel_id: channel_id.clone(), - sequence, - height, - reply_to, - }) + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.build_packet_proofs( + packet_type, + port_id.clone(), + channel_id.clone(), + sequence, + height, + ), + } } fn query_packet_commitment( @@ -411,18 +498,22 @@ impl ChainHandle for BaseChainHandle { request: QueryPacketCommitmentRequest, include_proof: IncludeProof, ) -> Result<(Vec, Option), Error> { - self.send(|reply_to| ChainRequest::QueryPacketCommitment { - request, - include_proof, - reply_to, - }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_packet_commitment(request, include_proof), + } } fn query_packet_commitments( &self, request: QueryPacketCommitmentsRequest, ) -> Result<(Vec, Height), Error> { - self.send(|reply_to| ChainRequest::QueryPacketCommitments { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_packet_commitments(request), + } } fn query_packet_receipt( @@ -430,18 +521,22 @@ impl ChainHandle for BaseChainHandle { request: QueryPacketReceiptRequest, include_proof: IncludeProof, ) -> Result<(Vec, Option), Error> { - self.send(|reply_to| ChainRequest::QueryPacketReceipt { - request, - include_proof, - reply_to, - }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_packet_receipt(request, include_proof), + } } fn query_unreceived_packets( &self, request: QueryUnreceivedPacketsRequest, ) -> Result, Error> { - self.send(|reply_to| ChainRequest::QueryUnreceivedPackets { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_unreceived_packets(request), + } } fn query_packet_acknowledgement( @@ -449,43 +544,67 @@ impl ChainHandle for BaseChainHandle { request: QueryPacketAcknowledgementRequest, include_proof: IncludeProof, ) -> Result<(Vec, Option), Error> { - self.send(|reply_to| ChainRequest::QueryPacketAcknowledgement { - request, - include_proof, - reply_to, - }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => { + chain.query_packet_acknowledgement(request, include_proof) + } + } } fn query_packet_acknowledgements( &self, request: QueryPacketAcknowledgementsRequest, ) -> Result<(Vec, Height), Error> { - self.send(|reply_to| ChainRequest::QueryPacketAcknowledgements { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_packet_acknowledgements(request), + } } fn query_unreceived_acknowledgements( &self, request: QueryUnreceivedAcksRequest, ) -> Result, Error> { - self.send(|reply_to| ChainRequest::QueryUnreceivedAcknowledgement { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_unreceived_acknowledgements(request), + } } fn query_txs(&self, request: QueryTxRequest) -> Result, Error> { - self.send(|reply_to| ChainRequest::QueryPacketEventDataFromTxs { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_txs(request), + } } fn query_packet_events( &self, request: QueryPacketEventDataRequest, ) -> Result, Error> { - self.send(|reply_to| ChainRequest::QueryPacketEventData { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_packet_events(request), + } } fn query_host_consensus_state( &self, request: QueryHostConsensusStateRequest, ) -> Result { - self.send(|reply_to| ChainRequest::QueryHostConsensusState { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => { + chain.query_host_consensus_state(request).map(Into::into) + } + } } fn maybe_register_counterparty_payee( @@ -494,25 +613,34 @@ impl ChainHandle for BaseChainHandle { port_id: PortId, counterparty_payee: Signer, ) -> Result<(), Error> { - self.send(|reply_to| ChainRequest::MaybeRegisterCounterpartyPayee { - channel_id, - port_id, - counterparty_payee, - reply_to, - }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => { + chain.maybe_register_counterparty_payee(&channel_id, &port_id, &counterparty_payee) + } + } } fn cross_chain_query( &self, request: Vec, ) -> Result, Error> { - self.send(|reply_to| ChainRequest::CrossChainQuery { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.cross_chain_query(request), + } } fn query_incentivized_packet( &self, request: QueryIncentivizedPacketRequest, ) -> Result { - self.send(|reply_to| ChainRequest::QueryIncentivizedPacket { request, reply_to }) + let _permit = self.semaphore.access(); + + match self.chain.as_ref() { + ChainImpl::CosmosSdk(chain) => chain.query_incentivized_packet(request), + } } } diff --git a/crates/relayer/src/chain/handle/cache.rs b/crates/relayer/src/chain/handle/cache.rs index d09bc6927f..39fcfa5ae2 100644 --- a/crates/relayer/src/chain/handle/cache.rs +++ b/crates/relayer/src/chain/handle/cache.rs @@ -1,6 +1,6 @@ use core::fmt::{Display, Error as FmtError, Formatter}; -use crossbeam_channel as channel; -use tracing::Span; +use std::sync::Arc; +use std::time::Duration; use ibc_proto::ibc::apps::fee::v1::QueryIncentivizedPacketRequest; use ibc_proto::ibc::apps::fee::v1::QueryIncentivizedPacketResponse; @@ -25,7 +25,7 @@ use crate::account::Balance; use crate::cache::{Cache, CacheStatus}; use crate::chain::client::ClientSettings; use crate::chain::endpoint::{ChainStatus, HealthCheck}; -use crate::chain::handle::{ChainHandle, ChainRequest, Subscription}; +use crate::chain::handle::{ChainHandle, Subscription}; use crate::chain::requests::*; use crate::chain::tracking::TrackedMsgs; use crate::client_state::{AnyClientState, IdentifiedAnyClientState}; @@ -40,6 +40,8 @@ use crate::light_client::AnyHeader; use crate::misbehaviour::MisbehaviourEvidence; use crate::telemetry; +use super::ChainImpl; + /// A chain handle with support for caching. /// To be used for the passive relaying mode (i.e., `start` CLI). #[derive(Debug, Clone)] @@ -72,8 +74,8 @@ impl Display for CachingChainHandle { } impl ChainHandle for CachingChainHandle { - fn new(chain_id: ChainId, sender: channel::Sender<(Span, ChainRequest)>) -> Self { - Self::new(Handle::new(chain_id, sender)) + fn new(chain: Arc) -> Self { + Self::new(Handle::new(chain)) } fn id(&self) -> ChainId { @@ -114,6 +116,10 @@ impl ChainHandle for CachingChainHandle { self.inner().config() } + fn max_block_time(&self) -> Duration { + self.inner().max_block_time() + } + fn get_key(&self) -> Result { self.inner().get_key() } diff --git a/crates/relayer/src/chain/handle/counting.rs b/crates/relayer/src/chain/handle/counting.rs index 66b83e5686..db2962e2cc 100644 --- a/crates/relayer/src/chain/handle/counting.rs +++ b/crates/relayer/src/chain/handle/counting.rs @@ -1,9 +1,9 @@ use core::fmt::{Display, Error as FmtError, Formatter}; use std::collections::HashMap; use std::sync::{Arc, RwLock, RwLockReadGuard}; +use std::time::Duration; -use crossbeam_channel as channel; -use tracing::{debug, Span}; +use tracing::debug; use ibc_proto::ibc::apps::fee::v1::{ QueryIncentivizedPacketRequest, QueryIncentivizedPacketResponse, @@ -28,7 +28,7 @@ use ibc_relayer_types::Height; use crate::account::Balance; use crate::chain::client::ClientSettings; use crate::chain::endpoint::{ChainStatus, HealthCheck}; -use crate::chain::handle::{ChainHandle, ChainRequest, Subscription}; +use crate::chain::handle::{ChainHandle, Subscription}; use crate::chain::requests::*; use crate::chain::tracking::TrackedMsgs; use crate::client_state::{AnyClientState, IdentifiedAnyClientState}; @@ -43,6 +43,8 @@ use crate::light_client::AnyHeader; use crate::misbehaviour::MisbehaviourEvidence; use crate::util::lock::LockExt; +use super::ChainImpl; + #[derive(Debug, Clone)] pub struct CountingChainHandle { inner: Handle, @@ -86,8 +88,8 @@ impl Display for CountingChainHandle { } impl ChainHandle for CountingChainHandle { - fn new(chain_id: ChainId, sender: channel::Sender<(Span, ChainRequest)>) -> Self { - Self::new(Handle::new(chain_id, sender)) + fn new(chain: Arc) -> Self { + Self::new(Handle::new(chain)) } fn id(&self) -> ChainId { @@ -140,6 +142,11 @@ impl ChainHandle for CountingChainHandle { self.inner().config() } + fn max_block_time(&self) -> Duration { + self.inc_metric("max_block_time"); + self.inner().max_block_time() + } + fn get_key(&self) -> Result { self.inc_metric("get_key"); self.inner().get_key() diff --git a/crates/relayer/src/channel.rs b/crates/relayer/src/channel.rs index 84bce4470e..afc6523820 100644 --- a/crates/relayer/src/channel.rs +++ b/crates/relayer/src/channel.rs @@ -477,16 +477,8 @@ impl Channel { /// [`ChainConfig.max_block_time`] for the two networks that /// this channel belongs to. fn max_block_times(&self) -> Result { - let a_block_time = self - .a_chain() - .config() - .map_err(ChannelError::relayer)? - .max_block_time; - let b_block_time = self - .b_chain() - .config() - .map_err(ChannelError::relayer)? - .max_block_time; + let a_block_time = self.a_chain().max_block_time(); + let b_block_time = self.b_chain().max_block_time(); Ok(a_block_time.max(b_block_time)) } diff --git a/crates/relayer/src/config.rs b/crates/relayer/src/config.rs index 92fe601cbf..e2179879cf 100644 --- a/crates/relayer/src/config.rs +++ b/crates/relayer/src/config.rs @@ -198,6 +198,10 @@ pub mod default { ZERO_DURATION } + pub fn max_concurrency() -> u16 { + 50 + } + pub fn auto_register_counterparty_payee() -> bool { false } @@ -575,6 +579,10 @@ pub struct ChainConfig { #[serde(default = "default::rpc_timeout", with = "humantime_serde")] pub rpc_timeout: Duration, + /// The maximum number of requests which can be issued to the chain concurrently. + #[serde(default = "default::max_concurrency")] + pub max_concurrency: u16, + /// Whether or not the full node Hermes connects to is trusted #[serde(default = "default::trusted_node")] pub trusted_node: bool, diff --git a/crates/relayer/src/connection.rs b/crates/relayer/src/connection.rs index 341049446b..b3738db022 100644 --- a/crates/relayer/src/connection.rs +++ b/crates/relayer/src/connection.rs @@ -441,16 +441,8 @@ impl Connection { /// [`ChainConfig.max_block_time`] for the two networks that /// this connection belongs to. fn max_block_times(&self) -> Result { - let a_block_time = self - .a_chain() - .config() - .map_err(ConnectionError::relayer)? - .max_block_time; - let b_block_time = self - .b_chain() - .config() - .map_err(ConnectionError::relayer)? - .max_block_time; + let a_block_time = self.a_chain().max_block_time(); + let b_block_time = self.b_chain().max_block_time(); Ok(a_block_time.max(b_block_time)) } diff --git a/crates/relayer/src/foreign_client.rs b/crates/relayer/src/foreign_client.rs index 008737e052..2948ba7d7e 100644 --- a/crates/relayer/src/foreign_client.rs +++ b/crates/relayer/src/foreign_client.rs @@ -587,6 +587,7 @@ impl ForeignClient ForeignClient { pub trait LightClient: Send + Sync { /// Fetch and verify a header, and return its minimal supporting set. fn header_and_minimal_set( - &mut self, + &self, trusted: Height, target: Height, client_state: &AnyClientState, @@ -48,7 +48,7 @@ pub trait LightClient: Send + Sync { /// Fetch a header from the chain at the given height and verify it. fn verify( - &mut self, + &self, trusted: Height, target: Height, client_state: &AnyClientState, @@ -58,14 +58,14 @@ pub trait LightClient: Send + Sync { /// Given a client update event that includes the header used in a client update, /// run the light client attack detector. fn detect_misbehaviour( - &mut self, + &self, update: &UpdateClient, client_state: &AnyClientState, now: C::Time, ) -> Result, error::Error>; /// Fetch a header from the chain at the given height, without verifying it - fn fetch(&mut self, height: Height) -> Result; + fn fetch(&self, height: Height) -> Result; } /// Decodes an encoded header into a known `Header` type, diff --git a/crates/relayer/src/light_client/tendermint.rs b/crates/relayer/src/light_client/tendermint.rs index 5e3d4c3fae..8df15694af 100644 --- a/crates/relayer/src/light_client/tendermint.rs +++ b/crates/relayer/src/light_client/tendermint.rs @@ -54,7 +54,7 @@ pub struct LightClient { impl super::LightClient for LightClient { fn header_and_minimal_set( - &mut self, + &self, trusted_height: ICSHeight, target_height: ICSHeight, client_state: &AnyClientState, @@ -80,7 +80,7 @@ impl super::LightClient for LightClient { } fn verify( - &mut self, + &self, trusted_height: ICSHeight, target_height: ICSHeight, client_state: &AnyClientState, @@ -119,7 +119,7 @@ impl super::LightClient for LightClient { Ok(Verified { target, supporting }) } - fn fetch(&mut self, height: ICSHeight) -> Result { + fn fetch(&self, height: ICSHeight) -> Result { trace!(%height, "fetching header"); self.fetch_light_block(AtHeight::At(height.into())) @@ -127,7 +127,7 @@ impl super::LightClient for LightClient { /// Perform misbehavior detection on the given client state and update client event. fn detect_misbehaviour( - &mut self, + &self, update: &UpdateClient, client_state: &AnyClientState, now: Time, @@ -341,7 +341,7 @@ impl LightClient { } fn adjust_headers( - &mut self, + &self, trusted_height: ICSHeight, target: LightBlock, supporting: Vec, diff --git a/crates/relayer/src/link/relay_path.rs b/crates/relayer/src/link/relay_path.rs index b24ccbe336..a61ae99e30 100644 --- a/crates/relayer/src/link/relay_path.rs +++ b/crates/relayer/src/link/relay_path.rs @@ -288,21 +288,11 @@ impl RelayPath { } pub(crate) fn src_max_block_time(&self) -> Result { - // TODO(hu55a1n1): Ideally, we should get the `max_expected_time_per_block` using the - // `/genesis` endpoint once it is working in tendermint-rs. - Ok(self - .src_chain() - .config() - .map_err(LinkError::relayer)? - .max_block_time) + Ok(self.src_chain().max_block_time()) } pub(crate) fn dst_max_block_time(&self) -> Result { - Ok(self - .dst_chain() - .config() - .map_err(LinkError::relayer)? - .max_block_time) + Ok(self.dst_chain().max_block_time()) } fn unordered_channel(&self) -> bool { diff --git a/crates/relayer/src/spawn.rs b/crates/relayer/src/spawn.rs index f71a65eb70..8eb2f6fbe9 100644 --- a/crates/relayer/src/spawn.rs +++ b/crates/relayer/src/spawn.rs @@ -6,8 +6,8 @@ use tokio::runtime::Runtime as TokioRuntime; use ibc_relayer_types::core::ics24_host::identifier::ChainId; use crate::{ - chain::{cosmos::CosmosSdkChain, handle::ChainHandle, runtime::ChainRuntime, ChainType}, - config::Config, + chain::{cosmos::CosmosSdkChain, endpoint::ChainEndpoint, handle::ChainHandle, ChainType}, + config::{ChainConfig, Config}, error::Error as RelayerError, }; @@ -40,6 +40,18 @@ impl SpawnErrorDetail { } } +pub enum ChainImpl { + CosmosSdk(CosmosSdkChain), +} + +impl ChainImpl { + pub fn config(&self) -> &ChainConfig { + match self { + Self::CosmosSdk(chain) => chain.config(), + } + } +} + /// Spawns a chain runtime from the configuration and given a chain identifier. /// Returns the corresponding handle if successful. pub fn spawn_chain_runtime( @@ -53,9 +65,12 @@ pub fn spawn_chain_runtime( .ok_or_else(|| SpawnError::missing_chain_config(chain_id.clone()))?; let handle = match chain_config.r#type { - ChainType::CosmosSdk => ChainRuntime::::spawn::(chain_config, rt), - } - .map_err(SpawnError::relayer)?; + ChainType::CosmosSdk => { + let chain = CosmosSdkChain::bootstrap(chain_config, rt).map_err(SpawnError::relayer)?; + let chain = ChainImpl::CosmosSdk(chain); + Handle::new(Arc::new(chain)) + } + }; Ok(handle) } diff --git a/crates/relayer/src/worker/channel.rs b/crates/relayer/src/worker/channel.rs index a6204a3df4..ea58a720f7 100644 --- a/crates/relayer/src/worker/channel.rs +++ b/crates/relayer/src/worker/channel.rs @@ -17,15 +17,7 @@ use super::WorkerCmd; fn max_block_times( chains: &ChainHandlePair, ) -> Duration { - let a_block_time = match chains.a.config() { - Err(_e) => Duration::from_millis(500), - Ok(config) => config.max_block_time, - }; - let b_block_time = match chains.b.config() { - Err(_e) => Duration::from_millis(500), - Ok(config) => config.max_block_time, - }; - a_block_time.max(b_block_time) + chains.a.max_block_time().max(chains.b.max_block_time()) } pub fn spawn_channel_worker( diff --git a/tools/test-framework/src/relayer/chain.rs b/tools/test-framework/src/relayer/chain.rs index f4913315ec..893a50468f 100644 --- a/tools/test-framework/src/relayer/chain.rs +++ b/tools/test-framework/src/relayer/chain.rs @@ -20,8 +20,10 @@ is still a [`ChainHandle`]. */ -use crossbeam_channel as channel; -use tracing::Span; +use std::sync::Arc; +use std::time::Duration; + +use ibc_relayer::spawn::ChainImpl; use ibc_proto::ibc::apps::fee::v1::{ QueryIncentivizedPacketRequest, QueryIncentivizedPacketResponse, @@ -29,7 +31,7 @@ use ibc_proto::ibc::apps::fee::v1::{ use ibc_relayer::account::Balance; use ibc_relayer::chain::client::ClientSettings; use ibc_relayer::chain::endpoint::{ChainStatus, HealthCheck}; -use ibc_relayer::chain::handle::{ChainHandle, ChainRequest, Subscription}; +use ibc_relayer::chain::handle::{ChainHandle, Subscription}; use ibc_relayer::chain::requests::*; use ibc_relayer::chain::tracking::TrackedMsgs; use ibc_relayer::client_state::{AnyClientState, IdentifiedAnyClientState}; @@ -71,8 +73,8 @@ where Tag: Send + Sync + 'static, Handle: ChainHandle, { - fn new(chain_id: ChainId, sender: channel::Sender<(Span, ChainRequest)>) -> Self { - Self::new(Handle::new(chain_id, sender)) + fn new(chain: Arc) -> Self { + Self::new(Handle::new(chain)) } fn id(&self) -> ChainId { @@ -113,6 +115,10 @@ where self.value().config() } + fn max_block_time(&self) -> Duration { + self.value().max_block_time() + } + fn get_key(&self) -> Result { self.value().get_key() } diff --git a/tools/test-framework/src/types/single/node.rs b/tools/test-framework/src/types/single/node.rs index 5aeced1f4b..17af75bf76 100644 --- a/tools/test-framework/src/types/single/node.rs +++ b/tools/test-framework/src/types/single/node.rs @@ -143,7 +143,8 @@ impl FullNode { url: WebSocketClientUrl::from_str(&self.chain_driver.websocket_address())?, batch_delay: config::default::batch_delay(), }, - rpc_timeout: config::default::rpc_timeout(), + rpc_timeout: ibc_relayer::config::default::rpc_timeout(), + max_concurrency: config::default::max_concurrency(), trusted_node: false, genesis_restart: None, account_prefix: self.chain_driver.account_prefix.clone(),