diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a6cef5f..5566edb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,7 +43,7 @@ jobs: - uses: actions/checkout@v4 with: persist-credentials: false - - uses: dtolnay/rust-toolchain@1.91 + - uses: dtolnay/rust-toolchain@1.93 with: components: clippy - uses: Swatinem/rust-cache@v2 @@ -74,6 +74,6 @@ jobs: - uses: actions/checkout@v4 with: persist-credentials: false - - uses: dtolnay/rust-toolchain@1.91 + - uses: dtolnay/rust-toolchain@1.93 - uses: Swatinem/rust-cache@v2 - run: cargo test --workspace --all-features diff --git a/Cargo.lock b/Cargo.lock index 8820234..3734e09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + [[package]] name = "aho-corasick" version = "1.1.5" @@ -11,6 +26,36 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "amaru-uplc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b565727e99c072b9d29f7ddf9eafffd51ec69a653dad6589c36d4d1ca053603c" +dependencies = [ + "append-only-vec", + "blst", + "bumpalo", + "chumsky", + "cryptoxide", + "divan", + "hamming", + "hex", + "minicbor 0.25.1", + "num", + "num-bigint", + "num-integer", + "once_cell", + "secp256k1", + "thiserror 1.0.69", + "walkdir", +] + [[package]] name = "android_system_properties" version = "0.1.6" @@ -21,1003 +66,3813 @@ dependencies = [ ] [[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "autocfg" -version = "1.5.1" +name = "anstream" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] [[package]] -name = "base64" -version = "0.22.1" +name = "anstyle" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] -name = "bitflags" -version = "2.13.1" +name = "anstyle-parse" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] [[package]] -name = "block-buffer" -version = "0.10.4" +name = "anstyle-query" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "generic-array", + "windows-sys 0.61.2", ] [[package]] -name = "block-buffer" -version = "0.12.1" +name = "anstyle-wincon" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ - "hybrid-array", + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", ] [[package]] -name = "bumpalo" -version = "3.20.3" +name = "anyhow" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] -name = "bytes" -version = "1.12.1" +name = "append-only-vec" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" +checksum = "2114736faba96bcd79595c700d03183f61357b9fbce14852515e59f3bee4ed4a" [[package]] -name = "cc" -version = "1.4.4" +name = "ar_archive_writer" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" +checksum = "73cd58deff2140a0a8eae87e417bd01db68a33e148aa93d1e8cd837e55e312b6" dependencies = [ - "find-msvc-tools", - "jobserver", - "libc", - "shlex", + "object 0.39.1", ] [[package]] -name = "cfg-if" -version = "1.0.4" +name = "arraydeque" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" [[package]] -name = "chrono" -version = "0.4.45" +name = "arrayvec" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" -dependencies = [ - "iana-time-zone", - "js-sys", - "num-traits", - "serde", - "wasm-bindgen", - "windows-link", -] +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] -name = "combine" -version = "4.6.8" +name = "async-stream" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" dependencies = [ - "bytes", - "memchr", + "async-stream-impl", + "futures-core", + "pin-project-lite", ] [[package]] -name = "const-oid" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" - -[[package]] -name = "const_format" -version = "0.2.36" +name = "async-stream-impl" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ - "const_format_proc_macros", - "konst", + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] -name = "const_format_proc_macros" -version = "0.2.34" +name = "async-trait" +version = "0.1.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "syn 3.0.4", ] [[package]] -name = "core-foundation" -version = "0.10.1" +name = "atomic-waker" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] -name = "core-foundation-sys" -version = "0.8.7" +name = "autocfg" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] -name = "cpufeatures" -version = "0.2.17" +name = "az" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] +checksum = "be5eb007b7cacc6c660343e96f650fedf4b5a77512399eb952ca6642cf8d13f7" [[package]] -name = "cpufeatures" -version = "0.3.1" +name = "backtrace" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ + "addr2line", + "cfg-if", "libc", + "miniz_oxide 0.8.9", + "object 0.37.3", + "rustc-demangle", + "windows-link", ] [[package]] -name = "crypto-common" -version = "0.1.7" +name = "backtrace-ext" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50" dependencies = [ - "generic-array", - "typenum", + "backtrace", ] [[package]] -name = "crypto-common" -version = "0.2.2" +name = "base58" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" -dependencies = [ - "hybrid-array", -] +checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" [[package]] -name = "darling" -version = "0.20.11" +name = "base64" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" -dependencies = [ - "darling_core", - "darling_macro", -] +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] -name = "darling_core" -version = "0.20.11" +name = "base64" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.119", -] +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] -name = "darling_macro" -version = "0.20.11" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.119", -] +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] -name = "derive_builder" -version = "0.20.2" +name = "base64" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" -dependencies = [ - "derive_builder_macro", -] +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" [[package]] -name = "derive_builder_core" -version = "0.20.2" +name = "base64ct" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.119", -] +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] -name = "derive_builder_macro" -version = "0.20.2" +name = "bech32" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" -dependencies = [ - "derive_builder_core", - "syn 2.0.119", -] +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" [[package]] -name = "digest" -version = "0.10.7" +name = "bech32" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "crypto-common 0.1.7", -] +checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" [[package]] -name = "digest" -version = "0.11.3" +name = "bech32" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +checksum = "efbd3e1070bbdf4cd88a75264e18e8a26f7cb5c6949eadf0ceb85fb159cf08f8" + +[[package]] +name = "binary-layout" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66c7e8da2156abef3421f6226ef339ade8c0d157ec50932d5e624f1c6a5127b4" dependencies = [ - "block-buffer 0.12.1", - "const-oid", - "crypto-common 0.2.2", + "doc-comment", + "paste", + "thiserror 1.0.69", ] [[package]] -name = "displaydoc" -version = "0.2.7" +name = "bincode" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ - "proc-macro2", - "quote", - "syn 3.0.4", + "serde", ] [[package]] -name = "errno" -version = "0.3.14" +name = "bincode" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" dependencies = [ - "libc", - "windows-sys 0.61.2", + "bincode_derive", + "serde", + "unty", ] [[package]] -name = "fastrand" -version = "2.5.0" +name = "bincode_derive" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" +checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09" +dependencies = [ + "virtue", +] [[package]] -name = "find-msvc-tools" -version = "0.1.11" +name = "bitcoin-consensus-encoding" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" +checksum = "6712f9c6fd6785b3b270884e57c441c403dc5d7e19ca45368c97c7a1de3000ec" +dependencies = [ + "bitcoin-internals", + "hex-conservative 1.3.0", + "serde", +] [[package]] -name = "fnv" -version = "1.0.7" +name = "bitcoin-internals" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +checksum = "d573f4cf32996a8dce612e4348cece65a241f1882ed594047c9ba348e8869fa5" [[package]] -name = "form_urlencoded" -version = "1.2.2" +name = "bitcoin-io" +version = "0.1.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +checksum = "bb5de036369d1ac59d3c1819ebc4d850f89466f5401c571a285b6ed564a4cb78" dependencies = [ - "percent-encoding", + "bitcoin-consensus-encoding", ] [[package]] -name = "fs4" -version = "1.1.0" +name = "bitcoin_hashes" +version = "0.14.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e72ed92b67c146290f88e9c89d60ca163ea417a446f61ffd7b72df3e7f1dfd5" +checksum = "bca4c7abb40c8817d77403c880988cfd484f23ab2365726afb2f798363e2c4a2" dependencies = [ - "rustix", - "windows-sys 0.61.2", + "bitcoin-io", + "hex-conservative 0.2.3", ] [[package]] -name = "futures-channel" -version = "0.3.34" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" + +[[package]] +name = "blake2" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4e37d16930f5459780f5621038b6382b9bb37c19016f39fb6b5808d831f174" +dependencies = [ + "crypto-mac", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "blst" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20659f9bbee16cbbd2f7393e40ab6309f5a98f76a2eb57a995ec508b72387fe" +dependencies = [ + "cc", + "glob", + "threadpool", + "zeroize", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytemuck" +version = "1.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" + +[[package]] +name = "byteview" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d74937895e761d5984206f82ca8ff7725d0fd8021921011921894b41ab1b9f7" + +[[package]] +name = "cc" +version = "1.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" + +[[package]] +name = "chacha20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.1", + "rand_core 0.10.1", +] + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "chumsky" +version = "1.0.0-alpha.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e82d74e6c83060ec269fe9e0d408d6de4a1645d525f9a0bbbb841ba4efd91ac" +dependencies = [ + "hashbrown 0.15.5", + "regex-automata 0.3.9", + "serde", + "stacker", + "unicode-ident", + "unicode-segmentation", +] + +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "ckb-merkle-mountain-range" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327c468ff2702c0a2b7ad26728a180611da22244882959b8b2e85c79bf56bcea" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "clap" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", + "terminal_size", +] + +[[package]] +name = "clap_derive" +version = "4.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 3.0.4", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + +[[package]] +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + +[[package]] +name = "combine" +version = "4.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "compare" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea0095f6103c2a8b44acd6fd15960c801dafebf02e21940360833e0673f48ba7" + +[[package]] +name = "condtype" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf0a07a401f374238ab8e2f11a104d2851bf9ce711ec69804834de8af45c7af" + +[[package]] +name = "config" +version = "0.15.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b85f248a4de22d204ceabc6299d89d2c70fbd7f09fea53c06c852369652d8139" +dependencies = [ + "pathdiff", + "serde_core", + "serde_json", + "toml 1.1.6+spec-1.1.0", + "winnow 1.0.4", +] + +[[package]] +name = "console" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "unicode-width 0.2.2", + "windows-sys 0.59.0", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + +[[package]] +name = "const_format" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" +dependencies = [ + "const_format_proc_macros", + "konst", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core_detect" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f8f80099a98041a3d1622845c271458a2d73e688351bf3cb999266764b81d48" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" + +[[package]] +name = "crc32fast" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a7799fd6b852db0e61728dde9a204c423b44d689dbd432522543614b490e78" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e71406cd8807725f7ac2f999a4cdd32e98f829fdf65f528343cebf945e41df1e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98b0cc327b5bc766e7fda9c9260cc0fa81b43a8e240440422dff70788e3f9ef1" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03e8bd762f7479489c70ed6c768ddca99d7296857de437a68dcb2a94365b3fae" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-skiplist" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df29de440c58ca2cc6e587ec3d22347551a32435fbde9d2bff64e78a9ffa151b" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "cryptoxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382ce8820a5bb815055d3553a610e8cb542b2d767bbacea99038afda96cd760d" + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core 0.20.11", + "darling_macro 0.20.11", +] + +[[package]] +name = "darling" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed17f5901b6630b993ca003def43f2f8ef4014fc13b047b57aad617ff32bc2ec" +dependencies = [ + "darling_core 0.24.1", + "darling_macro 0.24.1", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.119", +] + +[[package]] +name = "darling_core" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6837e2cf7485aaae18f86181d2f0e9a7ed297a025e220aeabf63fdebd3a2ddff" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 3.0.4", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core 0.20.11", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "darling_macro" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ac7135c3ef02b2f7833bbeb1be5ba7f966dcde8a87c6b87f65a778d71a02785" +dependencies = [ + "darling_core 0.24.1", + "quote", + "syn 3.0.4", +] + +[[package]] +name = "dashmap" +version = "6.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "defmt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror 2.0.20", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid 0.9.6", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "derive_builder" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +dependencies = [ + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +dependencies = [ + "derive_builder_core", + "syn 2.0.119", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common 0.1.7", + "subtle", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", + "const-oid 0.10.2", + "crypto-common 0.2.2", +] + +[[package]] +name = "displaydoc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.4", +] + +[[package]] +name = "divan" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a405457ec78b8fe08b0e32b4a3570ab5dff6dd16eb9e76a5ee0a9d9cbd898933" +dependencies = [ + "cfg-if", + "clap", + "condtype", + "divan-macros", + "libc", + "regex-lite", +] + +[[package]] +name = "divan-macros" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9556bc800956545d6420a640173e5ba7dfa82f38d3ea5a167eb555bc69ac3323" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "doc-comment" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "780955b8b195a21ab8e4ac6b60dd1dbdcec1dc6c51c0617964b08c81785e12c9" + +[[package]] +name = "dolos" +version = "2.0.0-alpha.0" +source = "git+https://github.com/txpipe/dolos?rev=1ae4e91c18a9e1456a3612af402d7b9b97546d30#1ae4e91c18a9e1456a3612af402d7b9b97546d30" +dependencies = [ + "async-stream", + "async-trait", + "base64 0.22.1", + "bech32 0.11.1", + "bincode 1.3.3", + "bytes", + "chrono", + "clap", + "config", + "dolos-cardano", + "dolos-core", + "dolos-fjall", + "dolos-redb3", + "dolos-snapshot", + "flate2", + "futures-core", + "futures-util", + "gasket", + "hex", + "http", + "hyper", + "indicatif", + "itertools 0.14.0", + "lazy_static", + "log", + "miette", + "opentelemetry", + "opentelemetry-otlp", + "opentelemetry_sdk", + "pallas", + "paste", + "protoc-wkt", + "rayon", + "redb-extras", + "reqwest 0.12.28", + "rustls", + "serde", + "serde_json", + "tar", + "thiserror 2.0.20", + "tokio", + "tokio-stream", + "tokio-util", + "tower 0.4.13", + "tower-http", + "tracing", + "tracing-log", + "tracing-opentelemetry", + "tracing-subscriber", + "trait-variant", + "vergen-gitcl", + "xxhash-rust", + "zstd", +] + +[[package]] +name = "dolos-cardano" +version = "2.0.0-alpha.0" +source = "git+https://github.com/txpipe/dolos?rev=1ae4e91c18a9e1456a3612af402d7b9b97546d30#1ae4e91c18a9e1456a3612af402d7b9b97546d30" +dependencies = [ + "async-stream", + "async-trait", + "chrono", + "crc", + "dolos-core", + "futures-core", + "hex", + "itertools 0.14.0", + "num-bigint", + "num-rational", + "pallas", + "paste", + "rayon", + "self_cell", + "serde", + "serde_json", + "thiserror 2.0.20", + "tracing", +] + +[[package]] +name = "dolos-core" +version = "2.0.0-alpha.0" +source = "git+https://github.com/txpipe/dolos?rev=1ae4e91c18a9e1456a3612af402d7b9b97546d30#1ae4e91c18a9e1456a3612af402d7b9b97546d30" +dependencies = [ + "futures-core", + "futures-util", + "hex", + "itertools 0.14.0", + "opentelemetry", + "pallas", + "rayon", + "regex", + "serde", + "serde_with 3.23.0", + "thiserror 2.0.20", + "tokio", + "tokio-stream", + "tracing", + "tracing-opentelemetry", + "trait-variant", + "xxhash-rust", +] + +[[package]] +name = "dolos-fjall" +version = "2.0.0-alpha.0" +source = "git+https://github.com/txpipe/dolos?rev=1ae4e91c18a9e1456a3612af402d7b9b97546d30#1ae4e91c18a9e1456a3612af402d7b9b97546d30" +dependencies = [ + "bincode 1.3.3", + "dolos-core", + "dolos-flatfiles", + "fjall", + "pallas", + "tempfile", + "thiserror 2.0.20", + "tracing", + "xxhash-rust", +] + +[[package]] +name = "dolos-flatfiles" +version = "2.0.0-alpha.0" +source = "git+https://github.com/txpipe/dolos?rev=1ae4e91c18a9e1456a3612af402d7b9b97546d30#1ae4e91c18a9e1456a3612af402d7b9b97546d30" +dependencies = [ + "rayon", + "tempfile", + "zstd", +] + +[[package]] +name = "dolos-mithril" +version = "2.0.0-alpha.0" +source = "git+https://github.com/txpipe/dolos?rev=1ae4e91c18a9e1456a3612af402d7b9b97546d30#1ae4e91c18a9e1456a3612af402d7b9b97546d30" +dependencies = [ + "dolos-core", + "mithril-client", + "tracing", +] + +[[package]] +name = "dolos-redb3" +version = "2.0.0-alpha.0" +source = "git+https://github.com/txpipe/dolos?rev=1ae4e91c18a9e1456a3612af402d7b9b97546d30#1ae4e91c18a9e1456a3612af402d7b9b97546d30" +dependencies = [ + "bincode 1.3.3", + "dolos-core", + "futures-core", + "futures-util", + "hex", + "itertools 0.14.0", + "pallas", + "redb", + "serde", + "tempfile", + "thiserror 2.0.20", + "tokio", + "tokio-stream", + "tokio-util", + "tower-http", + "tracing", +] + +[[package]] +name = "dolos-snapshot" +version = "2.0.0-alpha.0" +source = "git+https://github.com/txpipe/dolos?rev=1ae4e91c18a9e1456a3612af402d7b9b97546d30#1ae4e91c18a9e1456a3612af402d7b9b97546d30" +dependencies = [ + "dolos-cardano", + "dolos-core", + "hex", + "minicbor 0.26.5", + "serde", + "serde_json", + "stelae", + "stelae-driver", + "thiserror 2.0.20", + "tracing", +] + +[[package]] +name = "dolos-testing" +version = "2.0.0-alpha.0" +source = "git+https://github.com/txpipe/dolos?rev=1ae4e91c18a9e1456a3612af402d7b9b97546d30#1ae4e91c18a9e1456a3612af402d7b9b97546d30" +dependencies = [ + "bech32 0.9.1", + "dolos-cardano", + "dolos-core", + "dolos-fjall", + "dolos-redb3", + "futures-core", + "futures-util", + "hex", + "itertools 0.14.0", + "pallas", + "rand 0.9.5", + "serde", + "tempfile", + "tokio", + "tokio-stream", +] + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "serde", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand_core 0.6.4", + "serde", + "sha2 0.10.9", + "subtle", + "zeroize", +] + +[[package]] +name = "either" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + +[[package]] +name = "encoding_rs" +version = "0.8.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5ef0006ac9ab233c38522f5ae99cae3625151de8f706cacee1cba4b8e2832a" +dependencies = [ + "cfg-if", + "core_detect", + "multiversion", + "multiversion_no_op", + "rustversion", + "scopeguard", + "simdutf8", +] + +[[package]] +name = "enum_dispatch" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" +dependencies = [ + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "erased-serde" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "fastrand" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" +dependencies = [ + "getrandom 0.4.3", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "filetime" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" +dependencies = [ + "cfg-if", + "libc", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" + +[[package]] +name = "fixed" +version = "1.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9af2cbf772fa6d1c11358f92ef554cb6b386201210bcf0e91fb7fba8a907fb40" +dependencies = [ + "az", + "bytemuck", + "half", + "typenum", +] + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + +[[package]] +name = "fjall" +version = "3.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd201c93927cdf4712e8f7d4c9c8d34d68c7534380c05d4a58864a309f91c33f" +dependencies = [ + "byteorder-lite", + "byteview", + "dashmap", + "flume", + "log", + "lsm-tree", + "lz4_flex", + "tempfile", + "xxhash-rust", +] + +[[package]] +name = "flate2" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" +dependencies = [ + "crc32fast", + "miniz_oxide 0.9.1", + "zlib-rs", +] + +[[package]] +name = "flume" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" +dependencies = [ + "fastrand", + "futures-core", + "futures-sink", + "spin", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs4" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e72ed92b67c146290f88e9c89d60ca163ea417a446f61ffd7b72df3e7f1dfd5" +dependencies = [ + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "futures" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-executor" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + +[[package]] +name = "futures-macro" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.4", +] + +[[package]] +name = "futures-sink" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gasket" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37057b6b0b48bb9bdcd4c2bc8ec51090a6cd754744caf28d44b813584473be3a" +dependencies = [ + "async-trait", + "crossbeam", + "gasket-derive", + "serde", + "signal-hook", + "thiserror 1.0.69", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "gasket-derive" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00c4883f898206041f02b010ab10400715e89e7845c63410f6bad162a3841174" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi 5.3.0", + "wasip2", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi 6.0.0", + "rand_core 0.10.1", + "wasm-bindgen", +] + +[[package]] +name = "getset" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cf442baaabe4213ce7d1239afc26c039180b6456da2cededa316ae2c8a77a77" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + +[[package]] +name = "glob" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" + +[[package]] +name = "h2" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8e5e5a340588f4452631496976cf8636d4a7ecf600239fdc27615d2530bc16" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.14.2", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "hamming" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1" + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.1.5", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "foldhash 0.2.0", +] + +[[package]] +name = "hashlink" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a596f1b20ed2cc5ecac41a164aaebc7258057060f06c0cf7a2ba3991ee7990fb" +dependencies = [ + "hashbrown 0.17.1", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17592d60ebacc7d5e169f4663c5f84f9161cc90328abcfe8456f41e4dfcb284" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-conservative" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3fef046dca3ca91ee1408a8c1b80ab777e80a4d308d1bf4e7adb3fcb047e08" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "hex-conservative" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271e0d19bcb473b6675739a2b536076b24a082316cb5199ad918edce10c599e8" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "http" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-auth" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "150fa4a9462ef926824cf4519c84ed652ca8f4fbae34cb8af045b5cbcaf98822" +dependencies = [ + "memchr", +] + +[[package]] +name = "http-body" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hybrid-array" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" +dependencies = [ + "typenum", +] + +[[package]] +name = "hyper" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b501faa50e7a26c3d3560ca625132f4078a17771f4810baf70475ae48cbe43" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" +dependencies = [ + "displaydoc", + "litemap", + "serde", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locale_fallback" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "251af8e57c9400e3eb58242fe5b8b1152b2a64fdf4cf632f923c38ccee6f2fa9" +dependencies = [ + "icu_locale_core", + "icu_locale_fallback_data", + "icu_provider", + "potential_utf", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locale_fallback_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "decf2a22ec8fa68f1a0c1129a3f8583f8f8bc24e8b9ccbe98ead99f62a4dc3a8" + +[[package]] +name = "icu_normalizer" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" + +[[package]] +name = "icu_properties" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" + +[[package]] +name = "icu_provider" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" +dependencies = [ + "displaydoc", + "icu_locale_core", + "serde", + "stable_deref_trait", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_segmenter" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d07aafccd67af15d02512a6adf5896fbc5ed00f2e99b471d2efa14016db3db" +dependencies = [ + "icu_collections", + "icu_locale_fallback", + "icu_provider", + "icu_segmenter_data", + "potential_utf", + "smallvec", + "utf8_iter", + "zerovec", +] + +[[package]] +name = "icu_segmenter_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae293c039020f9ec10710af98d29ce6aa2051486638b49c9a6409f3b4a9e98ad" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", + "serde", + "serde_core", +] + +[[package]] +name = "indicatif" +version = "0.17.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" +dependencies = [ + "console", + "number_prefix", + "portable-atomic", + "unicode-width 0.2.2", + "web-time", +] + +[[package]] +name = "interval-heap" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11274e5e8e89b8607cfedc2910b6626e998779b48a019151c7604d0adcb86ac6" +dependencies = [ + "compare", +] + +[[package]] +name = "inventory" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4f0c30c76f2f4ccee3fe55a2435f691ca00c0e4bd87abe4f4a851b1d4dac39b" +dependencies = [ + "rustversion", +] + +[[package]] +name = "ipnet" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a756c3fac73139e83f14c2d742155dd2b78d3ee56597b419a0579b7bdd6dd78" + +[[package]] +name = "is_ci" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jiff" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1baf72f08796de0260609515130699b890ac25f30e610ad894bc5856cafdb" +dependencies = [ + "defmt", + "jiff-core", + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", + "windows-link", +] + +[[package]] +name = "jiff-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e52fe76043ccecc9005d2305ebaadf7d7fc0cc89ca6baa10a94d6bc68c7128c" +dependencies = [ + "defmt", + "log", +] + +[[package]] +name = "jiff-static" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "378268a1116ad67ae6228701118ac9f491d78fda38a40a1f1a9e1348de6f7212" +dependencies = [ + "jiff-core", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys", + "log", + "simd_cesu8", + "thiserror 2.0.20", + "walkdir", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.119", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "jsonwebtoken" +version = "10.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eba32bfb4ffdeaca3e34431072faf01745c9b26d25504aa7a6cf5684334fc4fc" +dependencies = [ + "base64 0.22.1", + "getrandom 0.2.17", + "js-sys", + "serde", + "serde_json", + "signature", + "zeroize", +] + +[[package]] +name = "kes-summed-ed25519" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb27d940b150ff718b407f94ff443915c4bbf938cc813b0164c827b170738fc" +dependencies = [ + "blake2 0.9.2", + "ed25519-dalek", + "rand_core 0.5.1", + "serde", + "serde_with 2.3.3", + "zeroize", +] + +[[package]] +name = "konst" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" +dependencies = [ + "konst_macro_rules", +] + +[[package]] +name = "konst_macro_rules" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "litemap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "lsm-tree" +version = "3.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5498808f4d41cf785079d3ef3f28716f1b4364af1b512f3097bfb651bded1b3e" +dependencies = [ + "byteorder-lite", + "byteview", + "crossbeam-skiplist", + "enum_dispatch", + "interval-heap", + "log", + "lz4_flex", + "quick_cache", + "rustc-hash", + "self_cell", + "sfa", + "tempfile", + "varint-rs", + "xxhash-rust", +] + +[[package]] +name = "lz4_flex" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef0d4ed8669f8f8826eb00dc878084aa8f253506c4fd5e8f58f5bce72ddb97e" +dependencies = [ + "twox-hash", +] + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "miette" +version = "7.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f98efec8807c63c752b5bd61f862c165c115b0a35685bdcfd9238c7aeb592b7" +dependencies = [ + "backtrace", + "backtrace-ext", + "cfg-if", + "miette-derive", + "owo-colors", + "supports-color", + "supports-hyperlinks", + "supports-unicode", + "terminal_size", + "textwrap", + "unicode-width 0.1.14", +] + +[[package]] +name = "miette-derive" +version = "7.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minicbor" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0452a60c1863c1f50b5f77cd295e8d2786849f35883f0b9e18e7e6e1b5691b0" +dependencies = [ + "minicbor-derive 0.15.3", +] + +[[package]] +name = "minicbor" +version = "0.26.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a309f581ade7597820083bc275075c4c6986e57e53f8d26f88507cfefc8c987" +dependencies = [ + "half", + "minicbor-derive 0.16.2", +] + +[[package]] +name = "minicbor-derive" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd2209fff77f705b00c737016a48e73733d7fbccb8b007194db148f03561fb70" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "minicbor-derive" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9882ef5c56df184b8ffc107fc6c61e33ee3a654b021961d790a78571bb9d67a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "miniz_oxide" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "mithril-aggregator-client" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed657d741f52390186f4f7dd4e73ffc43dc7993e629b5a3012ac678423cd58f1" +dependencies = [ + "anyhow", + "async-trait", + "mithril-common", + "reqwest 0.13.4", + "semver", + "serde", + "serde_json", + "slog", + "thiserror 2.0.20", + "tokio", +] + +[[package]] +name = "mithril-aggregator-discovery" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b6da30638ea966d7882c77b27b8a515f7f0af0f76db31594b637fd7c5735fc" +dependencies = [ + "anyhow", + "async-trait", + "mithril-aggregator-client", + "mithril-common", + "rand 0.10.2", + "reqwest 0.13.4", + "serde", + "serde_json", + "tokio", +] + +[[package]] +name = "mithril-build-script" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d70cffcca16139df8da60fc8227e1cf39a660446b9d6b4ba56970dfd42bbf70" +dependencies = [ + "saphyr", + "semver", + "serde_json", +] + +[[package]] +name = "mithril-cardano-node-internal-database" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe58aab87ee786b438c0878e2c9ff406ae390fa2db701ed99358fc62d788e3ee" +dependencies = [ + "anyhow", + "async-trait", + "digest 0.10.7", + "hex", + "mithril-common", + "serde", + "serde_json", + "sha2 0.10.9", + "slog", + "thiserror 2.0.20", + "tokio", + "walkdir", +] + +[[package]] +name = "mithril-client" +version = "0.14.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d16a7c5a55f0d0c3677b30972be455d7e9e7285f1b123b988d1f29a53cc2a3c" +dependencies = [ + "anyhow", + "async-trait", + "chrono", + "flate2", + "flume", + "futures", + "getrandom 0.4.3", + "mithril-aggregator-client", + "mithril-aggregator-discovery", + "mithril-cardano-node-internal-database", + "mithril-common", + "rand 0.10.2", + "reqwest 0.13.4", + "serde", + "serde_json", + "slog", + "strum 0.28.0", + "tar", + "thiserror 2.0.20", + "tokio", + "uuid", + "zstd", +] + +[[package]] +name = "mithril-common" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643fd8e23c9ac6e0df136b59070eb8ed5b33e962b749e945b15f2489fab015ec" +dependencies = [ + "anyhow", + "async-trait", + "bech32 0.12.0", + "bincode 2.0.1", + "blake2 0.10.6", + "chrono", + "ciborium", + "digest 0.10.7", + "ed25519-dalek", + "fixed", + "hex", + "kes-summed-ed25519", + "mithril-build-script", + "mithril-merkle-tree", + "mithril-stm", + "nom", + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "rayon", + "semver", + "serde", + "serde_bytes", + "serde_json", + "serde_with 3.23.0", + "sha2 0.10.9", + "slog", + "strum 0.28.0", + "thiserror 2.0.20", + "tokio", + "typetag", + "walkdir", + "wasm-bindgen", +] + +[[package]] +name = "mithril-merkle-tree" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99664c57168ccd410eff1f0aea4d8494ca5c57a9f8b01b8a8a23449ce74e0ba5" +dependencies = [ + "anyhow", + "bincode 2.0.1", + "blake2 0.10.6", + "ckb-merkle-mountain-range", + "hex", + "serde", +] + +[[package]] +name = "mithril-stm" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4df2ce85353b97d3e375bf3d4fcc7ad204f1ad259c038a230bbd1f209c48cfc3" +dependencies = [ + "anyhow", + "blake2 0.10.6", + "blst", + "ciborium", + "digest 0.10.7", + "hex", + "num-bigint", + "num-integer", + "num-rational", + "num-traits", + "rand_core 0.6.4", + "rayon", + "serde", + "thiserror 2.0.20", +] + +[[package]] +name = "multimap" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" + +[[package]] +name = "multiversion" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ca4bea16ffc3f443cf7d866912118196bfef4c6a1556ca00f9f9b00bb43f7c" +dependencies = [ + "multiversion-macros", +] + +[[package]] +name = "multiversion-macros" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d416831a7317ef4b08bee00b69cbbb9c8763da7959a7026244d6266869f9c83" +dependencies = [ + "proc-macro2", + "quote", + "rustversion", + "syn 3.0.4", +] + +[[package]] +name = "multiversion_no_op" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743fb55ba31b18fb1ecef6bdc9aa2743314978ac084044301a7eee33fb99a20d" + +[[package]] +name = "nom" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" +dependencies = [ + "memchr", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + +[[package]] +name = "num-integer" +version = "0.1.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + +[[package]] +name = "object" +version = "0.39.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e5a6c098c7a3b6547378093f5cc30bc54fd361ce711e05293a5cc589562739b" +dependencies = [ + "memchr", +] + +[[package]] +name = "oci-client" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5261a7fb43d9c53b8e63e6d5e86860719dad253d015d022066c72d585125aed8" +dependencies = [ + "bytes", + "chrono", + "futures-util", + "hex", + "http", + "http-auth", + "jsonwebtoken", + "lazy_static", + "oci-spec", + "olpc-cjson", + "regex", + "reqwest 0.13.4", + "serde", + "serde_json", + "sha2 0.11.0", + "thiserror 2.0.20", + "tokio", + "tracing", + "unicase", +] + +[[package]] +name = "oci-spec" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8445a2631507cec628a15fdd6154b54a3ab3f20ed4fe9d73a3b8b7a4e1ba03a" +dependencies = [ + "const_format", + "derive_builder", + "getset", + "regex", + "serde", + "serde_json", + "strum 0.27.2", + "strum_macros 0.27.2", + "thiserror 2.0.20", +] + +[[package]] +name = "olpc-cjson" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "696183c9b5fe81a7715d074fd632e8bd46f4ccc0231a3ed7fc580a80de5f7083" +dependencies = [ + "serde", + "serde_json", + "unicode-normalization", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + +[[package]] +name = "opentelemetry" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0142c63252a9e054e68a4c61a5778f7b14f576274d593f8ce883d191a099682" dependencies = [ "futures-core", + "futures-sink", + "js-sys", + "pin-project-lite", + "thiserror 2.0.20", + "tracing", ] [[package]] -name = "futures-core" -version = "0.3.34" +name = "opentelemetry-http" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" +checksum = "5683015d09e2df236ef005b17f6f196f0d5f6313c4fa43a7b6a53b52776e4331" +dependencies = [ + "async-trait", + "bytes", + "http", + "opentelemetry", + "reqwest 0.13.4", +] [[package]] -name = "futures-io" -version = "0.3.34" +name = "opentelemetry-otlp" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" +checksum = "9966929966d17620d7c316c643ba62631826e10021409357772d5eea84f62c35" +dependencies = [ + "http", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-proto", + "opentelemetry_sdk", + "prost 0.14.4", + "reqwest 0.13.4", + "thiserror 2.0.20", + "tokio", + "tonic 0.14.6", + "tonic-types", +] [[package]] -name = "futures-macro" -version = "0.3.34" +name = "opentelemetry-proto" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" +checksum = "56d658ba1faf63f7b9c492cfbe6e0ec365440a16132d3270c1065f7b33f1b638" dependencies = [ - "proc-macro2", - "quote", - "syn 3.0.4", + "opentelemetry", + "opentelemetry_sdk", + "prost 0.14.4", + "tonic 0.14.6", + "tonic-prost", ] [[package]] -name = "futures-sink" -version = "0.3.34" +name = "opentelemetry_sdk" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" +checksum = "9b59f80e1ac4d5ff7a2db8fb6c80badb7f0f3f858211fba08dd9aaec750894f9" +dependencies = [ + "futures-channel", + "futures-executor", + "futures-util", + "opentelemetry", + "percent-encoding", + "portable-atomic", + "rand 0.9.5", + "thiserror 2.0.20", + "tokio", + "tokio-stream", +] [[package]] -name = "futures-task" -version = "0.3.34" +name = "ordered-float" +version = "5.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" +checksum = "8c7c9e0d9b23589f26070720bac724174bfec1083e82f7854cdd0267518343c0" +dependencies = [ + "num-traits", +] [[package]] -name = "futures-util" -version = "0.3.34" +name = "owo-colors" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" -dependencies = [ - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "slab", -] +checksum = "13c45bb4a6ae1280ec0803b1ef9d3455eb50f01efbbe1447ab020f1d54fba9d8" [[package]] -name = "generic-array" -version = "0.14.7" +name = "pallas" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "846ff0e3269c223e6ed6202eca1dc98399bc85f7db9be4e4574fab778cfa981b" dependencies = [ - "typenum", - "version_check", + "pallas-addresses", + "pallas-codec", + "pallas-configs", + "pallas-crypto", + "pallas-hardano", + "pallas-network", + "pallas-primitives", + "pallas-traverse", + "pallas-txbuilder", + "pallas-utxorpc", + "pallas-validate", ] [[package]] -name = "getrandom" -version = "0.2.17" +name = "pallas-addresses" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +checksum = "4d10fe64a9b5b4b72d1e9ed3a802a6d87a204385a48bdca0136f7fb9ff8be73f" dependencies = [ - "cfg-if", - "libc", - "wasi", + "base58", + "bech32 0.11.1", + "crc", + "cryptoxide", + "hex", + "pallas-codec", + "pallas-crypto", + "thiserror 2.0.20", ] [[package]] -name = "getrandom" -version = "0.4.3" +name = "pallas-codec" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +checksum = "84f558ab7f9d4057aba59a3c8f18dcc06876d803dabced52c431b4ae5b137b2a" dependencies = [ - "cfg-if", - "libc", - "r-efi", + "hex", + "minicbor 0.26.5", + "serde", + "thiserror 2.0.20", ] [[package]] -name = "getset" -version = "0.1.7" +name = "pallas-configs" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cf442baaabe4213ce7d1239afc26c039180b6456da2cededa316ae2c8a77a77" +checksum = "9413d9d84c67434857c08ec2d92c96452671c68fb1921c0c1999a7a699587186" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", + "base64 0.22.1", + "num-rational", + "pallas-addresses", + "pallas-crypto", + "pallas-primitives", + "serde", + "serde_json", + "serde_with 3.23.0", ] [[package]] -name = "heck" -version = "0.5.0" +name = "pallas-crypto" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +checksum = "5abe09448466b168f50eb0beaae4e38a16e49bdfe6b2fba5748ea17a025b15b1" +dependencies = [ + "cryptoxide", + "hex", + "pallas-codec", + "rand_core 0.10.1", + "serde", + "thiserror 2.0.20", +] [[package]] -name = "hex" -version = "0.4.3" +name = "pallas-hardano" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +checksum = "adf818b49428697b0d0d5e680fecffa94020b141460dc6ebfe45295b43c8a6b1" +dependencies = [ + "binary-layout", + "hex", + "pallas-addresses", + "pallas-codec", + "pallas-crypto", + "pallas-network", + "pallas-traverse", + "serde", + "serde_json", + "serde_with 3.23.0", + "tap", + "thiserror 2.0.20", + "tracing", +] [[package]] -name = "http" -version = "1.5.0" +name = "pallas-network" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" +checksum = "4854a1aacddb0021d35469a961e494cb6d2bd2d6de82c6ee4ca2768861cf16cb" dependencies = [ - "bytes", - "itoa", + "byteorder", + "hex", + "itertools 0.14.0", + "pallas-codec", + "pallas-crypto", + "rand 0.10.2", + "socket2", + "thiserror 2.0.20", + "tokio", + "tracing", ] [[package]] -name = "http-auth" -version = "0.1.10" +name = "pallas-primitives" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "150fa4a9462ef926824cf4519c84ed652ca8f4fbae34cb8af045b5cbcaf98822" +checksum = "35c2b627b97f708bbb0252834e300d56b1ccea9c982c0e4189d1a414c1b53c18" dependencies = [ - "memchr", + "hex", + "pallas-codec", + "pallas-crypto", + "serde", + "serde_json", ] [[package]] -name = "http-body" -version = "1.1.0" +name = "pallas-traverse" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" +checksum = "ba24ccce6561ab01d910aa8a89abf7f949f4009c0e36771e763f09d3efba1eed" dependencies = [ - "bytes", - "http", + "hex", + "itertools 0.14.0", + "pallas-addresses", + "pallas-codec", + "pallas-crypto", + "pallas-primitives", + "paste", + "serde", + "thiserror 2.0.20", ] [[package]] -name = "http-body-util" -version = "0.1.5" +name = "pallas-txbuilder" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" +checksum = "24573093e2c342a63cda545ef799c51248a9ccb07061a9de0f2126b694830697" dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", + "hex", + "pallas-addresses", + "pallas-codec", + "pallas-crypto", + "pallas-primitives", + "pallas-traverse", + "serde", + "serde_json", + "thiserror 2.0.20", ] [[package]] -name = "httparse" -version = "1.10.1" +name = "pallas-utxorpc" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +checksum = "bb8a5432ea38e559378d5872d012c5cf34df95e0ed7e5a224aa2645ce57f9675" +dependencies = [ + "pallas-codec", + "pallas-crypto", + "pallas-primitives", + "pallas-traverse", + "pallas-validate", + "prost-types 0.13.5", + "utxorpc-spec", +] [[package]] -name = "hybrid-array" -version = "0.4.14" +name = "pallas-validate" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" +checksum = "dfaac47eb61c648c32cb98bd9fc74414bd173ee57b17c59412242731d0365964" dependencies = [ - "typenum", + "amaru-uplc", + "chrono", + "hex", + "itertools 0.14.0", + "pallas-addresses", + "pallas-codec", + "pallas-crypto", + "pallas-primitives", + "pallas-traverse", + "serde", + "thiserror 2.0.20", + "tracing", ] [[package]] -name = "hyper" -version = "1.11.1" +name = "parking_lot_core" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b501faa50e7a26c3d3560ca625132f4078a17771f4810baf70475ae48cbe43" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "http", - "http-body", - "httparse", - "itoa", - "pin-project-lite", + "cfg-if", + "libc", + "redox_syscall", "smallvec", - "tokio", - "want", + "windows-link", ] [[package]] -name = "hyper-rustls" -version = "0.27.9" +name = "paste" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + +[[package]] +name = "pbjson" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e6349fa080353f4a597daffd05cb81572a9c031a6d4fff7e504947496fcc68" dependencies = [ - "http", - "hyper", - "hyper-util", - "rustls", - "tokio", - "tokio-rustls", - "tower-service", + "base64 0.21.7", + "serde", ] [[package]] -name = "hyper-util" -version = "0.1.20" +name = "pbjson-build" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +checksum = "6eea3058763d6e656105d1403cb04e0a41b7bbac6362d413e7c33be0c32279c9" dependencies = [ - "base64", - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "hyper", - "ipnet", - "libc", - "percent-encoding", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", + "heck", + "itertools 0.13.0", + "prost 0.13.5", + "prost-types 0.13.5", ] [[package]] -name = "iana-time-zone" -version = "0.1.65" +name = "pbjson-types" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +checksum = "e54e5e7bfb1652f95bc361d76f3c780d8e526b134b85417e774166ee941f0887" dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", + "bytes", + "chrono", + "pbjson", + "pbjson-build", + "prost 0.13.5", + "prost-build", + "serde", ] [[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" +name = "percent-encoding" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "petgraph" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" dependencies = [ - "cc", + "fixedbitset", + "indexmap 2.14.2", ] [[package]] -name = "icu_collections" -version = "2.3.0" +name = "pin-project" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ - "displaydoc", - "potential_utf", - "utf8_iter", - "yoke", - "zerofrom", - "zerovec", + "pin-project-internal", ] [[package]] -name = "icu_locale_core" -version = "2.3.0" +name = "pin-project-internal" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] -name = "icu_normalizer" -version = "2.3.0" +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkcs8" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", + "der", + "spki", ] [[package]] -name = "icu_normalizer_data" -version = "2.3.0" +name = "pkg-config" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" [[package]] -name = "icu_properties" -version = "2.3.0" +name = "portable-atomic" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] -name = "icu_properties_data" -version = "2.3.0" +name = "portable-atomic-util" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" +dependencies = [ + "portable-atomic", +] [[package]] -name = "icu_provider" -version = "2.3.1" +name = "potential_utf" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" dependencies = [ - "displaydoc", - "icu_locale_core", + "serde_core", "writeable", - "yoke", - "zerofrom", - "zerotrie", "zerovec", ] [[package]] -name = "ident_case" -version = "1.0.1" +name = "powerfmt" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] -name = "idna" -version = "1.1.0" +name = "ppv-lite86" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", + "zerocopy", ] [[package]] -name = "idna_adapter" -version = "1.2.2" +name = "prettyplease" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ - "icu_normalizer", - "icu_properties", + "proc-macro2", + "syn 2.0.119", ] [[package]] -name = "ipnet" -version = "2.12.1" +name = "proc-macro2" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a756c3fac73139e83f14c2d742155dd2b78d3ee56597b419a0579b7bdd6dd78" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] [[package]] -name = "itoa" -version = "1.0.18" +name = "prost" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" +dependencies = [ + "bytes", + "prost-derive 0.13.5", +] [[package]] -name = "jni" -version = "0.22.4" +name = "prost" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1" dependencies = [ - "cfg-if", - "combine", - "jni-macros", - "jni-sys", - "log", - "simd_cesu8", - "thiserror", - "walkdir", - "windows-link", + "bytes", + "prost-derive 0.14.4", ] [[package]] -name = "jni-macros" -version = "0.22.4" +name = "prost-build" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" dependencies = [ - "proc-macro2", - "quote", - "rustc_version", - "simd_cesu8", + "heck", + "itertools 0.14.0", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost 0.13.5", + "prost-types 0.13.5", + "regex", "syn 2.0.119", + "tempfile", ] [[package]] -name = "jni-sys" -version = "0.4.1" +name = "prost-derive" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" dependencies = [ - "jni-sys-macros", + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] -name = "jni-sys-macros" -version = "0.4.1" +name = "prost-derive" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", "quote", "syn 2.0.119", ] [[package]] -name = "jobserver" -version = "0.1.35" +name = "prost-types" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" dependencies = [ - "getrandom 0.4.3", - "libc", + "prost 0.13.5", ] [[package]] -name = "js-sys" -version = "0.3.104" +name = "prost-types" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" +checksum = "f94967dc7688f3054c7fac87473ffae4cc4c3904800e2d9f5b857246d8963b0a" dependencies = [ - "cfg-if", - "futures-util", - "wasm-bindgen", + "prost 0.14.4", ] [[package]] -name = "jsonwebtoken" -version = "10.4.0" +name = "protoc-wkt" +version = "1.0.0+3.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eba32bfb4ffdeaca3e34431072faf01745c9b26d25504aa7a6cf5684334fc4fc" -dependencies = [ - "base64", - "getrandom 0.2.17", - "js-sys", - "serde", - "serde_json", - "signature", - "zeroize", -] +checksum = "ae1d0fdc23ea945d58449259496ba12d3b520da1a45ce5011f631c990add9029" [[package]] -name = "konst" -version = "0.2.20" +name = "psm" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" +checksum = "4dcd034599e63b970727f70d79e02d62390a4a84f7c6b827c27c46d5ac3fa622" dependencies = [ - "konst_macro_rules", + "ar_archive_writer", + "cc", ] [[package]] -name = "konst_macro_rules" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" - -[[package]] -name = "lazy_static" -version = "1.5.0" +name = "quick_cache" +version = "0.6.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "b9c6658afe513a3b484e3abfdaa0d03ef3c0bbf017542c178dd55f94eb3051f9" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", +] [[package]] -name = "libc" -version = "0.2.189" +name = "quinn" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.20", + "tokio", + "tracing", + "web-time", +] [[package]] -name = "linux-raw-sys" -version = "0.12.1" +name = "quinn-proto" +version = "0.11.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" +checksum = "04759210543be93709136e28212294a659ef5001836ff4eab4d663e4529bba83" +dependencies = [ + "bytes", + "getrandom 0.4.3", + "lru-slab", + "rand 0.10.2", + "rand_pcg", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.20", + "tinyvec", + "tracing", + "web-time", +] [[package]] -name = "litemap" -version = "0.8.3" +name = "quinn-udp" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" +checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.61.2", +] [[package]] -name = "log" -version = "0.4.34" +name = "quote" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] [[package]] -name = "memchr" -version = "2.8.3" +name = "r-efi" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] -name = "minicbor" -version = "0.26.5" +name = "r-efi" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a309f581ade7597820083bc275075c4c6986e57e53f8d26f88507cfefc8c987" -dependencies = [ - "minicbor-derive", -] +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] -name = "minicbor-derive" -version = "0.16.2" +name = "rand" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9882ef5c56df184b8ffc107fc6c61e33ee3a654b021961d790a78571bb9d67a" +checksum = "e058c7de0b26af77780c769414d6257830bb240f3c38477dbc2c16e5f54d6d4c" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", ] [[package]] -name = "mio" -version = "1.2.2" +name = "rand" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ - "libc", - "wasi", - "windows-sys 0.61.2", + "rand_chacha 0.9.0", + "rand_core 0.9.5", ] [[package]] -name = "num-traits" -version = "0.2.19" +name = "rand" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ - "autocfg", + "chacha20", + "getrandom 0.4.3", + "rand_core 0.10.1", ] [[package]] -name = "oci-client" -version = "0.17.0" +name = "rand_chacha" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5261a7fb43d9c53b8e63e6d5e86860719dad253d015d022066c72d585125aed8" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ - "bytes", - "chrono", - "futures-util", - "hex", - "http", - "http-auth", - "jsonwebtoken", - "lazy_static", - "oci-spec", - "olpc-cjson", - "regex", - "reqwest", - "serde", - "serde_json", - "sha2 0.11.0", - "thiserror", - "tokio", - "tracing", - "unicase", + "ppv-lite86", + "rand_core 0.6.4", ] [[package]] -name = "oci-spec" +name = "rand_chacha" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8445a2631507cec628a15fdd6154b54a3ab3f20ed4fe9d73a3b8b7a4e1ba03a" -dependencies = [ - "const_format", - "derive_builder", - "getset", - "regex", - "serde", - "serde_json", - "strum", - "strum_macros", - "thiserror", +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", ] [[package]] -name = "olpc-cjson" -version = "0.1.4" +name = "rand_core" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "696183c9b5fe81a7715d074fd632e8bd46f4ccc0231a3ed7fc580a80de5f7083" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "serde", - "serde_json", - "unicode-normalization", + "getrandom 0.2.17", ] [[package]] -name = "once_cell" -version = "1.21.4" +name = "rand_core" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] [[package]] -name = "openssl-probe" -version = "0.2.1" +name = "rand_core" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" [[package]] -name = "percent-encoding" -version = "2.3.2" +name = "rand_pcg" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core 0.10.1", +] [[package]] -name = "pin-project-lite" -version = "0.2.17" +name = "rayon" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +dependencies = [ + "either", + "rayon-core", +] [[package]] -name = "pkg-config" -version = "0.3.34" +name = "rayon-core" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] [[package]] -name = "potential_utf" -version = "0.1.6" +name = "redb" +version = "3.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" +checksum = "4ba239c1c1693315d3cc0e601db3b3965543afbf48c41730fdca2f069f510f4a" dependencies = [ - "zerovec", + "libc", ] [[package]] -name = "proc-macro2" -version = "1.0.107" +name = "redb-extras" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +checksum = "ba3a0913835a509dd3f308cfe2379b9884f7bcc8d1ff856513eeab1ec450923f" dependencies = [ - "unicode-ident", + "redb", + "roaring", + "thiserror 1.0.69", + "xxhash-rust", ] [[package]] -name = "quote" -version = "1.0.47" +name = "redox_syscall" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "proc-macro2", + "bitflags 2.13.1", ] [[package]] -name = "r-efi" -version = "6.0.0" +name = "ref-cast" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3" +dependencies = [ + "ref-cast-impl", +] [[package]] -name = "rand_core" -version = "0.6.4" +name = "ref-cast-impl" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" dependencies = [ - "getrandom 0.2.17", + "proc-macro2", + "quote", + "syn 3.0.4", ] [[package]] @@ -1028,8 +3883,19 @@ checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.18", + "regex-syntax 0.8.11", +] + +[[package]] +name = "regex-automata" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.5", ] [[package]] @@ -1040,25 +3906,80 @@ checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.11", ] +[[package]] +name = "regex-lite" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" + +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + [[package]] name = "regex-syntax" version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower 0.5.3", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] + [[package]] name = "reqwest" version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" dependencies = [ - "base64", + "base64 0.22.1", "bytes", + "encoding_rs", + "futures-channel", "futures-core", "futures-util", + "h2", "http", "http-body", "http-body-util", @@ -1067,6 +3988,7 @@ dependencies = [ "hyper-util", "js-sys", "log", + "mime", "percent-encoding", "pin-project-lite", "rustls", @@ -1079,7 +4001,7 @@ dependencies = [ "tokio", "tokio-rustls", "tokio-util", - "tower", + "tower 0.5.3", "tower-http", "tower-service", "url", @@ -1103,6 +4025,28 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "roaring" +version = "0.10.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e8d2cfa184d94d0726d650a9f4a1be7f9b76ac9fdb954219878dc00c1c1e7b" +dependencies = [ + "bytemuck", + "byteorder", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b74b56ffa8bb2830709a538c2cbcae9aa062db0d2a42563bfb09bdaae44020eb" + +[[package]] +name = "rustc-hash" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" + [[package]] name = "rustc_version" version = "0.4.1" @@ -1118,7 +4062,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags", + "bitflags 2.13.1", "errno", "libc", "linux-raw-sys", @@ -1131,6 +4075,7 @@ version = "0.23.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" dependencies = [ + "log", "once_cell", "ring", "rustls-pki-types", @@ -1157,6 +4102,7 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" dependencies = [ + "web-time", "zeroize", ] @@ -1166,7 +4112,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" dependencies = [ - "core-foundation", + "core-foundation 0.10.1", "core-foundation-sys", "jni", "log", @@ -1225,6 +4171,29 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "saphyr" +version = "0.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef5bcc48916766e53689486df76c80ccf62a38f20d20b816056ff6ab84197cbd" +dependencies = [ + "encoding_rs", + "hashlink", + "ordered-float", + "saphyr-parser", + "thiserror 2.0.20", +] + +[[package]] +name = "saphyr-parser" +version = "0.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbeae0f40b92f2afe16422744aabb145187167184cc18bf4d01da5acdc665f09" +dependencies = [ + "arraydeque", + "thiserror 2.0.20", +] + [[package]] name = "schannel" version = "0.1.29" @@ -1234,14 +4203,64 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "secp256k1" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252" +dependencies = [ + "bitcoin_hashes", + "rand 0.8.8", + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" +dependencies = [ + "cc", +] + [[package]] name = "security-framework" version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags", - "core-foundation", + "bitflags 2.13.1", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -1257,6 +4276,12 @@ dependencies = [ "libc", ] +[[package]] +name = "self_cell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab42ca02749e120097e328d91d415325bdf43b1c72c4c8badf37375fe40a813" + [[package]] name = "semver" version = "1.0.28" @@ -1273,6 +4298,16 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + [[package]] name = "serde_core" version = "1.0.229" @@ -1317,6 +4352,24 @@ dependencies = [ "zmij", ] +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1329,6 +4382,78 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +dependencies = [ + "base64 0.13.1", + "chrono", + "hex", + "indexmap 1.9.3", + "serde", + "serde_json", + "serde_with_macros 2.3.3", + "time", +] + +[[package]] +name = "serde_with" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "935177bb8c0cd8ca1a4e6d1a2ac8988bea69cab4f9d3a31311e012ad27868ea4" +dependencies = [ + "base64 0.23.1", + "bs58", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.14.2", + "jiff", + "schemars 0.9.0", + "schemars 1.2.2", + "serde_core", + "serde_json", + "serde_with_macros 3.23.0", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" +dependencies = [ + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "serde_with_macros" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d607aa01a3cb0ad757d6fd216136910db3c97b102fe686585689615a02dbcdc" +dependencies = [ + "darling 0.24.1", + "proc-macro2", + "quote", + "syn 3.0.4", +] + +[[package]] +name = "sfa" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1296838937cab56cd6c4eeeb8718ec777383700c33f060e2869867bd01d1175" +dependencies = [ + "byteorder-lite", + "log", + "xxhash-rust", +] + [[package]] name = "sha2" version = "0.10.9" @@ -1351,21 +4476,56 @@ dependencies = [ "digest 0.11.3", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" +[[package]] +name = "signal-hook" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + [[package]] name = "signature" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "rand_core", + "rand_core 0.6.4", ] +[[package]] +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + [[package]] name = "simd_cesu8" version = "1.2.0" @@ -1388,6 +4548,12 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +[[package]] +name = "slog" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06" + [[package]] name = "smallvec" version = "1.16.0" @@ -1404,12 +4570,44 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "spin" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +[[package]] +name = "stacker" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707f49d46706bacf8a2b00d51dace3f9de527c13eec3778f570c411f89e69967" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "windows-sys 0.61.2", +] + [[package]] name = "stats_alloc" version = "0.1.10" @@ -1424,9 +4622,9 @@ dependencies = [ "futures-util", "hex", "http", - "minicbor", + "minicbor 0.26.5", "oci-client", - "reqwest", + "reqwest 0.13.4", "rustls", "serde", "serde_jcs", @@ -1434,23 +4632,63 @@ dependencies = [ "sha2 0.10.9", "stats_alloc", "tempfile", - "thiserror", + "thiserror 2.0.20", "tokio", "zstd", ] +[[package]] +name = "stelae-cardano" +version = "0.2.0" +dependencies = [ + "dolos", + "dolos-cardano", + "dolos-core", + "dolos-mithril", + "dolos-snapshot", + "dolos-testing", + "itertools 0.14.0", + "pallas", + "serde", + "serde_json", + "stelae", + "stelae-driver", + "tempfile", + "thiserror 2.0.20", + "tokio", + "tokio-util", + "toml 0.8.23", + "tracing", +] + [[package]] name = "stelae-driver" version = "0.2.0" dependencies = [ "fs4", - "minicbor", + "minicbor 0.26.5", "serde", "serde_json", "stelae", "tempfile", - "thiserror", + "thiserror 2.0.20", + "tracing", +] + +[[package]] +name = "stelae-publisher" +version = "0.2.0" +dependencies = [ + "clap", + "config", + "miette", + "rustls", + "stelae", + "stelae-cardano", + "tokio", + "tokio-util", "tracing", + "tracing-subscriber", ] [[package]] @@ -1465,6 +4703,15 @@ version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +[[package]] +name = "strum" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" +dependencies = [ + "strum_macros 0.28.0", +] + [[package]] name = "strum_macros" version = "0.27.2" @@ -1477,12 +4724,45 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "subtle" version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "supports-color" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6" +dependencies = [ + "is_ci", +] + +[[package]] +name = "supports-hyperlinks" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e396b6523b11ccb83120b115a0b7366de372751aa6edf19844dfb13a6af97e91" + +[[package]] +name = "supports-unicode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" + [[package]] name = "syn" version = "2.0.119" @@ -1525,6 +4805,44 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags 2.13.1", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tar" +version = "0.4.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" +dependencies = [ + "filetime", + "libc", + "xattr", +] + [[package]] name = "tempfile" version = "3.27.0" @@ -1538,13 +4856,53 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "terminal_size" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874" +dependencies = [ + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "textwrap" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b81c0cb5fce14f53e49c1d4da0c508334ff12040221bb8ab01b2dabd91d04b6e" +dependencies = [ + "icu_segmenter", + "unicode-width 0.2.2", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + [[package]] name = "thiserror" version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ - "thiserror-impl", + "thiserror-impl 2.0.20", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] @@ -1558,6 +4916,56 @@ dependencies = [ "syn 3.0.4", ] +[[package]] +name = "thread_local" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "time" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +dependencies = [ + "deranged", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "time-macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinystr" version = "0.8.4" @@ -1565,6 +4973,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" dependencies = [ "displaydoc", + "serde_core", "zerovec", ] @@ -1581,55 +4990,222 @@ dependencies = [ name = "tinyvec_macros" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.4", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-util" +version = "0.7.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "futures-util", + "libc", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_edit", +] + +[[package]] +name = "toml" +version = "1.1.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "920602543f0911ab71da12c50d59701da54c196d1a2bf5cb4b75667f137a406a" +dependencies = [ + "serde_core", + "serde_spanned 1.1.1", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "winnow 1.0.4", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap 2.14.2", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_write", + "winnow 0.7.15", +] + +[[package]] +name = "toml_parser" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" +dependencies = [ + "winnow 1.0.4", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "tonic" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" +dependencies = [ + "async-trait", + "base64 0.22.1", + "bytes", + "http", + "http-body", + "http-body-util", + "percent-encoding", + "pin-project", + "prost 0.13.5", + "tokio-stream", + "tower-layer", + "tower-service", + "tracing", +] [[package]] -name = "tokio" -version = "1.53.1" +name = "tonic" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" +checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" dependencies = [ + "async-trait", + "base64 0.22.1", "bytes", - "libc", - "mio", - "pin-project-lite", - "socket2", - "tokio-macros", - "windows-sys 0.61.2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "sync_wrapper", + "tokio", + "tokio-stream", + "tower 0.5.3", + "tower-layer", + "tower-service", + "tracing", ] [[package]] -name = "tokio-macros" -version = "2.7.2" +name = "tonic-prost" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" +checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0" dependencies = [ - "proc-macro2", - "quote", - "syn 3.0.4", + "bytes", + "prost 0.14.4", + "tonic 0.14.6", ] [[package]] -name = "tokio-rustls" -version = "0.26.4" +name = "tonic-types" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +checksum = "73ab1b02061f83d519bba3caa167f88f261ef05720ab8ebc954ade70de3348e8" dependencies = [ - "rustls", - "tokio", + "prost 0.14.4", + "prost-types 0.14.4", + "tonic 0.14.6", ] [[package]] -name = "tokio-util" -version = "0.7.19" +name = "tower" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", + "tower-layer", + "tower-service", + "tracing", ] [[package]] @@ -1640,11 +5216,15 @@ checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", + "indexmap 2.14.2", "pin-project-lite", + "slab", "sync_wrapper", "tokio", + "tokio-util", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -1653,15 +5233,16 @@ version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ - "bitflags", + "bitflags 2.13.1", "bytes", "futures-util", "http", "http-body", "pin-project-lite", - "tower", + "tower 0.5.3", "tower-layer", "tower-service", + "tracing", "url", ] @@ -1707,6 +5288,59 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adbc64cba7137545b8044cb1fe9814f7aacf3c6b5f9b45be8bb5db538befdb26" +dependencies = [ + "js-sys", + "opentelemetry", + "smallvec", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", + "web-time", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "trait-variant" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b19a4867a870f6edc4c283f2b455804b1879c0baf0e642f26b03ed8ee262d9d3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] @@ -1715,12 +5349,48 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "twox-hash" +version = "2.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5283634e518fe9e82c7b20520bb4bc209009fd16c82077c802f8111ecbb0117a" + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + [[package]] name = "typenum" version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" +[[package]] +name = "typetag" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c90e86058a30d42a1a928dfb4b49bb33c98c3a2b4909492e6b0881cd94798ec2" +dependencies = [ + "erased-serde", + "inventory", + "once_cell", + "serde", + "typetag-impl", +] + +[[package]] +name = "typetag-impl" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f153acc4e99a5f2a5aefa09fb078be54e26271b2813f6041200b224c098d8328" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.4", +] + [[package]] name = "unicase" version = "2.9.0" @@ -1742,6 +5412,24 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + [[package]] name = "unicode-xid" version = "0.2.6" @@ -1754,6 +5442,12 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "unty" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" + [[package]] name = "url" version = "2.5.8" @@ -1772,12 +5466,100 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "utxorpc-spec" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa35373e6fbf0ea73651328aecd1641f92684de54bd908e3aa9855866b1c9875" +dependencies = [ + "bytes", + "futures-core", + "pbjson", + "pbjson-types", + "prost 0.13.5", + "prost-types 0.13.5", + "serde", + "tonic 0.12.3", +] + +[[package]] +name = "uuid" +version = "1.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ef6dac1e96601b4fb3acccccff2139741fcb757cb9a36089bf5be91cfb285ce" +dependencies = [ + "getrandom 0.4.3", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "varint-rs" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa6c38708f6257f1ec2ca7e5a11f9bbf58a27d7060078b6b333624968183d96" + +[[package]] +name = "vergen" +version = "9.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b849a1f6d8639e8de261e81ee0fc881e3e3620db1af9f2e0da015d4382ceaf75" +dependencies = [ + "anyhow", + "derive_builder", + "rustversion", + "vergen-lib", +] + +[[package]] +name = "vergen-gitcl" +version = "9.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ff3b5300a085d6bcd8fc96a507f706a28ae3814693236c9b409db71a1d15b9" +dependencies = [ + "anyhow", + "derive_builder", + "rustversion", + "time", + "vergen", + "vergen-lib", +] + +[[package]] +name = "vergen-lib" +version = "9.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b34a29ba7e9c59e62f229ae1932fb1b8fb8a6fdcc99215a641913f5f5a59a569" +dependencies = [ + "anyhow", + "derive_builder", + "rustversion", +] + [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "virtue" +version = "0.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" + [[package]] name = "walkdir" version = "2.5.0" @@ -1803,6 +5585,15 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "wasm-bindgen" version = "0.2.127" @@ -1881,6 +5672,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "webpki-root-certs" version = "1.0.9" @@ -1890,6 +5691,15 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "webpki-roots" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "winapi-util" version = "0.1.11" @@ -1940,6 +5750,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link", + "windows-result", + "windows-strings", +] + [[package]] name = "windows-result" version = "0.4.1" @@ -1967,6 +5788,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.61.2" @@ -2040,12 +5870,52 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + [[package]] name = "writeable" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" +[[package]] +name = "xattr" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" +dependencies = [ + "libc", + "rustix", +] + +[[package]] +name = "xxhash-rust" +version = "0.8.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aee1b19627c7c60102ab80d3a9cbe18de90bfe03bfa6c3715447681f0e8c8af6" + [[package]] name = "yoke" version = "0.8.3" @@ -2069,6 +5939,26 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zerocopy" +version = "0.8.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d35102a9f36d089ccae9e4c6802bc118be4487b80aaffc0ab4e0cf5ce92d2873" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c01f5ab44258da43cf276c74a2763db2ff3969c9c652c3f2de07041d0b2bc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "zerofrom" version = "0.1.8" @@ -2119,6 +6009,7 @@ dependencies = [ "displaydoc", "yoke", "zerofrom", + "zerovec", ] [[package]] @@ -2127,6 +6018,7 @@ version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ + "serde", "yoke", "zerofrom", "zerovec-derive", @@ -2143,6 +6035,12 @@ dependencies = [ "syn 3.0.4", ] +[[package]] +name = "zlib-rs" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b31d188d9d685a4f9c7b46d6e36631b07058d2cfe190267adce54dc230bf12" + [[package]] name = "zmij" version = "1.0.23" diff --git a/Cargo.toml b/Cargo.toml index 5e08088..0712eee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ # a single tag and a consumer pins both crates with one git reference. [workspace] resolver = "2" -members = ["stelae", "stelae-driver"] +members = ["stelae", "stelae-driver", "stelae-cardano", "stelae-publisher"] [workspace.package] version = "0.2.0" @@ -13,6 +13,14 @@ edition = "2021" license = "Apache-2.0" repository = "https://github.com/txpipe/stelae" +# Dolos v2.0.0-alpha.0 pins the released v0.2.0 Stelae crates. The publisher +# is built in this workspace, so patch both names back to these paths: this is +# what makes the profile's trait and registry types identical to the host's, +# rather than two same-version crates from different sources. +[patch."https://github.com/txpipe/stelae"] +stelae = { path = "stelae" } +stelae-driver = { path = "stelae-driver" } + # Same release flow as dolos: `cargo release` bumps the lockstep workspace # version, regenerates the root CHANGELOG.md through git-cliff, commits and # tags `v{{version}}`; pushing the commit and the tag stays a manual step. diff --git a/README.md b/README.md index 770a68b..674d817 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,11 @@ producer and consumer; it carries no Cardano assumption. | --- | --- | | [`stelae`](stelae/) | The wire protocol: framing, inscription, digests, plan/resume, the directory and OCI transports. The normative crate — a third party implements a profile against this and nothing else. | | [`stelae-driver`](stelae-driver/) | Profile-generic lifecycle machinery: the chained-publish lifecycle, restore budget/checkpoint, preflight, retry, reporting. A profile author's toolkit, never required for wire compatibility. | +| [`stelae-cardano`](stelae-cardano/) | Cardano application integration: cold-start restore, publication policy and the sequential Mithril backfill state machine. The only workspace crate allowed to depend on Dolos. | +| [`stelae-publisher`](stelae-publisher/) | The `stelae-publisher` executable and its operator-facing commands. | + +Publisher commands, configuration precedence and persisted-state contracts are +documented in [docs/publisher.md](docs/publisher.md). The boundary proof lives in the test suite: `stelae/tests/toy_profile.rs` implements a second, trivial profile against the protocol surface alone. diff --git a/deny.toml b/deny.toml index 294c400..03e5f85 100644 --- a/deny.toml +++ b/deny.toml @@ -20,23 +20,22 @@ ignore = [ multiple-versions = "warn" deny = [ - # The extraction boundary, stated where it is enforced: the protocol - # depends on no profile. In the dolos workspace this was a rule someone - # had to keep; here the resolver checks it. Enumerated because cargo-deny - # matches names exactly — a new dolos-* crate joins this list when it is - # born, which its author is the person editing these manifests anyway. - { crate = "dolos", reason = "the Stelae crates must never depend on a dolos crate; the protocol depends on no profile (SPEC.md)" }, - { crate = "dolos-cardano", reason = "the Stelae crates must never depend on a dolos crate" }, - { crate = "dolos-core", reason = "the Stelae crates must never depend on a dolos crate" }, - { crate = "dolos-fjall", reason = "the Stelae crates must never depend on a dolos crate" }, - { crate = "dolos-flatfiles", reason = "the Stelae crates must never depend on a dolos crate" }, - { crate = "dolos-minibf", reason = "the Stelae crates must never depend on a dolos crate" }, - { crate = "dolos-minikupo", reason = "the Stelae crates must never depend on a dolos crate" }, - { crate = "dolos-mithril", reason = "the Stelae crates must never depend on a dolos crate" }, - { crate = "dolos-redb3", reason = "the Stelae crates must never depend on a dolos crate" }, - { crate = "dolos-snapshot", reason = "the Stelae crates must never depend on a dolos crate" }, - { crate = "dolos-testing", reason = "the Stelae crates must never depend on a dolos crate" }, - { crate = "dolos-trp", reason = "the Stelae crates must never depend on a dolos crate" }, + # Dolos is admitted only below the Cardano integration. These wrappers keep + # the protocol and generic-driver boundary resolver-enforced: a direct Dolos + # edge from either crate fails. Names are enumerated because cargo-deny + # matches exactly; a new dolos-* crate must be added when introduced. + { crate = "dolos", wrappers = ["stelae-cardano"], reason = "Dolos belongs only below the Cardano integration; the protocol depends on no profile (SPEC.md)" }, + { crate = "dolos-cardano", wrappers = ["stelae-cardano", "dolos", "dolos-snapshot", "dolos-testing"], reason = "Dolos belongs only below the Cardano integration" }, + { crate = "dolos-core", wrappers = ["stelae-cardano", "dolos", "dolos-cardano", "dolos-snapshot", "dolos-mithril", "dolos-fjall", "dolos-redb3", "dolos-testing"], reason = "Dolos belongs only below the Cardano integration" }, + { crate = "dolos-fjall", wrappers = ["dolos", "dolos-testing"], reason = "Dolos belongs only below the Cardano integration" }, + { crate = "dolos-flatfiles", wrappers = ["dolos-fjall"], reason = "Dolos belongs only below the Cardano integration" }, + { crate = "dolos-minibf", reason = "Dolos belongs only below the Cardano integration" }, + { crate = "dolos-minikupo", reason = "Dolos belongs only below the Cardano integration" }, + { crate = "dolos-mithril", wrappers = ["stelae-cardano"], reason = "Dolos belongs only below the Cardano integration" }, + { crate = "dolos-redb3", wrappers = ["dolos", "dolos-testing"], reason = "Dolos belongs only below the Cardano integration" }, + { crate = "dolos-snapshot", wrappers = ["stelae-cardano", "dolos"], reason = "Dolos belongs only below the Cardano integration" }, + { crate = "dolos-testing", wrappers = ["stelae-cardano"], reason = "Dolos belongs only below the Cardano integration" }, + { crate = "dolos-trp", reason = "Dolos belongs only below the Cardano integration" }, # The same C-toolchain refusal the dolos workspace makes: the oci feature # takes reqwest with rustls-no-provider so the crypto provider is the # host's choice, and nothing here may drag cmake back in. diff --git a/docs/publisher.md b/docs/publisher.md new file mode 100644 index 0000000..93eb8e0 --- /dev/null +++ b/docs/publisher.md @@ -0,0 +1,133 @@ +# Stelae Cardano publisher + +`stelae-publisher` owns the Cardano publisher process. Its +`stelae-cardano` integration crate contains the publish-before-advance loop and +repository policy; Dolos supplies the ledger engine, storage backends, Mithril +client and `io.txpipe.dolos.cardano` profile through supported library facades. +No command starts or shells out to a Dolos executable. + +## Source and dependency identity + +All imported Dolos crates are pinned to +`1ae4e91c18a9e1456a3612af402d7b9b97546d30`, the merge revision of +[Dolos PR 1334](https://github.com/txpipe/dolos/pull/1334). The root `dolos` +package is imported with default features disabled. The workspace patch for +`https://github.com/txpipe/stelae` resolves the profile's v0.2.0 dependencies +back to the workspace `stelae` and `stelae-driver` packages. This prevents two +same-version protocol type universes. + +The lockfile is committed. These commands verify the intended graph: + +```sh +cargo build --locked --workspace --all-targets --all-features +cargo tree --locked -p stelae -e normal --all-features +cargo tree --locked -p stelae-driver -e normal --all-features +cargo tree --locked -d +cargo deny check advisories bans +``` + +Whole-workspace builds use Rust 1.93 or newer, as required by the pinned +Mithril dependency graph. + +The first two trees must contain no package matching `dolos` or `dolos-*`. +`deny.toml` permits Dolos packages only under `stelae-cardano`; a Dolos edge +from the protocol or generic driver is an error. + +## Configuration precedence + +The host deliberately keeps the current Dolos configuration names. Sources +are layered from lowest to highest precedence: + +1. optional `/etc/dolos/daemon.toml`; +2. optional `./dolos.toml`; +3. the required file named by global `--config`; +4. `DOLOS_*` environment variables. + +Registry credentials therefore remain +`DOLOS_STELAE_REGISTRY_USER`, `DOLOS_STELAE_REGISTRY_PASSWORD`, and +`DOLOS_STELAE_REGISTRY_TOKEN`. A token and user together, or a password with +no user, fail through the shared profile credential policy. CLI command names +belong to this executable; profile names, media types, tags and repository +identities remain the existing wire values. + +## Commands + +Publish the committed stores once to a directory: + +```sh +stelae-publisher --config dolos.toml publish --output-dir ./stele +``` + +Publish once to a repository: + +```sh +stelae-publisher --config dolos.toml publish \ + --repo oci://registry.example/cardano/preview \ + --concurrency 4 +``` + +`publish` preserves epoch selection, index-band and producer tuning, +`--rebuild`, `--verify-carried`, `--dry-run`, and `--require-new`. An +up-to-date repository is a successful no-op unless `--require-new` is set. + +Initialize empty stores and then backfill: + +```sh +stelae-publisher --config dolos.toml run \ + --repo oci://registry.example/cardano/preview \ + --concurrency 4 +``` + +`run` restores `latest` from the publication repository before replay. Use +`--restore-source` to restore elsewhere. Restore failure is fatal and partial +stores are cleared. `--allow-genesis` is the only genesis fallback and is for +a deliberately verified first publication. `initialize`, `publish`, and +`backfill` are also available independently. + +OCI operations run synchronously on the process thread. Mithril calls have a +separate Tokio runtime. SIGINT and SIGTERM cancel acquisition and are observed +between import chunks and retry attempts; an in-flight OCI publication still +finishes before shutdown is observed. Replay sessions explicitly finalize on +success and failure. + +## Persisted state and ordering + +The following paths are part of restart compatibility: + +| Path | Meaning | +| --- | --- | +| `/` | Dolos WAL, state, archive and mempool stores selected by the existing config | +| `/.snapshot-publish.json` | completed-layer publication journal used for in-place retry | +| `/.snapshot-restore.json` | immutable-layer restore checkpoint read by `--resume` | +| `/.stelae-publisher-initialized.json` | source, storage path, network magic and restore/genesis decision for cold start | +| `/scratch` | default OCI staging directory | +| `/mithril/immutable` | default bounded Mithril download window | + +Before any cleanup, initialization requires an absolute storage path below a +filesystem root. A marker is accepted only when its storage path, network +magic and source match the current configuration. A restore marker without a +committed cursor fails closed. A genesis marker can describe an empty store +only while the current run explicitly opts into genesis. + +The backfill state machine preserves these rules from the accepted Dolos host: + +- publish a committed epoch boundary before replaying past it; +- prune history only after that publication succeeds; +- retain two immutable files of cleanup/download margin using the configured + network's genesis chunk geometry; +- retry transient repository work in place using the publication journal; +- retain `snapshot.state_epochs` and the profile's existing plan, schema, + media-type, compression and journal identities. + +## Finite duplication window + +Dolos still carries its old `snapshot publish` / `snapshot backfill` command +and backfill module at the pinned revision. This host does not call that +module: `stelae-cardano/src/backfill.rs` owns the running loop. The duplicate is +temporary evidence for parity. Publisher-pipeline step 6 removes the old Dolos +implementation after parity, and step 7 removes the stale dependency pin. + +This increment does not ship an image, change a Helm chart, deploy, publish to +a production registry, or claim full production parity. Packaging, operational +cutover, differential live-registry evidence and later pin cleanup remain the +following publisher-pipeline steps. diff --git a/stelae-cardano/Cargo.toml b/stelae-cardano/Cargo.toml new file mode 100644 index 0000000..d9e6b24 --- /dev/null +++ b/stelae-cardano/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "stelae-cardano" +description = "Cardano publisher integration for Stelae" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +stelae = { path = "../stelae", version = "=0.2.0", features = ["oci"] } +stelae-driver = { path = "../stelae-driver", version = "=0.2.0", features = ["oci"] } + +# Accepted publisher-pipeline facade revision: txpipe/dolos PR #1334. +dolos = { git = "https://github.com/txpipe/dolos", rev = "1ae4e91c18a9e1456a3612af402d7b9b97546d30", default-features = false } +dolos-cardano = { git = "https://github.com/txpipe/dolos", rev = "1ae4e91c18a9e1456a3612af402d7b9b97546d30" } +dolos-core = { git = "https://github.com/txpipe/dolos", rev = "1ae4e91c18a9e1456a3612af402d7b9b97546d30" } +dolos-mithril = { git = "https://github.com/txpipe/dolos", rev = "1ae4e91c18a9e1456a3612af402d7b9b97546d30" } +dolos-snapshot = { git = "https://github.com/txpipe/dolos", rev = "1ae4e91c18a9e1456a3612af402d7b9b97546d30" } + +itertools = "0.14.0" +pallas = { version = "1.1.1", features = ["hardano", "phase2", "unstable"] } +serde = { version = "1.0.136", features = ["derive"] } +serde_json = "1.0.122" +thiserror = "2.0.12" +tokio = { version = "1.47", features = ["rt", "rt-multi-thread", "signal"] } +tokio-util = { version = "0.7.11", features = ["rt"] } +tracing = "0.1.37" + +[dev-dependencies] +dolos-testing = { git = "https://github.com/txpipe/dolos", rev = "1ae4e91c18a9e1456a3612af402d7b9b97546d30" } +tempfile = "3.20.0" +toml = "0.8.13" diff --git a/stelae-cardano/src/backfill.rs b/stelae-cardano/src/backfill.rs new file mode 100644 index 0000000..1f91e5b --- /dev/null +++ b/stelae-cardano/src/backfill.rs @@ -0,0 +1,748 @@ +//! Stelae-owned Cardano backfill state machine. +//! +//! Every iteration publishes the committed boundary before it advances, +//! prunes only after that publish succeeds, downloads bounded Mithril windows, +//! and closes the replay engine on every result. This is intentionally a +//! sequential relocation of the Dolos publisher loop at `DOLOS_REVISION`. + +use std::{ + path::{Path, PathBuf}, + sync::Arc, +}; + +use dolos::engine::{BulkReplaySession, ReplayWorkspace}; +use dolos_core::{ + config::{MithrilConfig, RootConfig}, + BlockSlot, ChainPoint, Genesis, RawBlock, ReplayProgress, +}; +use dolos_mithril as mithril; +use dolos_mithril::mithril_client::feedback::FeedbackReceiver; +use dolos_snapshot::{export::Plan, planning, source::SnapshotSource}; +use itertools::Itertools as _; +use tokio_util::sync::CancellationToken; +use tracing::{info, warn}; + +use crate::publisher::{BackfillPublisher, RepositoryPublish}; + +const IMPORT_CHUNK: usize = 100; +const IMMUTABLE_FILE_MARGIN: u64 = 2; +const SLOTS_PER_SECURITY_PARAM: u64 = 10; +const FALLBACK_SLOTS_PER_IMMUTABLE_FILE: u64 = 21_600; + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("{0}")] + Caller(#[source] Box), + #[error("reading snapshot.state_epochs")] + RetainedEpochs(#[source] dolos_snapshot::Error), + #[error("planning the publish")] + Planning(#[source] dolos_snapshot::Error), + #[error("replay failed ({replay}) and shutting down also failed ({shutdown})")] + ReplayAndShutdown { + replay: Box, + shutdown: Box, + }, + #[error("iterating the local immutable db: {0}")] + ImmutableDb(String), + #[error("reading block data: {0}")] + BlockData(String), + #[error("{what}: {reason}")] + Mithril { what: &'static str, reason: String }, + #[error("removing the consumed immutable file {name}")] + RemoveConsumed { + name: String, + #[source] + source: std::io::Error, + }, + #[error("state cursor at slot {slot} has no block hash, cannot walk the immutable db from it")] + UnanchoredCursor { slot: BlockSlot }, + #[error( + "the fetched immutable window {start:05}..={end:05} did not advance the downloaded files \ + (highest was {highest:?}, still {after:?}); mithril returned nothing new for the state \ + cursor at slot {cursor_slot} — the immutable dir holds {contents}" + )] + StalledWindow { + start: u64, + end: u64, + highest: Option, + after: Option, + cursor_slot: BlockSlot, + contents: String, + }, + #[error("the download window must be at least 1 immutable file")] + EmptyWindow, + #[error("backfill::run must be called outside an entered Tokio runtime")] + AsyncRuntimeContext, + #[error( + "interrupted by a shutdown signal; the stores are consistent and a rerun resumes here" + )] + Interrupted, +} + +impl Error { + pub fn caller(source: impl Into>) -> Self { + Self::Caller(source.into()) + } +} + +pub trait Workspace { + type Session: Session; + fn snapshot(&self) -> impl SnapshotSource + '_; + fn start(self, target_epoch: u64) -> Result; + fn finish(self) -> Result<(), Error>; +} + +pub trait Session { + fn committed_position(&self) -> Result, Error>; + fn import_blocks(&mut self, blocks: Vec) -> Result; + fn prune_history(&mut self) -> Result; + fn finish(self) -> Result<(), Error>; +} + +impl Workspace for ReplayWorkspace<'_> { + type Session = BulkReplaySession; + + fn snapshot(&self) -> impl SnapshotSource + '_ { + self.snapshot() + } + + fn start(self, target_epoch: u64) -> Result { + self.start(Some(target_epoch)).map_err(Error::caller) + } + + fn finish(self) -> Result<(), Error> { + self.finish().map_err(Error::caller) + } +} + +impl Session for BulkReplaySession { + fn committed_position(&self) -> Result, Error> { + self.committed_position().map_err(Error::caller) + } + + fn import_blocks(&mut self, blocks: Vec) -> Result { + self.import_blocks(blocks).map_err(Error::caller) + } + + fn prune_history(&mut self) -> Result { + self.prune_history().map_err(Error::caller) + } + + fn finish(self) -> Result<(), Error> { + self.finish().map_err(Error::caller) + } +} + +pub trait Replay { + fn round_started(&self) {} + fn reached(&self, slot: BlockSlot) { + let _ = slot; + } + fn round_finished(&self) {} +} + +impl Replay for () {} + +pub trait Publish { + fn announce(&self, plan: &Plan) -> Result<(), Error> { + let _ = plan; + Ok(()) + } + fn publish(&self, plan: &Plan, source: &dyn SnapshotSource) -> Result<(), Error>; +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Outcome { + UntilEpoch { sequence: u64 }, + UpToDate, +} + +enum Step { + Extend { target: u64, prune: bool }, + Done { sequence: u64 }, +} +enum Advance { + Boundary { cursor_slot: u64 }, + MithrilExhausted, + Cancelled, +} +enum Import { + Boundary, + Exhausted, + Cancelled, +} + +fn slots_per_immutable_file(genesis: &Genesis) -> u64 { + genesis + .shelley + .security_param + .map_or(FALLBACK_SLOTS_PER_IMMUTABLE_FILE, |k| { + u64::from(k) * SLOTS_PER_SECURITY_PARAM + }) +} + +fn target_epoch(cursor_epoch: Option) -> u64 { + cursor_epoch.map_or(1, |epoch| epoch + 1) +} + +fn resume_file(highest: Option, cursor_slot: Option, width: u64) -> Option { + highest.or_else(|| cursor_slot.map(|slot| (slot / width).saturating_sub(IMMUTABLE_FILE_MARGIN))) +} + +fn resume_lag(resume: Option, cursor_slot: Option, width: u64) -> Option { + let expected = (cursor_slot? / width).saturating_sub(IMMUTABLE_FILE_MARGIN); + match expected.saturating_sub(resume.unwrap_or(0)) { + 0 => None, + lag => Some(lag), + } +} + +fn next_window(resume: Option, window: u64, beacon: u64) -> Option<(Option, u64)> { + match resume { + Some(resume) if beacon <= resume => None, + Some(resume) => Some((Some(resume), beacon.min(resume.saturating_add(window)))), + None => Some((None, beacon.min(window))), + } +} + +fn fetch_advanced(before: Option, after: Option) -> bool { + after > before +} + +fn consumed_below(cursor_slot: u64, width: u64) -> u64 { + (cursor_slot / width).saturating_sub(IMMUTABLE_FILE_MARGIN) +} + +fn dir_contents(immutable_dir: &Path) -> String { + let Ok(entries) = std::fs::read_dir(immutable_dir) else { + return "an unreadable immutable dir".to_owned(); + }; + let mut numbers: Vec = entries + .flatten() + .filter_map(|entry| { + entry + .file_name() + .to_string_lossy() + .split('.') + .next()? + .parse() + .ok() + }) + .collect(); + numbers.sort_unstable(); + numbers.dedup(); + match (numbers.first(), numbers.last()) { + (Some(first), Some(last)) => { + format!("files {first:05}..={last:05} ({} of them)", numbers.len()) + } + _ => "no immutable files".to_owned(), + } +} + +fn cleanup_consumed(immutable_dir: &Path, cursor_slot: u64, width: u64) -> Result<(), Error> { + let threshold = consumed_below(cursor_slot, width); + if threshold == 0 { + return Ok(()); + } + let Ok(entries) = std::fs::read_dir(immutable_dir) else { + return Ok(()); + }; + let mut removed = 0; + for entry in entries.flatten() { + let name = entry.file_name().to_string_lossy().into_owned(); + let Some(number) = name.split('.').next().and_then(|s| s.parse::().ok()) else { + continue; + }; + if number < threshold { + std::fs::remove_file(entry.path()) + .map_err(|source| Error::RemoveConsumed { name, source })?; + removed += 1; + } + } + if removed > 0 { + info!(removed, threshold, "removed consumed immutable files"); + } + Ok(()) +} + +pub struct Driver<'a, W: Workspace> { + pub config: &'a RootConfig, + pub genesis: &'a Genesis, + pub mithril: &'a MithrilConfig, + pub download_dir: PathBuf, + pub window: u64, + pub until_epoch: Option, + pub skip_validation: bool, + pub runtime: tokio::runtime::Handle, + pub cancel: CancellationToken, + pub mithril_feedback: &'a dyn Fn() -> Option>, + pub replay: &'a dyn Replay, + pub open_workspace: &'a dyn Fn() -> Result, + pub publish: &'a dyn Publish, +} + +#[derive(Debug, Clone)] +pub struct Options { + pub repository: dolos_snapshot::registry::Repository, + pub insecure: bool, + pub scratch_dir: Option, + pub concurrency: Option, + pub verify_carried: bool, + pub download_dir: Option, + pub window: u64, + pub until_epoch: Option, + pub skip_validation: bool, +} + +fn require_synchronous_context() -> Result<(), Error> { + if tokio::runtime::Handle::try_current().is_ok() { + Err(Error::AsyncRuntimeContext) + } else { + Ok(()) + } +} + +/// Run backfill on a synchronous process thread. +/// +/// OCI publication stays on this thread while a private Tokio runtime drives +/// Mithril. Calling this entry point from an entered Tokio runtime is rejected. +pub fn run( + config: &RootConfig, + genesis: &Genesis, + options: &Options, + cancel: CancellationToken, + observer: &stelae::progress::Observer, +) -> Result { + require_synchronous_context()?; + let mithril = config.mithril.as_ref().ok_or_else(|| { + Error::caller(std::io::Error::new( + std::io::ErrorKind::InvalidInput, + "missing mithril config", + )) + })?; + let download_dir = options + .download_dir + .clone() + .unwrap_or_else(|| config.storage.path.join("mithril")); + std::fs::create_dir_all(&download_dir).map_err(Error::caller)?; + let runtime = tokio::runtime::Runtime::new().map_err(Error::caller)?; + let settings = RepositoryPublish { + repo: &options.repository, + insecure: options.insecure, + scratch_dir: options.scratch_dir.as_deref(), + rebuild: false, + tuning: dolos_snapshot::registry::Tuning { + concurrency: options.concurrency, + verify_adopted: options.verify_carried, + }, + }; + let publisher = BackfillPublisher { + config, + settings, + observer, + }; + let genesis = Arc::new(genesis.clone()); + let driver = Driver:: { + config, + genesis: &genesis, + mithril, + download_dir, + window: options.window, + until_epoch: options.until_epoch, + skip_validation: options.skip_validation, + runtime: runtime.handle().clone(), + cancel, + mithril_feedback: &|| None, + replay: &(), + open_workspace: &|| ReplayWorkspace::open(config, genesis.clone()).map_err(Error::caller), + publish: &publisher, + }; + driver.run() +} + +fn finish_both(work: Result, finish: Result<(), Error>) -> Result { + match (work, finish) { + (Ok(value), Ok(())) => Ok(value), + (Err(error), Ok(())) | (Ok(_), Err(error)) => Err(error), + (Err(replay), Err(shutdown)) => Err(Error::ReplayAndShutdown { + replay: Box::new(replay), + shutdown: Box::new(shutdown), + }), + } +} + +impl Driver<'_, W> { + fn immutable_dir(&self) -> PathBuf { + self.download_dir.join("immutable") + } + fn aborted(&self) -> bool { + self.cancel.is_cancelled() + } + + pub fn run(&self) -> Result { + if self.window == 0 { + return Err(Error::EmptyWindow); + } + let width = slots_per_immutable_file(self.genesis); + let immutable_dir = self.immutable_dir(); + info!( + slots_per_immutable_file = width, + "derived immutable chunk size from genesis" + ); + + loop { + if self.aborted() { + return Err(Error::Interrupted); + } + let (target, prune) = match self.publish_pending()? { + Step::Done { sequence } => return Ok(Outcome::UntilEpoch { sequence }), + Step::Extend { target, prune } => (target, prune), + }; + match self.extend(target, prune, width)? { + Advance::Boundary { cursor_slot } => { + cleanup_consumed(&immutable_dir, cursor_slot, width)? + } + Advance::MithrilExhausted => return Ok(Outcome::UpToDate), + Advance::Cancelled => return Err(Error::Interrupted), + } + } + } + + fn publish_pending(&self) -> Result { + let workspace = (self.open_workspace)()?; + let result = self.plan_pending(&workspace.snapshot()); + finish_both(result, workspace.finish()) + } + + fn plan_pending(&self, source: &dyn SnapshotSource) -> Result { + let Some(cursor) = source.committed_position().map_err(Error::Planning)? else { + return Ok(Step::Extend { + target: target_epoch(None), + prune: false, + }); + }; + let epoch = source + .epoch() + .map_err(Error::Planning)? + .ok_or(Error::UnanchoredCursor { + slot: cursor.slot(), + })?; + if epoch == 0 { + return Ok(Step::Extend { + target: target_epoch(Some(epoch)), + prune: false, + }); + } + let retained = planning::retained_epochs(self.config).map_err(Error::RetainedEpochs)?; + let plan = source + .plan(u64::from(self.genesis.network_magic()), retained) + .map_err(Error::Planning)?; + self.publish.announce(&plan)?; + stelae_driver::retry::transient( + "publishing the pending sequence", + &|| self.aborted(), + || self.publish.publish(&plan, source), + )?; + if self.until_epoch.is_some_and(|until| plan.sequence >= until) { + return Ok(Step::Done { + sequence: plan.sequence, + }); + } + Ok(Step::Extend { + target: target_epoch(Some(epoch)), + prune: true, + }) + } + + fn extend(&self, target: u64, prune: bool, width: u64) -> Result { + let workspace = (self.open_workspace)()?; + let mut session = workspace.start(target)?; + let result = self.advance_session(&mut session, prune, width); + finish_both(result, session.finish()) + } + + fn advance_session( + &self, + session: &mut W::Session, + prune: bool, + width: u64, + ) -> Result { + let immutable_dir = self.immutable_dir(); + if prune { + let rounds = session.prune_history()?; + info!(rounds, "housekeeping drained after publication"); + } + self.replay.round_started(); + let result = self.advance_loop(session, &immutable_dir, width); + self.replay.round_finished(); + result + } + + fn advance_loop( + &self, + session: &mut W::Session, + immutable_dir: &Path, + width: u64, + ) -> Result { + loop { + if self.aborted() { + return Ok(Advance::Cancelled); + } + match self.import_available(session, immutable_dir)? { + Import::Boundary => { + let cursor_slot = session + .committed_position()? + .map(|point| point.slot()) + .unwrap_or_default(); + return Ok(Advance::Boundary { cursor_slot }); + } + Import::Cancelled => return Ok(Advance::Cancelled), + Import::Exhausted => {} + } + + let Some(beacon) = stelae_driver::retry::transient( + "listing mithril snapshots", + &|| self.aborted(), + || { + self.runtime.block_on(async { + tokio::select! { + result = mithril::latest_immutable_file(self.mithril) => result.map(Some), + _ = self.cancel.cancelled() => Ok(None), + } + }) + }, + ) + .map_err(|error| Error::Mithril { + what: "listing mithril snapshots", + reason: error.to_string(), + })? + else { + return Ok(Advance::Cancelled); + }; + + let highest = mithril::highest_existing_immutable(immutable_dir); + let cursor_slot = session.committed_position()?.map(|point| point.slot()); + let resume = resume_file(highest, cursor_slot, width); + if let Some(lag) = + resume_lag(resume, cursor_slot, width).filter(|lag| *lag > self.window) + { + warn!( + lag, + ?resume, + width, + "immutable download resumes more than one window behind the cursor" + ); + } + let Some((start, end)) = next_window(resume, self.window, beacon) else { + return Ok(Advance::MithrilExhausted); + }; + let fetch = mithril::Fetch { + download_dir: &self.download_dir, + skip_validation: self.skip_validation, + download_start: start, + download_end: Some(end), + }; + let fetched = stelae_driver::retry::transient( + "fetching a mithril immutable window", + &|| self.aborted(), + || self.runtime.block_on(async { + tokio::select! { + result = mithril::fetch_snapshot(&fetch, self.mithril, (self.mithril_feedback)()) => result.map(Some), + _ = self.cancel.cancelled() => Ok(None), + } + }), + ).map_err(|error| Error::Mithril { + what: "fetching a mithril immutable window", + reason: error.to_string(), + })?; + if fetched.is_none() { + return Ok(Advance::Cancelled); + } + let after = mithril::highest_existing_immutable(immutable_dir); + if !fetch_advanced(highest, after) { + return Err(Error::StalledWindow { + start: start.unwrap_or(0), + end, + highest, + after, + cursor_slot: cursor_slot.unwrap_or_default(), + contents: dir_contents(immutable_dir), + }); + } + } + } + + fn import_available( + &self, + session: &mut W::Session, + immutable_dir: &Path, + ) -> Result { + use pallas::network::miniprotocols::Point; + + if !immutable_dir.is_dir() || mithril::highest_existing_immutable(immutable_dir).is_none() { + return Ok(Import::Exhausted); + } + let cursor = session.committed_position()?; + let point: Point = match cursor { + None => Point::Origin, + Some(cursor) => { + let slot = cursor.slot(); + cursor + .try_into() + .map_err(|_| Error::UnanchoredCursor { slot })? + } + }; + let mut blocks = pallas::interop::hardano::storage::immutable::read_blocks_from_point( + immutable_dir, + point.clone(), + ) + .map_err(|error| Error::ImmutableDb(error.to_string()))?; + if point != Point::Origin { + blocks.next(); + } + for batch in blocks.chunks(IMPORT_CHUNK).into_iter() { + let batch: Vec<_> = batch + .try_collect() + .map_err(|error| Error::BlockData(error.to_string()))?; + let progress = session.import_blocks(batch.into_iter().map(Arc::new).collect())?; + self.replay.reached(progress.position().slot()); + if progress.is_boundary() { + return Ok(Import::Boundary); + } + if self.aborted() { + return Ok(Import::Cancelled); + } + } + Ok(Import::Exhausted) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + const MAINNET_WIDTH: u64 = 21_600; + const PREVIEW_CURSOR: u64 = 22_118_504; + + #[test] + fn targets_follow_the_cursor() { + assert_eq!(target_epoch(None), 1); + assert_eq!(target_epoch(Some(0)), 1); + assert_eq!(target_epoch(Some(499)), 500); + } + + #[test] + fn chunk_width_is_network_specific() { + use dolos_cardano::include; + assert_eq!( + slots_per_immutable_file(&include::mainnet::load()), + MAINNET_WIDTH + ); + assert_eq!( + slots_per_immutable_file(&include::preprod::load()), + MAINNET_WIDTH + ); + assert_eq!(slots_per_immutable_file(&include::preview::load()), 4_320); + } + + #[test] + fn cold_start_resumes_from_cursor_margin() { + assert_eq!(resume_file(None, Some(PREVIEW_CURSOR), 4_320), Some(5_118)); + assert_eq!( + resume_file(None, Some(MAINNET_WIDTH), MAINNET_WIDTH), + Some(0) + ); + assert_eq!(resume_file(None, None, MAINNET_WIDTH), None); + assert_eq!( + resume_file(Some(120), Some(MAINNET_WIDTH * 6000), MAINNET_WIDTH), + Some(120) + ); + } + + #[test] + fn resume_lag_reports_only_distance_behind_margin() { + assert_eq!(resume_lag(Some(5_118), Some(PREVIEW_CURSOR), 4_320), None); + assert_eq!( + resume_lag(Some(1_022), Some(PREVIEW_CURSOR), 4_320), + Some(4_096) + ); + assert_eq!(resume_lag(Some(9_000), Some(PREVIEW_CURSOR), 4_320), None); + } + + #[test] + fn window_clamps_and_refetches_resume_file() { + assert_eq!(next_window(None, 40, 1_000), Some((None, 40))); + assert_eq!(next_window(Some(100), 40, 1_000), Some((Some(100), 140))); + assert_eq!(next_window(Some(990), 40, 1_000), Some((Some(990), 1_000))); + assert_eq!(next_window(Some(1_000), 40, 1_000), None); + } + + #[test] + fn only_a_new_highest_file_counts_as_fetch_progress() { + assert!(fetch_advanced(None, Some(0))); + assert!(fetch_advanced(Some(5), Some(6))); + assert!(!fetch_advanced(Some(5), Some(5))); + assert!(!fetch_advanced(None, None)); + } + + #[test] + fn cleanup_threshold_keeps_two_files_of_margin() { + assert_eq!(consumed_below(0, MAINNET_WIDTH), 0); + assert_eq!(consumed_below(MAINNET_WIDTH * 3, MAINNET_WIDTH), 1); + assert_eq!(consumed_below(MAINNET_WIDTH * 10 + 5, MAINNET_WIDTH), 8); + } + + #[test] + fn cleanup_removes_only_consumed_numbered_files() { + let dir = tempfile::tempdir().unwrap(); + for n in 0..6u64 { + for ext in ["chunk", "primary", "secondary"] { + std::fs::write(dir.path().join(format!("{n:05}.{ext}")), []).unwrap(); + } + } + std::fs::write(dir.path().join("lock"), []).unwrap(); + cleanup_consumed(dir.path(), MAINNET_WIDTH * 5, MAINNET_WIDTH).unwrap(); + let mut remaining: Vec<_> = std::fs::read_dir(dir.path()) + .unwrap() + .flatten() + .map(|entry| entry.file_name().to_string_lossy().into_owned()) + .collect(); + remaining.sort(); + assert_eq!( + remaining, + [ + "00003.chunk", + "00003.primary", + "00003.secondary", + "00004.chunk", + "00004.primary", + "00004.secondary", + "00005.chunk", + "00005.primary", + "00005.secondary", + "lock", + ] + ); + } + + #[test] + fn simultaneous_work_and_finish_failures_are_preserved() { + let error = + finish_both::<()>(Err(Error::Interrupted), Err(Error::EmptyWindow)).unwrap_err(); + assert!(matches!(error, Error::ReplayAndShutdown { .. })); + } + + #[test] + fn synchronous_entrypoint_refuses_an_entered_tokio_runtime() { + assert!(require_synchronous_context().is_ok()); + let runtime = tokio::runtime::Builder::new_current_thread() + .build() + .unwrap(); + runtime.block_on(async { + assert!(matches!( + require_synchronous_context(), + Err(Error::AsyncRuntimeContext) + )); + }); + } +} diff --git a/stelae-cardano/src/initialize.rs b/stelae-cardano/src/initialize.rs new file mode 100644 index 0000000..1757784 --- /dev/null +++ b/stelae-cardano/src/initialize.rs @@ -0,0 +1,307 @@ +//! Fail-closed cold-start initialization for the publisher host. + +use std::{ + path::{Component, Path, PathBuf}, + sync::Arc, +}; + +use dolos::engine::ReplayWorkspace; +use dolos_core::{seed_wal_from_state, Genesis, WalSeed}; +use dolos_snapshot::{ + facade::{self, Point, RestoreInput, SnapshotRepository}, + node, + registry::{self, Repository}, + restore::{Restoring, Source, Target}, +}; +use serde::{Deserialize, Serialize}; +use stelae::progress::Observer; + +const MARKER_FILE: &str = ".stelae-publisher-initialized.json"; + +type AnyError = Box; + +#[derive(Debug, Clone)] +pub struct Options { + pub source: Source, + pub point: Point, + pub insecure: bool, + pub scratch_dir: Option, + pub skip_space_check: bool, + pub resume: bool, + pub allow_genesis: bool, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Outcome { + Existing, + Restored { sequence: u64 }, + Genesis, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] +struct Marker { + schema: u8, + storage_path: PathBuf, + network_magic: u64, + source: String, + mode: String, +} + +fn source_name(source: &Source) -> String { + match source { + Source::Dir(path) => format!("file://{}", path.display()), + Source::Repo(repository) => repository.to_string(), + } +} + +fn validate_storage_path(path: &Path) -> Result<(), AnyError> { + if !path.is_absolute() { + return Err(format!("storage path {} is not absolute", path.display()).into()); + } + if path.parent().is_none() || path.file_name().is_none() { + return Err("refusing to initialize or clear a filesystem root".into()); + } + if path + .components() + .any(|part| matches!(part, Component::ParentDir)) + { + return Err(format!("storage path {} contains `..`", path.display()).into()); + } + Ok(()) +} + +fn expected_marker( + config: &crate::RootConfig, + magic: u64, + options: &Options, + mode: &str, +) -> Marker { + Marker { + schema: 1, + storage_path: config.storage.path.clone(), + network_magic: magic, + source: source_name(&options.source), + mode: mode.to_owned(), + } +} + +fn write_marker(path: &Path, marker: &Marker) -> Result<(), AnyError> { + let target = path.join(MARKER_FILE); + let temporary = path.join(format!("{MARKER_FILE}.tmp")); + let bytes = serde_json::to_vec_pretty(marker)?; + std::fs::write(&temporary, bytes)?; + std::fs::rename(temporary, target)?; + Ok(()) +} + +fn read_marker(path: &Path) -> Result, AnyError> { + let path = path.join(MARKER_FILE); + match std::fs::read(path) { + Ok(bytes) => Ok(Some(serde_json::from_slice(&bytes)?)), + Err(error) if error.kind() == std::io::ErrorKind::NotFound => Ok(None), + Err(error) => Err(error.into()), + } +} + +fn close_restore_stores( + archive: &dolos::adapters::ArchiveStoreBackend, + state: &dolos::adapters::StateStoreBackend, +) -> Result<(), AnyError> { + archive.shutdown()?; + state.shutdown()?; + Ok(()) +} + +fn seed_wal(config: &crate::RootConfig) -> Result<(), AnyError> { + let state = dolos::storage::open_state_store(config)?; + let wal: dolos::storage::WalStoreBackend = + dolos::storage::open_wal_store(config)?; + match seed_wal_from_state(&state, &wal)? { + WalSeed::NoCursor => return Err("restore completed without a state cursor".into()), + WalSeed::Seeded(_) => {} + } + state.shutdown()?; + wal.shutdown()?; + Ok(()) +} + +fn restore( + config: &crate::RootConfig, + genesis: &Genesis, + options: &Options, + observer: &Observer, +) -> Result { + let archive = dolos::storage::open_archive_store(config)?; + let state = dolos::storage::open_state_store(config)?; + let restoring = Restoring { + network_magic: u64::from(genesis.network_magic()), + max_history: config.sync.max_history, + storage_path: &config.storage.path, + resume: options.resume, + skip_space_check: options.skip_space_check, + }; + let target = Target::new(&archive, &state); + + let outcome = match &options.source { + Source::Dir(path) => facade::restore( + RestoreInput::Directory(path), + restoring, + target, + Some(observer), + ), + Source::Repo(repository) => { + let auth = node::registry_auth(&config.stelae)?; + let scratch = node::scratch_dir(&config.storage, options.scratch_dir.as_deref()); + let repository = SnapshotRepository::open( + repository, + options.insecure, + auth, + scratch, + registry::Tuning::default(), + )?; + facade::restore( + RestoreInput::Repository { + repository: &repository, + point: options.point, + }, + restoring, + target, + Some(observer), + ) + } + }; + + let close = close_restore_stores(&archive, &state); + let outcome = outcome.map_err(|error| -> AnyError { Box::new(error) }); + let outcome = match (outcome, close) { + (Ok(value), Ok(())) => value, + (Err(error), Ok(())) | (Ok(_), Err(error)) => return Err(error), + (Err(operation), Err(close)) => { + return Err(format!( + "restore failed ({operation}); closing stores also failed ({close})" + ) + .into()) + } + }; + drop(archive); + drop(state); + seed_wal(config)?; + + // Prove the restored/reconciled stores can be opened through the engine + // facade before the marker makes this initialization authoritative. + ReplayWorkspace::open(config, Arc::new(genesis.clone()))?.finish()?; + Ok(outcome.plan.sequence) +} + +/// Initialize empty publisher storage from its own latest stele. +/// +/// A failed restore clears partial stores and fails. Genesis is selected only +/// when the caller explicitly opts in. An existing initialized dataset is +/// never cleared or silently replaced. +pub fn run( + config: &crate::RootConfig, + genesis: &Genesis, + options: &Options, + observer: &Observer, +) -> Result { + validate_storage_path(&config.storage.path)?; + std::fs::create_dir_all(&config.storage.path)?; + + if dolos::storage::has_existing_data(config)? { + if let Some(marker) = read_marker(&config.storage.path)? { + let expected = expected_marker( + config, + u64::from(genesis.network_magic()), + options, + marker.mode.as_str(), + ); + if marker != expected || !matches!(marker.mode.as_str(), "restore" | "genesis") { + return Err(format!( + "initialization marker does not match configured storage/source contract: {marker:?}" + ).into()); + } + } + return Ok(Outcome::Existing); + } + + if let Some(marker) = read_marker(&config.storage.path)? { + let expected = expected_marker( + config, + u64::from(genesis.network_magic()), + options, + marker.mode.as_str(), + ); + if marker == expected && marker.mode == "genesis" && options.allow_genesis { + return Ok(Outcome::Genesis); + } + return Err("initialization marker exists but storage has no committed cursor".into()); + } + + match restore(config, genesis, options, observer) { + Ok(sequence) => { + let marker = expected_marker( + config, + u64::from(genesis.network_magic()), + options, + "restore", + ); + write_marker(&config.storage.path, &marker)?; + Ok(Outcome::Restored { sequence }) + } + Err(error) => { + dolos::storage::clear_storage(&config.storage.path)?; + if !options.allow_genesis { + return Err(format!( + "latest stele restore failed; refusing genesis fallback: {error}" + ) + .into()); + } + let marker = expected_marker( + config, + u64::from(genesis.network_magic()), + options, + "genesis", + ); + write_marker(&config.storage.path, &marker)?; + Ok(Outcome::Genesis) + } + } +} + +/// Parse the source type without exposing Dolos's profile module to the host. +pub fn parse_source(raw: &str) -> Result { + raw.parse() +} + +/// Parse a repository using the wire-level `oci://` identity. +pub fn parse_repository(raw: &str) -> Result { + raw.parse() + .map_err(|error: stelae::Error| error.to_string()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn cleanup_targets_must_be_absolute_and_below_a_root() { + assert!(validate_storage_path(Path::new("relative/db")).is_err()); + assert!(validate_storage_path(Path::new("/")).is_err()); + assert!(validate_storage_path(Path::new("/data/../db")).is_err()); + assert!(validate_storage_path(Path::new("/data/db")).is_ok()); + } + + #[test] + fn marker_roundtrip_preserves_the_storage_contract() { + let dir = tempfile::tempdir().unwrap(); + let marker = Marker { + schema: 1, + storage_path: dir.path().join("db"), + network_magic: 2, + source: "oci://registry.invalid/cardano/preview".to_owned(), + mode: "restore".to_owned(), + }; + write_marker(dir.path(), &marker).unwrap(); + assert_eq!(read_marker(dir.path()).unwrap(), Some(marker)); + } +} diff --git a/stelae-cardano/src/lib.rs b/stelae-cardano/src/lib.rs new file mode 100644 index 0000000..daae54a --- /dev/null +++ b/stelae-cardano/src/lib.rs @@ -0,0 +1,39 @@ +//! The Cardano integration for the Stelae publisher. +//! +//! This crate owns application orchestration. It uses Dolos's supported +//! headless engine and snapshot facades, but does not invoke a Dolos binary or +//! its legacy backfill driver. The protocol and generic lifecycle remain in +//! `stelae` and `stelae-driver`, which have no Cardano dependency. + +pub mod backfill; +pub mod initialize; +pub mod publisher; + +pub use dolos::core::{config::RootConfig, Genesis}; +pub use dolos_snapshot::{ + facade::{Point, Repository, RestoreInput, Selection, SnapshotRepository, SnapshotSource}, + planning::EpochRange, + restore::Source as RestoreSource, +}; + +/// The exact Dolos revision accepted by publisher-pipeline step 2. +pub const DOLOS_REVISION: &str = "1ae4e91c18a9e1456a3612af402d7b9b97546d30"; + +#[cfg(test)] +mod dependency_identity { + use super::*; + + fn accepts_host_profile() {} + + #[test] + fn dolos_profile_implements_the_workspace_driver_trait() { + accepts_host_profile::(); + } + + #[test] + fn facade_registry_types_are_the_protocol_types_used_by_this_workspace() { + fn accepts_repository(_: &stelae::oci::Repository) {} + let repository: Repository = "oci://example.invalid/cardano/preview".parse().unwrap(); + accepts_repository(&repository); + } +} diff --git a/stelae-cardano/src/publisher.rs b/stelae-cardano/src/publisher.rs new file mode 100644 index 0000000..aa6b291 --- /dev/null +++ b/stelae-cardano/src/publisher.rs @@ -0,0 +1,332 @@ +//! Stelae-owned policy for publishing the Dolos Cardano profile. + +use std::path::{Path, PathBuf}; + +use dolos_core::config::RootConfig; +use dolos_snapshot::{ + export::Plan, + facade::SnapshotSource, + node, + planning::{self, PlanReport}, + registry::{self, Auth, Preview, Published, Repository, Tuning}, +}; +use stelae::progress::Observer; +use stelae_driver::Standing; + +use crate::backfill; + +/// Resolved repository publication settings. +pub struct RepositoryPublish<'a> { + pub repo: &'a Repository, + pub insecure: bool, + pub scratch_dir: Option<&'a Path>, + pub rebuild: bool, + pub tuning: Tuning, +} + +/// The policy decision made from the repository's current standing. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Next { + First, + After { latest: u64 }, + Nothing(String), +} + +impl Next { + pub fn read( + standing: Standing, + sequence: u64, + require_new: bool, + ) -> Result { + match standing { + Standing::Empty => Ok(Self::First), + Standing::Next { latest } => Ok(Self::After { latest }), + Standing::UpToDate { latest } => { + let message = format!( + "nothing to publish: this repository is at sequence {latest} and this node is at sequence {sequence}" + ); + if require_new { + Err(dolos_snapshot::Error::NothingToPublish(message)) + } else { + Ok(Self::Nothing(message)) + } + } + Standing::Ahead { latest, distance } => Err(dolos_snapshot::Error::PublishWouldGap { + latest, + sequence, + distance, + }), + } + } +} + +/// An opened repository plus the journal and reuse policy of this publisher. +pub struct Publisher { + inner: dolos_snapshot::publisher::Publisher, +} + +impl Publisher { + pub fn open( + config: &RootConfig, + publish: &RepositoryPublish<'_>, + auth: Auth, + ) -> Result { + let scratch = node::scratch_dir(&config.storage, publish.scratch_dir); + Self::open_explicit( + publish.repo, + publish.insecure, + auth, + scratch, + registry::record_path_in(&config.storage.path), + publish.rebuild, + publish.tuning, + ) + } + + #[allow(clippy::too_many_arguments)] + pub fn open_explicit( + repository: &Repository, + insecure: bool, + auth: Auth, + scratch_dir: PathBuf, + record_path: PathBuf, + rebuild: bool, + tuning: Tuning, + ) -> Result { + let inner = dolos_snapshot::publisher::Publisher::open_explicit( + repository, + insecure, + auth, + scratch_dir, + record_path, + rebuild, + tuning, + )?; + + Ok(Self { inner }) + } + + pub fn standing(&self, plan: &Plan) -> Result { + self.inner.standing(plan) + } + + pub fn preflight(&self) -> Result<(), dolos_snapshot::Error> { + self.inner.preflight() + } + + pub fn preview( + &self, + plan: &Plan, + source: &dyn SnapshotSource, + ) -> Result { + source.preview(&self.inner, plan) + } + + pub fn publish( + &self, + plan: &Plan, + source: &dyn SnapshotSource, + observer: &Observer, + ) -> Result { + source.publish(&self.inner, plan, observer) + } +} + +pub struct BackfillPublisher<'a> { + pub config: &'a RootConfig, + pub settings: RepositoryPublish<'a>, + pub observer: &'a Observer, +} + +impl backfill::Publish for BackfillPublisher<'_> { + fn announce(&self, plan: &Plan) -> Result<(), backfill::Error> { + let report = PlanReport::read(plan).map_err(backfill::Error::caller)?; + tracing::info!( + sequence = report.sequence, + cursor = %report.cursor, + network = %report.network, + "publishing pending boundary" + ); + Ok(()) + } + + fn publish(&self, plan: &Plan, source: &dyn SnapshotSource) -> Result<(), backfill::Error> { + let auth = node::registry_auth(&self.config.stelae).map_err(backfill::Error::caller)?; + let publisher = + Publisher::open(self.config, &self.settings, auth).map_err(backfill::Error::caller)?; + let standing = publisher.standing(plan).map_err(backfill::Error::caller)?; + match Next::read(standing, plan.sequence, false).map_err(backfill::Error::caller)? { + Next::Nothing(message) => { + tracing::info!(%message); + return Ok(()); + } + Next::First | Next::After { .. } => {} + } + publisher.preflight().map_err(backfill::Error::caller)?; + let published = publisher + .publish(plan, source, self.observer) + .map_err(backfill::Error::caller)?; + tracing::info!( + sequence = plan.sequence, + identity = %published.identity, + built = published.layers_built, + reused = published.layers_reused, + "published pending boundary" + ); + Ok(()) + } +} + +#[derive(Debug, Clone)] +pub enum Destination { + Directory(PathBuf), + Repository { + repository: Repository, + insecure: bool, + scratch_dir: Option, + rebuild: bool, + concurrency: Option, + verify_carried: bool, + require_new: bool, + }, +} + +#[derive(Debug)] +pub enum PublishOutcome { + DryRun { + sequence: u64, + }, + Nothing(String), + Directory { + sequence: u64, + identity: String, + layers: usize, + }, + Repository { + sequence: u64, + identity: String, + built: usize, + reused: usize, + }, +} + +pub fn publish_once( + config: &RootConfig, + genesis: &dolos_core::Genesis, + selection: dolos_snapshot::facade::Selection, + destination: Destination, + dry_run: bool, + observer: &Observer, +) -> Result<(PlanReport, PublishOutcome), Box> { + let workspace = + dolos::engine::ReplayWorkspace::open(config, std::sync::Arc::new(genesis.clone()))?; + let result = (|| { + let snapshot = workspace.snapshot(); + let retained = planning::retained_epochs(config)?; + let plan = + snapshot.selected_plan(u64::from(genesis.network_magic()), retained, selection)?; + let report = PlanReport::read(&plan)?; + let outcome = match destination { + Destination::Directory(path) => { + if dry_run { + PublishOutcome::DryRun { + sequence: plan.sequence, + } + } else { + let inscription = snapshot.publish_directory(&path, &plan, observer)?; + PublishOutcome::Directory { + sequence: plan.sequence, + identity: inscription.digest()?.to_string(), + layers: inscription.layers.len(), + } + } + } + Destination::Repository { + repository, + insecure, + scratch_dir, + rebuild, + concurrency, + verify_carried, + require_new, + } => { + let settings = RepositoryPublish { + repo: &repository, + insecure, + scratch_dir: scratch_dir.as_deref(), + rebuild, + tuning: Tuning { + concurrency, + verify_adopted: verify_carried, + }, + }; + let auth = node::registry_auth(&config.stelae)?; + let publisher = Publisher::open(config, &settings, auth)?; + let standing = publisher.standing(&plan)?; + match Next::read(standing, plan.sequence, require_new)? { + Next::Nothing(message) => PublishOutcome::Nothing(message), + Next::First | Next::After { .. } => { + publisher.preflight()?; + if dry_run { + let _preview = publisher.preview(&plan, &snapshot)?; + PublishOutcome::DryRun { + sequence: plan.sequence, + } + } else { + let published = publisher.publish(&plan, &snapshot, observer)?; + PublishOutcome::Repository { + sequence: plan.sequence, + identity: published.identity.to_string(), + built: published.layers_built, + reused: published.layers_reused, + } + } + } + } + } + }; + Ok::<_, Box>((report, outcome)) + })(); + let finish = workspace + .finish() + .map_err(|error| -> Box { Box::new(error) }); + match (result, finish) { + (Ok(value), Ok(())) => Ok(value), + (Err(error), Ok(())) | (Ok(_), Err(error)) => Err(error), + (Err(operation), Err(finish)) => Err(format!( + "publication failed ({operation}); closing stores also failed ({finish})" + ) + .into()), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn repository_standing_maps_to_first_next_noop_and_refusal() { + assert_eq!( + Next::read(Standing::Empty, 500, false).unwrap(), + Next::First + ); + assert_eq!( + Next::read(Standing::Next { latest: 499 }, 500, false).unwrap(), + Next::After { latest: 499 } + ); + assert!(matches!( + Next::read(Standing::UpToDate { latest: 500 }, 500, false).unwrap(), + Next::Nothing(_) + )); + assert!(Next::read(Standing::UpToDate { latest: 500 }, 500, true).is_err()); + assert!(Next::read( + Standing::Ahead { + latest: 497, + distance: 3, + }, + 500, + false, + ) + .is_err()); + } +} diff --git a/stelae-cardano/tests/host.rs b/stelae-cardano/tests/host.rs new file mode 100644 index 0000000..bb3de44 --- /dev/null +++ b/stelae-cardano/tests/host.rs @@ -0,0 +1,233 @@ +use std::{cell::Cell, io, sync::Arc}; + +use dolos::engine::{BulkReplaySession, ReplayWorkspace}; +use dolos_core::{ + config::{ChainConfig, MithrilConfig, RootConfig}, + ChainPoint, +}; +use dolos_snapshot::{export::Plan, source::SnapshotSource}; +use dolos_testing::{ + blocks::make_conway_block_with_prev, + synthetic::{build_synthetic_blocks, SyntheticBlockConfig}, +}; +use stelae::progress::Observer; +use stelae_cardano::{ + backfill::{self, Driver}, + initialize, + publisher::{publish_once, Destination, PublishOutcome}, + Point, RestoreSource, Selection, +}; + +struct Node { + root: tempfile::TempDir, + config: RootConfig, +} + +impl Node { + fn new() -> Self { + let root = tempfile::tempdir().unwrap(); + let document = format!( + r#" + [upstream] + peer_address = "unused.invalid:3001" + + [storage] + version = "v4" + path = {} + + [genesis] + byron_path = "unused" + shelley_path = "unused" + alonzo_path = "unused" + conway_path = "unused" + force_protocol = 6 + + [chain] + type = "cardano" + magic = 2 + is_testnet = true + "#, + toml::Value::String(root.path().join("data").display().to_string()), + ); + Self { + root, + config: toml::from_str(&document).unwrap(), + } + } +} + +#[test] +fn a_bounded_fixture_publishes_to_a_directory_through_the_new_host() { + let mut node = Node::new(); + let genesis = dolos_cardano::include::preview::load(); + let (blocks, _, chain) = build_synthetic_blocks(SyntheticBlockConfig { + block_count: 3, + txs_per_block: 2, + slot: 100, + ..Default::default() + }); + node.config.chain = ChainConfig::Cardano(chain); + + let mut session = + BulkReplaySession::open(&node.config, Arc::new(genesis.clone()), None).unwrap(); + session.import_blocks(blocks).unwrap(); + session.finish().unwrap(); + + let destination = node.root.path().join("stele"); + let (_, outcome) = publish_once( + &node.config, + &genesis, + Selection::default(), + Destination::Directory(destination.clone()), + false, + &Observer::silent(), + ) + .unwrap(); + + let PublishOutcome::Directory { layers, .. } = outcome else { + panic!("fixture was not published to the directory"); + }; + assert!(layers > 0); + assert!(destination.join("inscription.json").is_file()); + + let restored = Node::new(); + let outcome = initialize::run( + &restored.config, + &genesis, + &initialize::Options { + source: RestoreSource::Dir(destination), + point: Point::Latest, + insecure: false, + scratch_dir: None, + skip_space_check: false, + resume: false, + allow_genesis: false, + }, + &Observer::silent(), + ) + .unwrap(); + assert!(matches!(outcome, initialize::Outcome::Restored { .. })); + assert!(dolos::storage::has_existing_data(&restored.config).unwrap()); +} + +#[test] +fn relocated_backfill_publishes_a_pending_boundary_before_any_advance() { + struct Publisher { + expected: ChainPoint, + fail: bool, + called: Cell, + cancel: tokio_util::sync::CancellationToken, + } + + impl backfill::Publish for Publisher { + fn publish(&self, plan: &Plan, source: &dyn SnapshotSource) -> Result<(), backfill::Error> { + assert_eq!(plan.sequence, 1); + assert_eq!( + source.committed_position().unwrap(), + Some(self.expected.clone()) + ); + self.called.set(true); + if self.fail { + self.cancel.cancel(); + Err(backfill::Error::caller(io::Error::other( + "publication failed", + ))) + } else { + Ok(()) + } + } + } + + let mut node = Node::new(); + let mut genesis = dolos_cardano::include::preview::load(); + genesis.force_protocol = Some(9); + let epoch_one = genesis.shelley.epoch_length.unwrap() as u64; + let genesis = Arc::new(genesis); + let (before, block_before) = make_conway_block_with_prev(epoch_one - 1, None, 1); + let (boundary, block_boundary) = make_conway_block_with_prev(epoch_one, before.hash(), 2); + node.config.chain = ChainConfig::Cardano(Default::default()); + let mut session = BulkReplaySession::open(&node.config, genesis.clone(), Some(1)).unwrap(); + session + .import_blocks(vec![block_before, block_boundary]) + .unwrap(); + session.finish().unwrap(); + + let mithril = MithrilConfig { + aggregator: "http://unused.invalid".to_owned(), + genesis_key: String::new(), + ancillary_key: None, + }; + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap(); + + for fail in [true, false] { + let cancel = tokio_util::sync::CancellationToken::new(); + let publish = Publisher { + expected: boundary.clone(), + fail, + called: Cell::new(false), + cancel: cancel.clone(), + }; + let open_workspace = || { + ReplayWorkspace::open(&node.config, genesis.clone()).map_err(backfill::Error::caller) + }; + let driver = Driver { + config: &node.config, + genesis: &genesis, + mithril: &mithril, + download_dir: node.root.path().join("unused"), + window: 1, + until_epoch: Some(1), + skip_validation: false, + runtime: runtime.handle().clone(), + cancel, + mithril_feedback: &|| None, + replay: &(), + open_workspace: &open_workspace, + publish: &publish, + }; + assert_eq!(driver.run().is_err(), fail); + assert!(publish.called.get()); + + let workspace = ReplayWorkspace::open(&node.config, genesis.clone()).unwrap(); + assert_eq!( + workspace.snapshot().committed_position().unwrap(), + Some(boundary.clone()) + ); + workspace.finish().unwrap(); + } +} + +#[test] +fn cold_start_fails_closed_and_genesis_requires_explicit_opt_in() { + let node = Node::new(); + let genesis = dolos_cardano::include::preview::load(); + let mut options = initialize::Options { + source: RestoreSource::Dir(node.root.path().join("missing-stele")), + point: Point::Latest, + insecure: false, + scratch_dir: None, + skip_space_check: false, + resume: false, + allow_genesis: false, + }; + + let error = initialize::run(&node.config, &genesis, &options, &Observer::silent()) + .unwrap_err() + .to_string(); + assert!(error.contains("refusing genesis fallback"), "{error}"); + + options.allow_genesis = true; + assert_eq!( + initialize::run(&node.config, &genesis, &options, &Observer::silent()).unwrap(), + initialize::Outcome::Genesis + ); + // A restart before the first committed block preserves the explicit + // genesis decision only while the invocation opts in again. + assert_eq!( + initialize::run(&node.config, &genesis, &options, &Observer::silent()).unwrap(), + initialize::Outcome::Genesis + ); +} diff --git a/stelae-publisher/Cargo.toml b/stelae-publisher/Cargo.toml new file mode 100644 index 0000000..1b8725c --- /dev/null +++ b/stelae-publisher/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "stelae-publisher" +description = "Stelae-owned Cardano publisher executable" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true + +[[bin]] +name = "stelae-publisher" +path = "src/main.rs" + +[dependencies] +stelae = { path = "../stelae", version = "=0.2.0", features = ["oci"] } +stelae-cardano = { path = "../stelae-cardano", version = "=0.2.0" } + +clap = { version = "4.5.37", features = ["derive"] } +config = { version = "0.15.19", default-features = false, features = ["toml", "json"] } +miette = { version = "7.6.0", features = ["fancy"] } +rustls = { version = "0.23", default-features = false, features = ["ring", "logging", "std", "tls12"] } +tokio = { version = "1.47", features = ["rt", "signal"] } +tokio-util = { version = "0.7.11", features = ["rt"] } +tracing = "0.1.37" +tracing-subscriber = "0.3.17" diff --git a/stelae-publisher/src/main.rs b/stelae-publisher/src/main.rs new file mode 100644 index 0000000..a64a05d --- /dev/null +++ b/stelae-publisher/src/main.rs @@ -0,0 +1,393 @@ +use std::{ + num::NonZeroUsize, + path::{Path, PathBuf}, + sync::Arc, +}; + +use clap::{Args, Parser, Subcommand}; +use miette::{Context as _, IntoDiagnostic as _}; +use stelae::progress::{Event, Observer, Progress}; +use stelae_cardano::{ + backfill, initialize, + publisher::{self, Destination, PublishOutcome}, + EpochRange, Genesis, Point, Repository, RestoreSource, RootConfig, Selection, +}; +use tokio_util::sync::CancellationToken; + +#[derive(Debug, Parser)] +#[command(name = "stelae-publisher", version, about)] +struct Cli { + /// Explicit Dolos-compatible configuration file. + #[arg(short, long, global = true)] + config: Option, + #[command(subcommand)] + command: Command, +} + +#[derive(Debug, Subcommand)] +enum Command { + /// Initialize empty stores from a stele, failing closed by default. + Initialize(InitializeArgs), + /// Publish the currently committed dataset once. + Publish(PublishArgs), + /// Replay Mithril history and publish every reached epoch boundary. + Backfill(BackfillArgs), + /// Initialize and then run the backfill state machine. + Run(RunArgs), +} + +#[derive(Debug, Args, Clone)] +struct InitializeArgs { + /// Own stele to restore: file://DIR or oci://HOST/PATH. + #[arg(long)] + source: RestoreSource, + #[arg(long, default_value = "latest")] + point: Point, + #[arg(long, action)] + insecure: bool, + #[arg(long)] + scratch_dir: Option, + #[arg(long, action)] + skip_space_check: bool, + /// Resume a prior restore using its layer journal. + #[arg(long, alias = "continue", action)] + resume: bool, + /// Start empty only when restore fails; intended solely for first publish. + #[arg(long, action)] + allow_genesis: bool, +} + +impl InitializeArgs { + fn options(&self) -> initialize::Options { + initialize::Options { + source: self.source.clone(), + point: self.point, + insecure: self.insecure, + scratch_dir: self.scratch_dir.clone(), + skip_space_check: self.skip_space_check, + resume: self.resume, + allow_genesis: self.allow_genesis, + } + } +} + +#[derive(Debug, Args, Clone)] +struct BackfillArgs { + /// OCI repository to extend. + #[arg(long, value_name = "OCI_URL")] + repo: Repository, + #[arg(long, action)] + insecure: bool, + #[arg(long)] + scratch_dir: Option, + #[arg(long)] + concurrency: Option, + #[arg(long, action)] + verify_carried: bool, + #[arg(long)] + download_dir: Option, + #[arg(long, default_value = "40")] + window: u64, + #[arg(long)] + until_epoch: Option, + #[arg(long, action)] + skip_validation: bool, +} + +impl BackfillArgs { + fn options(&self) -> backfill::Options { + backfill::Options { + repository: self.repo.clone(), + insecure: self.insecure, + scratch_dir: self.scratch_dir.clone(), + concurrency: self.concurrency, + verify_carried: self.verify_carried, + download_dir: self.download_dir.clone(), + window: self.window, + until_epoch: self.until_epoch, + skip_validation: self.skip_validation, + } + } +} + +#[derive(Debug, Args)] +struct RunArgs { + #[command(flatten)] + backfill: BackfillArgs, + /// Restore source; defaults to --repo. + #[arg(long)] + restore_source: Option, + #[arg(long, default_value = "latest")] + point: Point, + #[arg(long, action)] + skip_space_check: bool, + #[arg(long, action)] + resume: bool, + #[arg(long, action)] + allow_genesis: bool, +} + +#[derive(Debug, Args)] +#[command(group(clap::ArgGroup::new("destination").required(true).args(["output_dir", "repo"])))] +struct PublishArgs { + #[arg(long)] + output_dir: Option, + #[arg(long, value_name = "OCI_URL")] + repo: Option, + #[arg(long)] + epochs: Option, + #[arg(long)] + index_band: Option, + #[arg(long)] + producers: Option, + #[arg(long, action, conflicts_with = "output_dir")] + rebuild: bool, + #[arg(long, action, conflicts_with = "output_dir")] + insecure: bool, + #[arg(long, conflicts_with = "output_dir")] + scratch_dir: Option, + #[arg(long, conflicts_with = "output_dir")] + concurrency: Option, + #[arg(long, action, conflicts_with = "output_dir")] + verify_carried: bool, + #[arg(long, action)] + dry_run: bool, + #[arg(long, action, conflicts_with = "output_dir")] + require_new: bool, +} + +#[derive(Default)] +struct ConsoleProgress; + +impl Progress for ConsoleProgress { + fn on(&self, event: Event<'_>) { + match event { + Event::LayerStarted { + index, total, kind, .. + } => { + eprintln!("layer {}/{total}: {kind}", index + 1); + } + Event::Retry { + attempt, + remaining, + reason, + } => { + eprintln!("retry after attempt {attempt} ({remaining} left): {reason}"); + } + _ => {} + } + } +} + +fn load_config(explicit: Option<&Path>) -> Result { + let mut builder = config::Config::builder() + .add_source(config::File::with_name("/etc/dolos/daemon.toml").required(false)) + .add_source(config::File::with_name("dolos.toml").required(false)); + if let Some(path) = explicit { + let path = path.to_str().ok_or_else(|| { + config::ConfigError::Message(format!( + "configuration path is not valid UTF-8: {}", + path.display() + )) + })?; + builder = builder.add_source(config::File::with_name(path).required(true)); + } + builder + .add_source(config::Environment::with_prefix("DOLOS").separator("_")) + .build()? + .try_deserialize() +} + +fn load_genesis(config: &RootConfig) -> miette::Result { + Genesis::from_file_paths( + &config.genesis.byron_path, + &config.genesis.shelley_path, + &config.genesis.alonzo_path, + &config.genesis.conway_path, + config.genesis.force_protocol, + ) + .into_diagnostic() + .context("loading genesis files") +} + +fn spawn_exit_watcher() -> miette::Result { + let cancel = CancellationToken::new(); + let hooked = cancel.clone(); + std::thread::Builder::new() + .name("exit-signal".to_owned()) + .spawn(move || { + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("building signal runtime"); + runtime.block_on(async move { + #[cfg(unix)] + { + let mut term = + tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()) + .expect("installing SIGTERM watcher"); + tokio::select! { _ = tokio::signal::ctrl_c() => {}, _ = term.recv() => {} } + } + #[cfg(not(unix))] + tokio::signal::ctrl_c() + .await + .expect("installing interrupt watcher"); + tracing::warn!("shutdown requested; stopping at the next cancellation point"); + hooked.cancel(); + }); + }) + .into_diagnostic() + .context("spawning exit-signal watcher")?; + Ok(cancel) +} + +fn run_initialize( + config: &RootConfig, + genesis: &Genesis, + args: &InitializeArgs, + observer: &Observer, +) -> miette::Result<()> { + match initialize::run(config, genesis, &args.options(), observer) + .map_err(|error| miette::miette!("{error}"))? + { + initialize::Outcome::Existing => println!("publisher storage already initialized"), + initialize::Outcome::Restored { sequence } => println!("restored sequence {sequence}"), + initialize::Outcome::Genesis => { + println!("restore unavailable; explicit genesis start selected") + } + } + Ok(()) +} + +fn run_backfill( + config: &RootConfig, + genesis: &Genesis, + args: &BackfillArgs, + observer: &Observer, +) -> miette::Result<()> { + if args.window == 0 { + return Err(miette::miette!("--window must be at least 1")); + } + match backfill::run( + config, + genesis, + &args.options(), + spawn_exit_watcher()?, + observer, + ) + .into_diagnostic()? + { + backfill::Outcome::UntilEpoch { sequence } => println!("sequence {sequence} published"), + backfill::Outcome::UpToDate => println!("repository is up to date with Mithril"), + } + Ok(()) +} + +fn run_publish( + config: &RootConfig, + genesis: &Genesis, + args: &PublishArgs, + observer: &Observer, +) -> miette::Result<()> { + let selection = Selection { + epochs: args.epochs, + index_band: args.index_band, + producers: args.producers, + }; + let destination = match (&args.output_dir, &args.repo) { + (Some(path), None) => Destination::Directory(path.clone()), + (None, Some(repository)) => Destination::Repository { + repository: repository.clone(), + insecure: args.insecure, + scratch_dir: args.scratch_dir.clone(), + rebuild: args.rebuild, + concurrency: args.concurrency, + verify_carried: args.verify_carried, + require_new: args.require_new, + }, + _ => unreachable!("clap enforces exactly one destination"), + }; + let (report, outcome) = publisher::publish_once( + config, + genesis, + selection, + destination, + args.dry_run, + observer, + ) + .map_err(|error| miette::miette!("{error}"))?; + eprintln!("network: {} ({})", report.network, report.magic); + eprintln!("cursor: {}", report.cursor); + match outcome { + PublishOutcome::DryRun { sequence } => { + println!("dry run: sequence {sequence}; nothing written") + } + PublishOutcome::Nothing(message) => println!("{message}"), + PublishOutcome::Directory { + sequence, + identity, + layers, + } => { + println!("wrote sequence {sequence}: {identity} ({layers} layers)") + } + PublishOutcome::Repository { + sequence, + identity, + built, + reused, + } => { + println!("wrote sequence {sequence}: {identity} ({built} built, {reused} reused)") + } + } + Ok(()) +} + +fn main() -> miette::Result<()> { + let _ = rustls::crypto::ring::default_provider().install_default(); + tracing_subscriber::fmt().with_target(false).init(); + let cli = Cli::parse(); + let config = load_config(cli.config.as_deref()) + .into_diagnostic() + .context("parsing configuration")?; + let genesis = load_genesis(&config)?; + let observer = Observer::new(Arc::new(ConsoleProgress)); + + match cli.command { + Command::Initialize(args) => run_initialize(&config, &genesis, &args, &observer), + Command::Publish(args) => run_publish(&config, &genesis, &args, &observer), + Command::Backfill(args) => run_backfill(&config, &genesis, &args, &observer), + Command::Run(args) => { + let initialize = InitializeArgs { + source: args + .restore_source + .unwrap_or_else(|| RestoreSource::Repo(args.backfill.repo.clone())), + point: args.point, + insecure: args.backfill.insecure, + scratch_dir: args.backfill.scratch_dir.clone(), + skip_space_check: args.skip_space_check, + resume: args.resume, + allow_genesis: args.allow_genesis, + }; + run_initialize(&config, &genesis, &initialize, &observer)?; + run_backfill(&config, &genesis, &args.backfill, &observer) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[cfg(unix)] + #[test] + fn an_explicit_non_utf8_config_path_is_rejected() { + use std::{ffi::OsString, os::unix::ffi::OsStringExt as _}; + + let path = PathBuf::from(OsString::from_vec(vec![0xff])); + let error = match load_config(Some(&path)) { + Ok(_) => panic!("non-UTF-8 path was accepted"), + Err(error) => error, + }; + assert!(error.to_string().contains("not valid UTF-8")); + } +}