diff --git a/.gitignore b/.gitignore index d8126b9..0275d82 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ testing-framework/assets/stack/kzgrs_test_params/ # Local test artifacts (kept when NOMOS_TESTS_KEEP_LOGS=1) tests/workflows/.tmp* tests/workflows/.tmp*/ +examples/.tmp*/ diff --git a/Cargo.lock b/Cargo.lock index 930e3a2..9dac85d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,12 +77,9 @@ dependencies = [ [[package]] name = "arc-swap" -version = "1.8.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d03449bb8ca2cc2ef70869af31463d1ae5ccc8fa3e334b307203fbf815207e" -dependencies = [ - "rustversion", -] +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" [[package]] name = "archery" @@ -240,7 +237,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -266,7 +263,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -385,7 +382,7 @@ checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -444,7 +441,7 @@ dependencies = [ "nom 7.1.3", "num-traits", "rusticata-macros", - "thiserror 2.0.18", + "thiserror 2.0.17", "time", ] @@ -456,7 +453,7 @@ checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", "synstructure", ] @@ -468,7 +465,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -524,7 +521,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -546,7 +543,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -557,7 +554,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -636,7 +633,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper", "tokio", - "tower 0.5.3", + "tower 0.5.2", "tower-layer", "tower-service", "tracing", @@ -665,9 +662,9 @@ dependencies = [ [[package]] name = "az" -version = "1.3.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5eb007b7cacc6c660343e96f650fedf4b5a77512399eb952ca6642cf8d13f7" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" [[package]] name = "backoff" @@ -675,7 +672,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" dependencies = [ - "getrandom 0.2.17", + "getrandom 0.2.16", "instant", "rand 0.8.5", ] @@ -742,9 +739,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.8.3" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" +checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a" [[package]] name = "bincode" @@ -770,7 +767,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -857,9 +854,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bytemuck" @@ -900,15 +897,15 @@ checksum = "b0839c297f8783316fcca9d90344424e968395413f0662a5481f79c6648bbc14" dependencies = [ "hashbrown 0.14.5", "once_cell", - "thiserror 2.0.18", + "thiserror 2.0.17", "web-time", ] [[package]] name = "cc" -version = "1.2.53" +version = "1.2.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932" +checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" dependencies = [ "find-msvc-tools", "jobserver", @@ -945,7 +942,7 @@ checksum = "45565fc9416b9896014f5732ac776f810ee53a66730c17e4020c3ec064a8f88f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -975,16 +972,16 @@ dependencies = [ "serde_yaml", "testing-framework-config", "testing-framework-core", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tracing", ] [[package]] name = "chrono" -version = "0.4.43" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ "iana-time-zone", "num-traits", @@ -1037,9 +1034,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.54" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" dependencies = [ "clap_builder", "clap_derive", @@ -1047,9 +1044,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.54" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ "anstyle", "clap_lex", @@ -1064,14 +1061,14 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] name = "clap_lex" -version = "0.7.7" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "color-eyre" @@ -1278,7 +1275,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -1302,7 +1299,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -1313,7 +1310,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -1331,15 +1328,15 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.10.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "data-encoding-macro" -version = "0.1.19" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8142a83c17aa9461d637e649271eae18bf2edd00e91f2e105df36c3c16355bdb" +checksum = "47ce6c96ea0102f01122a185683611bd5ac8d99e62bc59dd12e6bda344ee673d" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -1347,12 +1344,12 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.17" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab67060fc6b8ef687992d439ca0fa36e7ed17e9a0b16b25b601e8757df720de" +checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" dependencies = [ "data-encoding", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -1425,7 +1422,7 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -1487,7 +1484,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -1539,9 +1536,9 @@ dependencies = [ [[package]] name = "dtoa" -version = "1.0.11" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c3cf4824e2d5f025c7b531afcb2325364084a16806f6d47fbc1f5fbd9960590" +checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" [[package]] name = "ecdsa" @@ -1592,7 +1589,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -1629,7 +1626,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -1649,7 +1646,7 @@ checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -1723,15 +1720,15 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "find-msvc-tools" -version = "0.1.8" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db" +checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" [[package]] name = "fixed" -version = "1.30.0" +version = "1.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c566da967934c6c7ee0458a9773de9b2a685bd2ce26a3b28ddfc740e640182f5" +checksum = "707070ccf8c4173548210893a0186e29c266901b71ed20cd9e2ca0193dfe95c3" dependencies = [ "az", "bytemuck", @@ -1742,9 +1739,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.8" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ "crc32fast", "miniz_oxide", @@ -1889,7 +1886,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -1899,7 +1896,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" dependencies = [ "futures-io", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pki-types", ] @@ -1963,9 +1960,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.17" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "js-sys", @@ -2069,9 +2066,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.13" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" dependencies = [ "atomic-waker", "bytes", @@ -2079,7 +2076,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.4.0", - "indexmap 2.13.0", + "indexmap 2.12.1", "slab", "tokio", "tokio-util", @@ -2191,7 +2188,7 @@ dependencies = [ "once_cell", "rand 0.9.2", "socket2 0.5.10", - "thiserror 2.0.18", + "thiserror 2.0.17", "tinyvec", "tokio", "tracing", @@ -2214,7 +2211,7 @@ dependencies = [ "rand 0.9.2", "resolv-conf", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tracing", ] @@ -2416,7 +2413,7 @@ dependencies = [ "http 1.4.0", "hyper 1.8.1", "hyper-util", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pki-types", "tokio", "tokio-rustls 0.26.4", @@ -2730,9 +2727,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", "hashbrown 0.16.1", @@ -2778,9 +2775,9 @@ checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "iri-string" -version = "0.7.10" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" dependencies = [ "memchr", "serde", @@ -2824,9 +2821,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jf-crhf" @@ -2865,9 +2862,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.85" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", @@ -3033,9 +3030,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.180" +version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] name = "libloading" @@ -3063,7 +3060,7 @@ dependencies = [ "either", "futures", "futures-timer", - "getrandom 0.2.17", + "getrandom 0.2.16", "libp2p-allow-block-list", "libp2p-autonat", "libp2p-connection-limits", @@ -3082,7 +3079,7 @@ dependencies = [ "multiaddr", "pin-project", "rw-stream-sink", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -3116,7 +3113,7 @@ dependencies = [ "quick-protobuf-codec", "rand 0.8.5", "rand_core 0.6.4", - "thiserror 2.0.18", + "thiserror 2.0.17", "tracing", "web-time", ] @@ -3134,9 +3131,9 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.43.2" +version = "0.43.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "249128cd37a2199aff30a7675dffa51caf073b51aa612d2f544b19932b9aebca" +checksum = "4d28e2d2def7c344170f5c6450c0dbe3dfef655610dbfde2f6ac28a527abbe36" dependencies = [ "either", "fnv", @@ -3151,7 +3148,7 @@ dependencies = [ "quick-protobuf", "rand 0.8.5", "rw-stream-sink", - "thiserror 2.0.18", + "thiserror 2.0.17", "tracing", "unsigned-varint 0.8.0", "web-time", @@ -3188,7 +3185,7 @@ dependencies = [ "fnv", "futures", "futures-timer", - "getrandom 0.2.17", + "getrandom 0.2.16", "hashlink", "hex_fmt", "libp2p-core", @@ -3221,7 +3218,7 @@ dependencies = [ "quick-protobuf", "quick-protobuf-codec", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.17", "tracing", ] @@ -3241,7 +3238,7 @@ dependencies = [ "rand 0.8.5", "serde", "sha2", - "thiserror 2.0.18", + "thiserror 2.0.17", "tracing", "zeroize", ] @@ -3267,7 +3264,7 @@ dependencies = [ "rand 0.8.5", "sha2", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.17", "tracing", "uint", "web-time", @@ -3325,9 +3322,9 @@ dependencies = [ "quinn", "rand 0.8.5", "ring", - "rustls 0.23.36", + "rustls 0.23.35", "socket2 0.5.10", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tracing", ] @@ -3395,7 +3392,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -3426,9 +3423,9 @@ dependencies = [ "libp2p-identity", "rcgen", "ring", - "rustls 0.23.36", - "rustls-webpki 0.103.9", - "thiserror 2.0.18", + "rustls 0.23.35", + "rustls-webpki 0.103.8", + "thiserror 2.0.17", "x509-parser", "yasna", ] @@ -3450,9 +3447,9 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.12" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ "bitflags 2.10.0", "libc", @@ -3924,7 +3921,7 @@ dependencies = [ "overwatch", "serde", "serde_with", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tokio-stream", "tracing", @@ -3951,7 +3948,7 @@ dependencies = [ "cached", "fixed", "futures", - "indexmap 2.13.0", + "indexmap 2.12.1", "libp2p", "libp2p-stream", "log", @@ -4130,7 +4127,7 @@ dependencies = [ "num-bigint", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -4167,7 +4164,7 @@ dependencies = [ "rand_core 0.6.4", "serde", "subtle", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tracing", "x25519-dalek", @@ -4181,7 +4178,7 @@ source = "git+https://github.com/logos-co/nomos-node.git?rev=97b411ed0ce269e72a6 dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -4194,7 +4191,7 @@ dependencies = [ "logos-blockchain-key-management-system-keys", "overwatch", "serde", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tracing", ] @@ -4370,7 +4367,7 @@ dependencies = [ "serde_json", "serde_with", "serde_yaml", - "thiserror 2.0.18", + "thiserror 2.0.17", "time", "tokio", "tokio-stream", @@ -4394,7 +4391,7 @@ dependencies = [ "num-traits", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -4410,7 +4407,7 @@ dependencies = [ "num-bigint", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -4436,7 +4433,7 @@ dependencies = [ "logos-blockchain-tx-service", "overwatch", "serde", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tokio-stream", "tracing", @@ -4570,7 +4567,7 @@ dependencies = [ "serde", "serde_with", "sntpc", - "thiserror 2.0.18", + "thiserror 2.0.17", "time", "tokio", "tokio-stream", @@ -4678,7 +4675,7 @@ dependencies = [ "logos-blockchain-ledger", "num-bigint", "rpds", - "thiserror 2.0.18", + "thiserror 2.0.17", "tracing", ] @@ -4727,7 +4724,7 @@ dependencies = [ "num-bigint", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -4757,13 +4754,13 @@ checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" [[package]] name = "match-lookup" -version = "0.1.2" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "757aee279b8bdbb9f9e676796fd459e4207a1f986e87886700abf589f5abf771" +checksum = "1265724d8cb29dbbc2b0f06fffb8bf1a8c0cf73a78eede9ba73a4a66c52a981e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 1.0.109", ] [[package]] @@ -4844,9 +4841,9 @@ dependencies = [ [[package]] name = "moka" -version = "0.12.12" +version = "0.12.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3dec6bd31b08944e08b58fd99373893a6c17054d6f3ea5006cc894f4f4eee2a" +checksum = "8261cd88c312e0004c1d51baad2980c66528dfdb2bee62003e643a4d8f86b077" dependencies = [ "crossbeam-channel", "crossbeam-epoch", @@ -4854,6 +4851,7 @@ dependencies = [ "equivalent", "parking_lot", "portable-atomic", + "rustc_version", "smallvec", "tagptr", "uuid", @@ -5034,17 +5032,17 @@ dependencies = [ "log", "netlink-packet-core 0.7.0", "netlink-sys", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] name = "netlink-sys" -version = "0.8.8" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd6c30ed10fa69cc491d491b85cc971f6bdeb8e7367b7cde2ee6cc878d583fae" +checksum = "16c903aa70590cb93691bf97a767c8d1d6122d2cc9070433deb3bbf36ce8bd23" dependencies = [ "bytes", - "futures-util", + "futures", "libc", "log", "tokio", @@ -5200,7 +5198,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -5265,7 +5263,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -5393,7 +5391,7 @@ dependencies = [ "async-trait", "futures", "overwatch-derive", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tokio-stream", "tokio-util", @@ -5409,7 +5407,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -5480,9 +5478,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.5" +version = "2.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9eb05c21a464ea704b53158d358a31e6425db2f63a1a7312268b05fe2b75f7" +checksum = "cbcfd20a6d4eeba40179f05735784ad32bdaef05ce8e8af05f180d45bb3e7e22" dependencies = [ "memchr", "ucd-trie", @@ -5490,9 +5488,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.8.5" +version = "2.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f9dbced329c441fa79d80472764b1a2c7e57123553b8519b36663a2fb234ed" +checksum = "51f72981ade67b1ca6adc26ec221be9f463f2b5839c7508998daa17c23d94d7f" dependencies = [ "pest", "pest_generator", @@ -5500,22 +5498,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.5" +version = "2.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bb96d5051a78f44f43c8f712d8e810adb0ebf923fc9ed2655a7f66f63ba8ee5" +checksum = "dee9efd8cdb50d719a80088b76f81aec7c41ed6d522ee750178f83883d271625" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] name = "pest_meta" -version = "2.8.5" +version = "2.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602113b5b5e8621770cfd490cfd90b9f84ab29bd2b0e49ad83eb6d186cef2365" +checksum = "bf1d70880e76bdc13ba52eafa6239ce793d85c8e43896507e43dd8984ff05b82" dependencies = [ "pest", "sha2", @@ -5576,7 +5574,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -5623,9 +5621,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.13.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] name = "potential_utf" @@ -5703,14 +5701,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] @@ -5735,7 +5733,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -5786,7 +5784,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -5848,9 +5846,9 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.36", + "rustls 0.23.35", "socket2 0.6.1", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tracing", "web-time", @@ -5868,10 +5866,10 @@ dependencies = [ "rand 0.9.2", "ring", "rustc-hash", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pki-types", "slab", - "thiserror 2.0.18", + "thiserror 2.0.17", "tinyvec", "tracing", "web-time", @@ -5893,9 +5891,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.43" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -5930,7 +5928,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.5", + "rand_core 0.9.3", ] [[package]] @@ -5950,7 +5948,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.5", + "rand_core 0.9.3", ] [[package]] @@ -5959,14 +5957,14 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.17", + "getrandom 0.2.16", ] [[package]] name = "rand_core" -version = "0.9.5" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ "getrandom 0.3.4", ] @@ -5977,7 +5975,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" dependencies = [ - "rand_core 0.9.5", + "rand_core 0.9.3", ] [[package]] @@ -6017,9 +6015,9 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ - "getrandom 0.2.17", + "getrandom 0.2.16", "libredox", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -6053,9 +6051,9 @@ checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "reqwest" -version = "0.12.28" +version = "0.12.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +checksum = "3b4c14b2d9afca6a60277086b0cc6a6ae0b568f6f7916c943a8cdc79f8be240f" dependencies = [ "base64 0.22.1", "bytes", @@ -6075,7 +6073,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pki-types", "serde", "serde_json", @@ -6085,7 +6083,7 @@ dependencies = [ "tokio-native-tls", "tokio-rustls 0.26.4", "tokio-util", - "tower 0.5.3", + "tower 0.5.2", "tower-http 0.6.8", "tower-service", "url", @@ -6120,7 +6118,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.17", + "getrandom 0.2.16", "libc", "untrusted", "windows-sys 0.52.0", @@ -6160,7 +6158,7 @@ dependencies = [ "quote", "rand 0.9.2", "syn 1.0.109", - "thiserror 2.0.18", + "thiserror 2.0.17", "tiny-keccak", "tokio", ] @@ -6188,6 +6186,7 @@ name = "runner-examples" version = "0.1.0" dependencies = [ "anyhow", + "async-trait", "testing-framework-core", "testing-framework-runner-compose", "testing-framework-runner-k8s", @@ -6200,9 +6199,9 @@ dependencies = [ [[package]] name = "rust-embed" -version = "8.11.0" +version = "8.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04113cb9355a377d83f06ef1f0a45b8ab8cd7d8b1288160717d66df5c7988d27" +checksum = "947d7f3fad52b283d261c4c99a084937e2fe492248cb9a68a8435a861b8798ca" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -6211,22 +6210,22 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "8.11.0" +version = "8.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0902e4c7c8e997159ab384e6d0fc91c221375f6894346ae107f47dd0f3ccaa" +checksum = "5fa2c8c9e8711e10f9c4fd2d64317ef13feaab820a4c51541f1a8c8e2e851ab2" dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.114", + "syn 2.0.111", "walkdir", ] [[package]] name = "rust-embed-utils" -version = "8.11.0" +version = "8.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1" +checksum = "60b161f275cb337fe0a44d924a5f4df0ed69c2c39519858f931ce61c779d3475" dependencies = [ "sha2", "walkdir", @@ -6234,9 +6233,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.27" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc-hash" @@ -6264,9 +6263,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.3" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ "bitflags 2.10.0", "errno", @@ -6289,14 +6288,14 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.36" +version = "0.23.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.9", + "rustls-webpki 0.103.8", "subtle", "zeroize", ] @@ -6324,9 +6323,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "708c0f9d5f54ba0272468c1d306a52c495b31fa155e91bc25371e6df7996908c" dependencies = [ "web-time", "zeroize", @@ -6344,9 +6343,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" dependencies = [ "ring", "rustls-pki-types", @@ -6372,9 +6371,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.22" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "same-file" @@ -6524,7 +6523,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -6539,15 +6538,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", "memchr", + "ryu", "serde", "serde_core", - "zmij", ] [[package]] @@ -6597,7 +6596,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -6606,7 +6605,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.12.1", "itoa", "ryu", "serde", @@ -6615,12 +6614,11 @@ dependencies = [ [[package]] name = "serial_test" -version = "3.3.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d0b343e184fc3b7bb44dff0705fffcf4b3756ba6aff420dddd8b24ca145e555" +checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" dependencies = [ - "futures-executor", - "futures-util", + "futures", "log", "once_cell", "parking_lot", @@ -6630,13 +6628,13 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "3.3.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f50427f258fb77356e4cd4aa0e87e2bd2c66dbcee41dc405282cae2bfc26c83" +checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -6667,11 +6665,10 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.8" +version = "1.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" dependencies = [ - "errno", "libc", ] @@ -6810,7 +6807,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -6832,9 +6829,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.114" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -6858,7 +6855,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -6917,9 +6914,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.24.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", "getrandom 0.3.4", @@ -6986,7 +6983,7 @@ dependencies = [ "rand 0.8.5", "serde", "testing-framework-env", - "thiserror 2.0.18", + "thiserror 2.0.17", "time", "tracing", ] @@ -7024,7 +7021,7 @@ dependencies = [ "tempfile", "testing-framework-config", "testing-framework-env", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tracing", ] @@ -7055,7 +7052,7 @@ dependencies = [ "testing-framework-config", "testing-framework-core", "testing-framework-env", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tracing", "url", @@ -7079,7 +7076,7 @@ dependencies = [ "testing-framework-config", "testing-framework-core", "testing-framework-env", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tracing", "url", @@ -7091,8 +7088,12 @@ name = "testing-framework-runner-local" version = "0.1.0" dependencies = [ "async-trait", + "logos-blockchain-libp2p", + "logos-blockchain-utils", + "rand 0.8.5", + "testing-framework-config", "testing-framework-core", - "thiserror 2.0.18", + "thiserror 2.0.17", "tracing", ] @@ -7108,7 +7109,7 @@ dependencies = [ "reqwest", "testing-framework-config", "testing-framework-core", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tracing", ] @@ -7124,11 +7125,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.17", ] [[package]] @@ -7139,18 +7140,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -7173,30 +7174,30 @@ dependencies = [ [[package]] name = "time" -version = "0.3.45" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", "itoa", "num-conv", "powerfmt", - "serde_core", + "serde", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.7" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" -version = "0.2.25" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ "num-conv", "time-core", @@ -7238,9 +7239,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.49.0" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ "bytes", "libc", @@ -7271,7 +7272,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -7300,15 +7301,15 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.36", + "rustls 0.23.35", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.18" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" dependencies = [ "futures-core", "pin-project-lite", @@ -7318,9 +7319,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.18" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" dependencies = [ "bytes", "futures-core", @@ -7332,20 +7333,20 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.5+spec-1.1.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.23.10+spec-1.0.0" +version = "0.23.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.12.1", "toml_datetime", "toml_parser", "winnow", @@ -7353,9 +7354,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.6+spec-1.1.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" dependencies = [ "winnow", ] @@ -7412,9 +7413,9 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", @@ -7478,7 +7479,7 @@ dependencies = [ "http-body 1.0.1", "iri-string", "pin-project-lite", - "tower 0.5.3", + "tower 0.5.2", "tower-layer", "tower-service", ] @@ -7513,9 +7514,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.44" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" dependencies = [ "log", "pin-project-lite", @@ -7530,7 +7531,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" dependencies = [ "crossbeam-channel", - "thiserror 2.0.18", + "thiserror 2.0.17", "time", "tracing-subscriber 0.3.22", ] @@ -7543,14 +7544,14 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] name = "tracing-core" -version = "0.1.36" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" dependencies = [ "once_cell", "valuable", @@ -7715,9 +7716,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicase" -version = "2.9.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" @@ -7757,15 +7758,14 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.8" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", "serde", - "serde_derive", ] [[package]] @@ -7780,7 +7780,7 @@ version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.12.1", "serde", "serde_json", "utoipa-gen", @@ -7795,7 +7795,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -7878,18 +7878,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.2+wasi-0.2.9" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.108" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if", "once_cell", @@ -7900,12 +7900,11 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.58" +version = "0.4.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" dependencies = [ "cfg-if", - "futures-util", "js-sys", "once_cell", "wasm-bindgen", @@ -7914,9 +7913,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.108" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7924,22 +7923,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.108" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.108" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] @@ -7959,9 +7958,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.85" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", @@ -7979,9 +7978,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "1.0.5" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c" +checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" dependencies = [ "rustls-pki-types", ] @@ -8077,7 +8076,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -8088,7 +8087,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -8397,9 +8396,9 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.51.0" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" @@ -8441,7 +8440,7 @@ dependencies = [ "nom 7.1.3", "oid-registry", "rusticata-macros", - "thiserror 2.0.18", + "thiserror 2.0.17", "time", ] @@ -8488,28 +8487,28 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.33" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" +checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.33" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" +checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -8529,7 +8528,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", "synstructure", ] @@ -8544,13 +8543,13 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.4.3" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -8583,7 +8582,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.111", ] [[package]] @@ -8597,13 +8596,7 @@ dependencies = [ "crossbeam-utils", "displaydoc", "flate2", - "indexmap 2.13.0", + "indexmap 2.12.1", "num_enum", "thiserror 1.0.69", ] - -[[package]] -name = "zmij" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfcd145825aace48cff44a8844de64bf75feec3080e0aa5cdbde72961ae51a65" diff --git a/examples/Cargo.toml b/examples/Cargo.toml index ba28e95..4dee650 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -20,5 +20,8 @@ tokio = { workspace = true, features = ["macros", "ne tracing = { workspace = true } tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] } +[dev-dependencies] +async-trait = { workspace = true } + [lints] workspace = true diff --git a/examples/doc-snippets/src/custom_workload_example_expectation.rs b/examples/doc-snippets/src/custom_workload_example_expectation.rs index 243027e..0278438 100644 --- a/examples/doc-snippets/src/custom_workload_example_expectation.rs +++ b/examples/doc-snippets/src/custom_workload_example_expectation.rs @@ -18,16 +18,13 @@ impl Expectation for ReachabilityExpectation { } async fn evaluate(&mut self, ctx: &RunContext) -> Result<(), DynError> { - let client = ctx - .node_clients() - .validator_clients() - .get(self.target_idx) - .ok_or_else(|| { - Box::new(std::io::Error::new( - std::io::ErrorKind::Other, - "missing target client", - )) as DynError - })?; + let validators = ctx.node_clients().validator_clients(); + let client = validators.get(self.target_idx).ok_or_else(|| { + Box::new(std::io::Error::new( + std::io::ErrorKind::Other, + "missing target client", + )) as DynError + })?; client .consensus_info() diff --git a/examples/doc-snippets/src/custom_workload_example_workload.rs b/examples/doc-snippets/src/custom_workload_example_workload.rs index cd17837..4b545a4 100644 --- a/examples/doc-snippets/src/custom_workload_example_workload.rs +++ b/examples/doc-snippets/src/custom_workload_example_workload.rs @@ -43,16 +43,13 @@ impl Workload for ReachabilityWorkload { } async fn start(&self, ctx: &RunContext) -> Result<(), DynError> { - let client = ctx - .node_clients() - .validator_clients() - .get(self.target_idx) - .ok_or_else(|| { - Box::new(std::io::Error::new( - std::io::ErrorKind::Other, - "missing target client", - )) as DynError - })?; + let validators = ctx.node_clients().validator_clients(); + let client = validators.get(self.target_idx).ok_or_else(|| { + Box::new(std::io::Error::new( + std::io::ErrorKind::Other, + "missing target client", + )) as DynError + })?; // Lightweight API call to prove reachability. client diff --git a/examples/tests/dynamic_join.rs b/examples/tests/dynamic_join.rs new file mode 100644 index 0000000..6400fee --- /dev/null +++ b/examples/tests/dynamic_join.rs @@ -0,0 +1,147 @@ +use std::time::Duration; + +use anyhow::Result; +use async_trait::async_trait; +use testing_framework_core::scenario::{ + Deployer, DynError, RunContext, ScenarioBuilder, StartNodeOptions, Workload, +}; +use testing_framework_runner_local::LocalDeployer; +use testing_framework_workflows::ScenarioBuilderExt; +use tokio::time::{sleep, timeout}; +use tracing_subscriber::fmt::try_init; + +const START_DELAY: Duration = Duration::from_secs(5); +const READY_TIMEOUT: Duration = Duration::from_secs(60); +const READY_POLL_INTERVAL: Duration = Duration::from_secs(2); + +struct JoinNodeWorkload { + name: String, +} + +impl JoinNodeWorkload { + fn new(name: impl Into) -> Self { + Self { name: name.into() } + } +} + +#[async_trait] +impl Workload for JoinNodeWorkload { + fn name(&self) -> &str { + "dynamic_join" + } + + async fn start(&self, ctx: &RunContext) -> Result<(), DynError> { + let handle = ctx + .node_control() + .ok_or_else(|| "dynamic join workload requires node control".to_owned())?; + + sleep(START_DELAY).await; + + let node = handle.start_validator(&self.name).await?; + let client = node.api; + + timeout(READY_TIMEOUT, async { + loop { + match client.consensus_info().await { + Ok(info) if info.height > 0 => break, + Ok(_) | Err(_) => sleep(READY_POLL_INTERVAL).await, + } + } + }) + .await + .map_err(|_| "dynamic join node did not become ready in time")?; + + sleep(ctx.run_duration()).await; + Ok(()) + } +} + +struct JoinNodeWithPeersWorkload { + name: String, + peers: Vec, +} + +impl JoinNodeWithPeersWorkload { + fn new(name: impl Into, peers: Vec) -> Self { + Self { + name: name.into(), + peers, + } + } +} + +#[async_trait] +impl Workload for JoinNodeWithPeersWorkload { + fn name(&self) -> &str { + "dynamic_join_with_peers" + } + + async fn start(&self, ctx: &RunContext) -> Result<(), DynError> { + let handle = ctx + .node_control() + .ok_or_else(|| "dynamic join workload requires node control".to_owned())?; + + sleep(START_DELAY).await; + + let options = StartNodeOptions { + peer_names: self.peers.clone(), + }; + let node = handle.start_validator_with(&self.name, options).await?; + let client = node.api; + + timeout(READY_TIMEOUT, async { + loop { + match client.consensus_info().await { + Ok(info) if info.height > 0 => break, + Ok(_) | Err(_) => sleep(READY_POLL_INTERVAL).await, + } + } + }) + .await + .map_err(|_| "dynamic join node did not become ready in time")?; + + sleep(ctx.run_duration()).await; + Ok(()) + } +} + +#[tokio::test] +#[ignore = "run manually with `cargo test -p runner-examples -- --ignored`"] +async fn dynamic_join_reaches_consensus_liveness() -> Result<()> { + let _ = try_init(); + + let mut scenario = + ScenarioBuilder::topology_with(|t| t.network_star().validators(2).executors(0)) + .enable_node_control() + .with_workload(JoinNodeWorkload::new("joiner")) + .expect_consensus_liveness() + .with_run_duration(Duration::from_secs(60)) + .build()?; + + let deployer = LocalDeployer::default(); + let runner = deployer.deploy(&scenario).await?; + let _handle = runner.run(&mut scenario).await?; + + Ok(()) +} + +#[tokio::test] +#[ignore = "run manually with `cargo test -p runner-examples -- --ignored`"] +async fn dynamic_join_with_peers_reaches_consensus_liveness() -> Result<()> { + let mut scenario = + ScenarioBuilder::topology_with(|t| t.network_star().validators(2).executors(0)) + .enable_node_control() + .with_workload(JoinNodeWithPeersWorkload::new( + "joiner", + vec!["validator-0".to_string()], + )) + .expect_consensus_liveness() + .with_run_duration(Duration::from_secs(60)) + .build()?; + + let deployer = LocalDeployer::default(); + let runner = deployer.deploy(&scenario).await?; + let _handle = runner.run(&mut scenario).await?; + + Ok(()) +} diff --git a/testing-framework/configs/src/topology/configs/mod.rs b/testing-framework/configs/src/topology/configs/mod.rs index a1d2d3d..b328316 100644 --- a/testing-framework/configs/src/topology/configs/mod.rs +++ b/testing-framework/configs/src/topology/configs/mod.rs @@ -5,6 +5,7 @@ pub mod bootstrap; pub mod consensus; pub mod da; pub mod network; +pub mod runtime; pub mod time; pub mod tracing; pub mod wallet; diff --git a/testing-framework/configs/src/topology/configs/network.rs b/testing-framework/configs/src/topology/configs/network.rs index 8d56a66..49387e4 100644 --- a/testing-framework/configs/src/topology/configs/network.rs +++ b/testing-framework/configs/src/topology/configs/network.rs @@ -108,6 +108,36 @@ pub fn create_network_configs( .collect()) } +pub fn build_network_config_for_node( + id: [u8; 32], + port: u16, + initial_peers: Vec, +) -> Result { + let mut node_key_bytes = id; + let node_key = ed25519::SecretKey::try_from_bytes(&mut node_key_bytes).map_err(|err| { + NetworkConfigError::NodeKeyFromBytes { + message: err.to_string(), + } + })?; + + let swarm_config = SwarmConfig { + node_key, + port, + chain_sync_config: cryptarchia_sync::Config { + peer_response_timeout: PEER_RESPONSE_TIMEOUT, + }, + nat_config: nat_settings(port)?, + ..default_swarm_config() + }; + + Ok(GeneralNetworkConfig { + backend: BackendSettings { + initial_peers, + swarm: swarm_config, + }, + }) +} + fn initial_peers_by_network_layout( swarm_configs: &[SwarmConfig], network_params: &NetworkParams, diff --git a/testing-framework/configs/src/topology/configs/runtime.rs b/testing-framework/configs/src/topology/configs/runtime.rs new file mode 100644 index 0000000..cdd1fde --- /dev/null +++ b/testing-framework/configs/src/topology/configs/runtime.rs @@ -0,0 +1,147 @@ +use std::collections::HashMap; + +use key_management_system_service::{backend::preload::PreloadKMSBackendSettings, keys::Key}; +use nomos_libp2p::Multiaddr; + +use crate::{ + node_address_from_port, + nodes::kms::key_id_for_preload_backend, + topology::configs::{ + GeneralConfig, GeneralConfigError, api, blend, bootstrap, consensus, + consensus::{ConsensusParams, GeneralConsensusConfig}, + da, + da::DaParams, + network, + network::{Libp2pNetworkLayout, NetworkParams}, + time, tracing, + wallet::WalletConfig, + }, +}; + +pub fn build_general_config_for_node( + id: [u8; 32], + network_port: u16, + initial_peers: Vec, + da_port: u16, + blend_port: u16, + consensus_params: &ConsensusParams, + da_params: &DaParams, + wallet_config: &WalletConfig, + base_consensus: &GeneralConsensusConfig, + time_config: &time::GeneralTimeConfig, +) -> Result { + let consensus_config = + build_consensus_config_for_node(id, consensus_params, wallet_config, base_consensus)?; + + let bootstrap_config = + bootstrap::create_bootstrap_configs(&[id], bootstrap::SHORT_PROLONGED_BOOTSTRAP_PERIOD) + .into_iter() + .next() + .ok_or(GeneralConfigError::EmptyParticipants)?; + + let da_config = da::try_create_da_configs(&[id], da_params, &[da_port])? + .into_iter() + .next() + .ok_or(GeneralConfigError::EmptyParticipants)?; + + let blend_config = blend::create_blend_configs(&[id], &[blend_port]) + .into_iter() + .next() + .ok_or(GeneralConfigError::EmptyParticipants)?; + + let network_config = network::build_network_config_for_node(id, network_port, initial_peers)?; + + let api_config = api::create_api_configs(&[id])? + .into_iter() + .next() + .ok_or(GeneralConfigError::EmptyParticipants)?; + + let tracing_config = tracing::create_tracing_configs(&[id]) + .into_iter() + .next() + .ok_or(GeneralConfigError::EmptyParticipants)?; + + let kms_config = build_kms_config_for_node(&blend_config, &da_config, wallet_config); + + Ok(GeneralConfig { + consensus_config, + bootstrapping_config: bootstrap_config, + da_config, + network_config, + blend_config, + api_config, + tracing_config, + time_config: time_config.clone(), + kms_config, + }) +} + +pub fn build_consensus_config_for_node( + id: [u8; 32], + consensus_params: &ConsensusParams, + wallet_config: &WalletConfig, + base: &GeneralConsensusConfig, +) -> Result { + let mut config = consensus::create_consensus_configs(&[id], consensus_params, wallet_config)? + .into_iter() + .next() + .ok_or(GeneralConfigError::EmptyParticipants)?; + + config.genesis_tx = base.genesis_tx.clone(); + config.utxos = base.utxos.clone(); + config.da_notes = base.da_notes.clone(); + config.blend_notes = base.blend_notes.clone(); + config.wallet_accounts = base.wallet_accounts.clone(); + + Ok(config) +} + +pub fn build_initial_peers(network_params: &NetworkParams, peer_ports: &[u16]) -> Vec { + match network_params.libp2p_network_layout { + Libp2pNetworkLayout::Star => peer_ports + .first() + .map(|port| vec![node_address_from_port(*port)]) + .unwrap_or_default(), + Libp2pNetworkLayout::Chain => peer_ports + .last() + .map(|port| vec![node_address_from_port(*port)]) + .unwrap_or_default(), + Libp2pNetworkLayout::Full => peer_ports + .iter() + .map(|port| node_address_from_port(*port)) + .collect(), + } +} + +fn build_kms_config_for_node( + blend_config: &blend::GeneralBlendConfig, + da_config: &da::GeneralDaConfig, + wallet_config: &WalletConfig, +) -> PreloadKMSBackendSettings { + let mut keys = HashMap::from([ + ( + key_id_for_preload_backend(&Key::Ed25519(blend_config.signer.clone())), + Key::Ed25519(blend_config.signer.clone()), + ), + ( + key_id_for_preload_backend(&Key::Zk(blend_config.secret_zk_key.clone())), + Key::Zk(blend_config.secret_zk_key.clone()), + ), + ( + key_id_for_preload_backend(&Key::Ed25519(da_config.signer.clone())), + Key::Ed25519(da_config.signer.clone()), + ), + ( + key_id_for_preload_backend(&Key::Zk(da_config.secret_zk_key.clone())), + Key::Zk(da_config.secret_zk_key.clone()), + ), + ]); + + for account in &wallet_config.accounts { + let key = Key::Zk(account.secret_key.clone()); + let key_id = key_id_for_preload_backend(&key); + keys.entry(key_id).or_insert(key); + } + + PreloadKMSBackendSettings { keys } +} diff --git a/testing-framework/core/src/nodes/executor.rs b/testing-framework/core/src/nodes/executor.rs index 39485e1..cb589ae 100644 --- a/testing-framework/core/src/nodes/executor.rs +++ b/testing-framework/core/src/nodes/executor.rs @@ -60,10 +60,11 @@ impl Drop for Executor { } impl Executor { - pub async fn spawn(config: Config) -> Result { + pub async fn spawn(config: Config, label: &str) -> Result { + let log_prefix = format!("{LOGS_PREFIX}-{label}"); let handle = spawn_node( config, - LOGS_PREFIX, + &log_prefix, "executor.yaml", binary_path(), !*IS_DEBUG_TRACING, diff --git a/testing-framework/core/src/nodes/validator.rs b/testing-framework/core/src/nodes/validator.rs index 7f972ca..c183e0b 100644 --- a/testing-framework/core/src/nodes/validator.rs +++ b/testing-framework/core/src/nodes/validator.rs @@ -72,10 +72,11 @@ impl Validator { self.handle.wait_for_exit(timeout).await } - pub async fn spawn(config: Config) -> Result { + pub async fn spawn(config: Config, label: &str) -> Result { + let log_prefix = format!("{LOGS_PREFIX}-{label}"); let handle = spawn_node( config, - LOGS_PREFIX, + &log_prefix, "validator.yaml", binary_path(), !*IS_DEBUG_TRACING, diff --git a/testing-framework/core/src/scenario/capabilities.rs b/testing-framework/core/src/scenario/capabilities.rs index 3af53e8..4f80cb7 100644 --- a/testing-framework/core/src/scenario/capabilities.rs +++ b/testing-framework/core/src/scenario/capabilities.rs @@ -2,6 +2,7 @@ use async_trait::async_trait; use reqwest::Url; use super::DynError; +use crate::{nodes::ApiClient, topology::generation::NodeRole}; /// Marker type used by scenario builders to request node control support. #[derive(Clone, Copy, Debug, Default)] @@ -21,6 +22,13 @@ pub struct ObservabilityCapability { pub grafana_url: Option, } +/// Options for dynamically starting a node. +#[derive(Clone, Debug, Default)] +pub struct StartNodeOptions { + /// Names of nodes to connect to on startup (implementation-defined). + pub peer_names: Vec, +} + /// Trait implemented by scenario capability markers to signal whether node /// control is required. pub trait RequiresNodeControl { @@ -45,4 +53,35 @@ pub trait NodeControlHandle: Send + Sync { async fn restart_validator(&self, index: usize) -> Result<(), DynError>; async fn restart_executor(&self, index: usize) -> Result<(), DynError>; + + async fn start_validator(&self, _name: &str) -> Result { + Err("start_validator not supported by this deployer".into()) + } + + async fn start_executor(&self, _name: &str) -> Result { + Err("start_executor not supported by this deployer".into()) + } + + async fn start_validator_with( + &self, + _name: &str, + _options: StartNodeOptions, + ) -> Result { + Err("start_validator_with not supported by this deployer".into()) + } + + async fn start_executor_with( + &self, + _name: &str, + _options: StartNodeOptions, + ) -> Result { + Err("start_executor_with not supported by this deployer".into()) + } +} + +#[derive(Clone)] +pub struct StartedNode { + pub name: String, + pub role: NodeRole, + pub api: ApiClient, } diff --git a/testing-framework/core/src/scenario/mod.rs b/testing-framework/core/src/scenario/mod.rs index 6cee1cc..2b79383 100644 --- a/testing-framework/core/src/scenario/mod.rs +++ b/testing-framework/core/src/scenario/mod.rs @@ -13,6 +13,7 @@ pub type DynError = Box; pub use capabilities::{ NodeControlCapability, NodeControlHandle, ObservabilityCapability, RequiresNodeControl, + StartNodeOptions, StartedNode, }; pub use definition::{ Builder, Scenario, ScenarioBuildError, ScenarioBuilder, TopologyConfigurator, diff --git a/testing-framework/core/src/scenario/runtime/context.rs b/testing-framework/core/src/scenario/runtime/context.rs index 30f2a44..5a40f39 100644 --- a/testing-framework/core/src/scenario/runtime/context.rs +++ b/testing-framework/core/src/scenario/runtime/context.rs @@ -63,7 +63,7 @@ impl RunContext { } #[must_use] - pub fn random_node_client(&self) -> Option<&ApiClient> { + pub fn random_node_client(&self) -> Option { self.node_clients.any_client() } diff --git a/testing-framework/core/src/scenario/runtime/node_clients.rs b/testing-framework/core/src/scenario/runtime/node_clients.rs index 32ed57f..657b4e0 100644 --- a/testing-framework/core/src/scenario/runtime/node_clients.rs +++ b/testing-framework/core/src/scenario/runtime/node_clients.rs @@ -1,4 +1,7 @@ -use std::pin::Pin; +use std::{ + pin::Pin, + sync::{Arc, RwLock}, +}; use rand::{Rng as _, seq::SliceRandom as _, thread_rng}; @@ -11,6 +14,11 @@ use crate::{ /// Collection of API clients for the validator and executor set. #[derive(Clone, Default)] pub struct NodeClients { + inner: Arc>, +} + +#[derive(Default)] +struct NodeClientsInner { validators: Vec, executors: Vec, } @@ -18,10 +26,12 @@ pub struct NodeClients { impl NodeClients { #[must_use] /// Build clients from preconstructed vectors. - pub const fn new(validators: Vec, executors: Vec) -> Self { + pub fn new(validators: Vec, executors: Vec) -> Self { Self { - validators, - executors, + inner: Arc::new(RwLock::new(NodeClientsInner { + validators, + executors, + })), } } @@ -43,48 +53,65 @@ impl NodeClients { #[must_use] /// Validator API clients. - pub fn validator_clients(&self) -> &[ApiClient] { - &self.validators + pub fn validator_clients(&self) -> Vec { + self.inner + .read() + .expect("node clients lock poisoned") + .validators + .clone() } #[must_use] /// Executor API clients. - pub fn executor_clients(&self) -> &[ApiClient] { - &self.executors + pub fn executor_clients(&self) -> Vec { + self.inner + .read() + .expect("node clients lock poisoned") + .executors + .clone() } #[must_use] /// Choose a random validator client if present. - pub fn random_validator(&self) -> Option<&ApiClient> { - if self.validators.is_empty() { + pub fn random_validator(&self) -> Option { + let validators = self.validator_clients(); + if validators.is_empty() { return None; } let mut rng = thread_rng(); - let idx = rng.gen_range(0..self.validators.len()); - self.validators.get(idx) + let idx = rng.gen_range(0..validators.len()); + validators.get(idx).cloned() } #[must_use] /// Choose a random executor client if present. - pub fn random_executor(&self) -> Option<&ApiClient> { - if self.executors.is_empty() { + pub fn random_executor(&self) -> Option { + let executors = self.executor_clients(); + if executors.is_empty() { return None; } let mut rng = thread_rng(); - let idx = rng.gen_range(0..self.executors.len()); - self.executors.get(idx) + let idx = rng.gen_range(0..executors.len()); + executors.get(idx).cloned() } /// Iterator over all clients. - pub fn all_clients(&self) -> impl Iterator { - self.validators.iter().chain(self.executors.iter()) + pub fn all_clients(&self) -> Vec { + let guard = self.inner.read().expect("node clients lock poisoned"); + guard + .validators + .iter() + .chain(guard.executors.iter()) + .cloned() + .collect() } #[must_use] /// Choose any random client from validators+executors. - pub fn any_client(&self) -> Option<&ApiClient> { - let validator_count = self.validators.len(); - let executor_count = self.executors.len(); + pub fn any_client(&self) -> Option { + let guard = self.inner.read().expect("node clients lock poisoned"); + let validator_count = guard.validators.len(); + let executor_count = guard.executors.len(); let total = validator_count + executor_count; if total == 0 { return None; @@ -92,9 +119,9 @@ impl NodeClients { let mut rng = thread_rng(); let choice = rng.gen_range(0..total); if choice < validator_count { - self.validators.get(choice) + guard.validators.get(choice).cloned() } else { - self.executors.get(choice - validator_count) + guard.executors.get(choice - validator_count).cloned() } } @@ -103,6 +130,16 @@ impl NodeClients { pub const fn cluster_client(&self) -> ClusterClient<'_> { ClusterClient::new(self) } + + pub fn add_validator(&self, client: ApiClient) { + let mut guard = self.inner.write().expect("node clients lock poisoned"); + guard.validators.push(client); + } + + pub fn add_executor(&self, client: ApiClient) { + let mut guard = self.inner.write().expect("node clients lock poisoned"); + guard.executors.push(client); + } } pub struct ClusterClient<'a> { @@ -127,7 +164,7 @@ impl<'a> ClusterClient<'a> { where E: Into, { - let mut clients: Vec<&ApiClient> = self.node_clients.all_clients().collect(); + let mut clients = self.node_clients.all_clients(); if clients.is_empty() { return Err("cluster client has no api clients".into()); } @@ -135,7 +172,7 @@ impl<'a> ClusterClient<'a> { clients.shuffle(&mut thread_rng()); let mut last_err = None; - for client in clients { + for client in &clients { match f(client).await { Ok(value) => return Ok(value), Err(err) => last_err = Some(err.into()), diff --git a/testing-framework/core/src/topology/deployment.rs b/testing-framework/core/src/topology/deployment.rs index 7395e26..e8126d1 100644 --- a/testing-framework/core/src/topology/deployment.rs +++ b/testing-framework/core/src/topology/deployment.rs @@ -91,13 +91,15 @@ impl Topology { let mut validators = Vec::new(); for i in 0..n_validators { let config = create_validator_config(config[i].clone()); - validators.push(Validator::spawn(config).await?); + let label = format!("validator-{i}"); + validators.push(Validator::spawn(config, &label).await?); } let mut executors = Vec::new(); for i in 0..n_executors { let config = create_executor_config(config[n_validators + i].clone()); - executors.push(Executor::spawn(config).await?); + let label = format!("executor-{i}"); + executors.push(Executor::spawn(config, &label).await?); } Ok((validators, executors)) diff --git a/testing-framework/deployers/compose/src/lifecycle/block_feed.rs b/testing-framework/deployers/compose/src/lifecycle/block_feed.rs index c86f869..8f69ab0 100644 --- a/testing-framework/deployers/compose/src/lifecycle/block_feed.rs +++ b/testing-framework/deployers/compose/src/lifecycle/block_feed.rs @@ -20,7 +20,6 @@ async fn spawn_block_feed_with( let block_source_client = node_clients .random_validator() - .cloned() .ok_or(ComposeRunnerError::BlockFeedMissing)?; spawn_block_feed(block_source_client) diff --git a/testing-framework/deployers/k8s/src/deployer/orchestrator.rs b/testing-framework/deployers/k8s/src/deployer/orchestrator.rs index cc55100..1dca17f 100644 --- a/testing-framework/deployers/k8s/src/deployer/orchestrator.rs +++ b/testing-framework/deployers/k8s/src/deployer/orchestrator.rs @@ -338,7 +338,8 @@ fn maybe_print_endpoints( .unwrap_or_else(|| "".to_string()) ); - for (idx, client) in node_clients.validator_clients().iter().enumerate() { + let validator_clients = node_clients.validator_clients(); + for (idx, client) in validator_clients.iter().enumerate() { println!( "TESTNET_PPROF validator_{}={}/debug/pprof/profile?seconds=15&format=proto", idx, @@ -346,7 +347,8 @@ fn maybe_print_endpoints( ); } - for (idx, client) in node_clients.executor_clients().iter().enumerate() { + let executor_clients = node_clients.executor_clients(); + for (idx, client) in executor_clients.iter().enumerate() { println!( "TESTNET_PPROF executor_{}={}/debug/pprof/profile?seconds=15&format=proto", idx, diff --git a/testing-framework/deployers/k8s/src/lifecycle/block_feed.rs b/testing-framework/deployers/k8s/src/lifecycle/block_feed.rs index 5380bcc..e72f9c0 100644 --- a/testing-framework/deployers/k8s/src/lifecycle/block_feed.rs +++ b/testing-framework/deployers/k8s/src/lifecycle/block_feed.rs @@ -14,9 +14,9 @@ pub async fn spawn_block_feed_with( let block_source_client = node_clients .validator_clients() - .first() + .into_iter() + .next() .or_else(|| node_clients.any_client()) - .cloned() .ok_or(K8sRunnerError::BlockFeedMissing)?; info!("starting block feed"); diff --git a/testing-framework/deployers/local/Cargo.toml b/testing-framework/deployers/local/Cargo.toml index e29a929..df0eb47 100644 --- a/testing-framework/deployers/local/Cargo.toml +++ b/testing-framework/deployers/local/Cargo.toml @@ -13,7 +13,11 @@ version = "0.1.0" workspace = true [dependencies] -async-trait = "0.1" -testing-framework-core = { path = "../../core" } -thiserror = { workspace = true } -tracing = { workspace = true } +async-trait = "0.1" +nomos-libp2p = { workspace = true } +nomos-utils = { workspace = true } +rand = { workspace = true } +testing-framework-config = { workspace = true } +testing-framework-core = { path = "../../core" } +thiserror = { workspace = true } +tracing = { workspace = true } diff --git a/testing-framework/deployers/local/src/runner.rs b/testing-framework/deployers/local/src/runner.rs index 4e08aaa..c9c7b2b 100644 --- a/testing-framework/deployers/local/src/runner.rs +++ b/testing-framework/deployers/local/src/runner.rs @@ -1,11 +1,28 @@ +use std::{ + collections::HashMap, + sync::{Arc, Mutex}, +}; + use async_trait::async_trait; +use nomos_libp2p::Multiaddr; +use nomos_utils::net::get_available_udp_port; +use rand::Rng as _; +use testing_framework_config::topology::configs::{ + consensus, + runtime::{build_general_config_for_node, build_initial_peers}, + time, +}; use testing_framework_core::{ + node_address_from_port, + nodes::{ApiClient, executor::Executor, validator::Validator}, scenario::{ - BlockFeed, BlockFeedTask, Deployer, DynError, Metrics, NodeClients, RunContext, Runner, - Scenario, ScenarioError, spawn_block_feed, + BlockFeed, BlockFeedTask, Deployer, DynError, Metrics, NodeClients, NodeControlCapability, + NodeControlHandle, RunContext, Runner, Scenario, ScenarioError, StartNodeOptions, + StartedNode, spawn_block_feed, }, topology::{ deployment::{SpawnTopologyError, Topology}, + generation::{GeneratedTopology, NodeRole}, readiness::ReadinessError, }, }; @@ -82,6 +99,43 @@ impl Deployer<()> for LocalDeployer { } } +#[async_trait] +impl Deployer for LocalDeployer { + type Error = LocalDeployerError; + + async fn deploy( + &self, + scenario: &Scenario, + ) -> Result { + info!( + validators = scenario.topology().validators().len(), + executors = scenario.topology().executors().len(), + "starting local deployment with node control" + ); + + let topology = Self::prepare_topology(scenario).await?; + let node_clients = NodeClients::from_topology(scenario.topology(), &topology); + let node_control = Arc::new(LocalNodeControl::new( + scenario.topology().clone(), + node_clients.clone(), + )); + + let (block_feed, block_feed_guard) = spawn_block_feed_with(&node_clients).await?; + + let context = RunContext::new( + scenario.topology().clone(), + Some(topology), + node_clients, + scenario.duration(), + Metrics::empty(), + block_feed, + Some(node_control), + ); + + Ok(Runner::new(context, Some(Box::new(block_feed_guard)))) + } +} + impl LocalDeployer { #[must_use] /// Construct a local deployer. @@ -89,7 +143,7 @@ impl LocalDeployer { Self::default() } - async fn prepare_topology(scenario: &Scenario<()>) -> Result { + async fn prepare_topology(scenario: &Scenario) -> Result { let descriptors = scenario.topology(); info!( validators = descriptors.validators().len(), @@ -133,7 +187,7 @@ async fn spawn_block_feed_with( "selecting validator client for local block feed" ); - let Some(block_source_client) = node_clients.random_validator().cloned() else { + let Some(block_source_client) = node_clients.random_validator() else { return Err(LocalDeployerError::WorkloadFailed { source: "block feed requires at least one validator".into(), }); @@ -151,3 +205,240 @@ fn workload_error(source: impl Into) -> LocalDeployerError { source: source.into(), } } + +struct LocalNodeControl { + descriptors: GeneratedTopology, + node_clients: NodeClients, + base_consensus: consensus::GeneralConsensusConfig, + base_time: time::GeneralTimeConfig, + state: Mutex, +} + +struct LocalNodeControlState { + validator_count: usize, + executor_count: usize, + peer_ports: Vec, + peer_ports_by_name: HashMap, + validators: Vec, + executors: Vec, +} + +#[async_trait] +impl NodeControlHandle for LocalNodeControl { + async fn restart_validator(&self, _index: usize) -> Result<(), DynError> { + Err("local deployer does not support restart_validator".into()) + } + + async fn restart_executor(&self, _index: usize) -> Result<(), DynError> { + Err("local deployer does not support restart_executor".into()) + } + + async fn start_validator(&self, name: &str) -> Result { + self.start_node(NodeRole::Validator, name, StartNodeOptions::default()) + .await + } + + async fn start_executor(&self, name: &str) -> Result { + self.start_node(NodeRole::Executor, name, StartNodeOptions::default()) + .await + } + + async fn start_validator_with( + &self, + name: &str, + options: StartNodeOptions, + ) -> Result { + self.start_node(NodeRole::Validator, name, options).await + } + + async fn start_executor_with( + &self, + name: &str, + options: StartNodeOptions, + ) -> Result { + self.start_node(NodeRole::Executor, name, options).await + } +} + +impl LocalNodeControl { + fn new(descriptors: GeneratedTopology, node_clients: NodeClients) -> Self { + let base_node = descriptors + .validators() + .first() + .or_else(|| descriptors.executors().first()) + .expect("generated topology must contain at least one node"); + + let base_consensus = base_node.general.consensus_config.clone(); + let base_time = base_node.general.time_config.clone(); + + let peer_ports = descriptors + .nodes() + .map(|node| node.network_port()) + .collect::>(); + + let peer_ports_by_name = descriptors + .validators() + .iter() + .map(|node| (format!("validator-{}", node.index()), node.network_port())) + .chain( + descriptors + .executors() + .iter() + .map(|node| (format!("executor-{}", node.index()), node.network_port())), + ) + .collect(); + + let state = LocalNodeControlState { + validator_count: descriptors.validators().len(), + executor_count: descriptors.executors().len(), + peer_ports, + peer_ports_by_name, + validators: Vec::new(), + executors: Vec::new(), + }; + + Self { + descriptors, + node_clients, + base_consensus, + base_time, + state: Mutex::new(state), + } + } + + async fn start_node( + &self, + role: NodeRole, + name: &str, + options: StartNodeOptions, + ) -> Result { + let (peer_ports, peer_ports_by_name, node_name) = { + let state = self.state.lock().expect("local node control lock poisoned"); + let index = match role { + NodeRole::Validator => state.validator_count, + NodeRole::Executor => state.executor_count, + }; + + let role_label = match role { + NodeRole::Validator => "validator", + NodeRole::Executor => "executor", + }; + + let label = if name.trim().is_empty() { + format!("{role_label}-{index}") + } else { + format!("{role_label}-{name}") + }; + + if state.peer_ports_by_name.contains_key(&label) { + return Err(format!("node name '{label}' already exists").into()); + } + + ( + state.peer_ports.clone(), + state.peer_ports_by_name.clone(), + label, + ) + }; + + let id = random_node_id(); + let network_port = allocate_udp_port("network port")?; + let da_port = allocate_udp_port("DA port")?; + let blend_port = allocate_udp_port("Blend port")?; + + let topology = self.descriptors.config(); + let initial_peers = if options.peer_names.is_empty() { + build_initial_peers(&topology.network_params, &peer_ports) + } else { + resolve_peer_names(&peer_ports_by_name, &options.peer_names)? + }; + + let general_config = build_general_config_for_node( + id, + network_port, + initial_peers, + da_port, + blend_port, + &topology.consensus_params, + &topology.da_params, + &topology.wallet_config, + &self.base_consensus, + &self.base_time, + )?; + + let api_client = match role { + NodeRole::Validator => { + let config = testing_framework_core::nodes::validator::create_validator_config( + general_config, + ); + + let node = Validator::spawn(config, &node_name).await?; + let client = ApiClient::from_urls(node.url(), node.testing_url()); + + self.node_clients.add_validator(client.clone()); + + let mut state = self.state.lock().expect("local node control lock poisoned"); + + state.peer_ports.push(network_port); + state + .peer_ports_by_name + .insert(node_name.clone(), network_port); + state.validator_count += 1; + state.validators.push(node); + + client + } + NodeRole::Executor => { + let config = + testing_framework_core::nodes::executor::create_executor_config(general_config); + + let node = Executor::spawn(config, &node_name).await?; + let client = ApiClient::from_urls(node.url(), node.testing_url()); + + self.node_clients.add_executor(client.clone()); + + let mut state = self.state.lock().expect("local node control lock poisoned"); + + state.peer_ports.push(network_port); + state + .peer_ports_by_name + .insert(node_name.clone(), network_port); + state.executor_count += 1; + state.executors.push(node); + + client + } + }; + + Ok(StartedNode { + name: node_name, + role, + api: api_client, + }) + } +} + +fn resolve_peer_names( + peer_ports_by_name: &HashMap, + peer_names: &[String], +) -> Result, DynError> { + let mut peers = Vec::with_capacity(peer_names.len()); + for name in peer_names { + let port = peer_ports_by_name + .get(name) + .ok_or_else(|| format!("unknown peer name '{name}'"))?; + peers.push(node_address_from_port(*port)); + } + Ok(peers) +} + +fn random_node_id() -> [u8; 32] { + let mut id = [0u8; 32]; + rand::thread_rng().fill(&mut id); + id +} + +fn allocate_udp_port(label: &'static str) -> Result { + get_available_udp_port() + .ok_or_else(|| format!("failed to allocate free UDP port for {label}").into()) +} diff --git a/testing-framework/workflows/src/expectations/consensus_liveness.rs b/testing-framework/workflows/src/expectations/consensus_liveness.rs index 6788635..571320e 100644 --- a/testing-framework/workflows/src/expectations/consensus_liveness.rs +++ b/testing-framework/workflows/src/expectations/consensus_liveness.rs @@ -90,7 +90,7 @@ impl ConsensusLiveness { } fn ensure_participants(ctx: &RunContext) -> Result<(), DynError> { - if ctx.node_clients().all_clients().count() == 0 { + if ctx.node_clients().all_clients().is_empty() { Err(Box::new(ConsensusLivenessError::MissingParticipants)) } else { Ok(()) @@ -98,7 +98,7 @@ impl ConsensusLiveness { } async fn collect_results(ctx: &RunContext) -> LivenessCheck { - let clients: Vec<_> = ctx.node_clients().all_clients().collect(); + let clients = ctx.node_clients().all_clients(); let mut samples = Vec::with_capacity(clients.len()); let mut issues = Vec::new(); diff --git a/testing-framework/workflows/src/workloads/util.rs b/testing-framework/workflows/src/workloads/util.rs index 2e9f9a5..0a48d4e 100644 --- a/testing-framework/workflows/src/workloads/util.rs +++ b/testing-framework/workflows/src/workloads/util.rs @@ -48,8 +48,8 @@ pub async fn submit_transaction_via_cluster( ); let node_clients = ctx.node_clients(); - let mut validator_clients: Vec<_> = node_clients.validator_clients().iter().collect(); - let mut executor_clients: Vec<_> = node_clients.executor_clients().iter().collect(); + let mut validator_clients = node_clients.validator_clients(); + let mut executor_clients = node_clients.executor_clients(); validator_clients.shuffle(&mut thread_rng()); executor_clients.shuffle(&mut thread_rng());