diff --git a/Cargo.lock b/Cargo.lock index 30cbd2a02..8d68bdb77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,9 +77,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fc76eaeac4c9164506c466d4ffdd8ec9d0c5bf57ee97177c4d8eceb3a0e138" +checksum = "f8eb277bec05f56a0e0591f155a484cbd0f4f07ff2905051a48c72f004f7ed58" dependencies = [ "cipher 0.5.2", "cpubits", @@ -115,9 +115,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] @@ -160,9 +160,9 @@ dependencies = [ [[package]] name = "android_system_properties" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" dependencies = [ "libc", ] @@ -230,16 +230,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1384d3fe1eecb464229fcf6eebb72306591c56bf27b373561489458a7c73027d" dependencies = [ "futures", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "wasm-bindgen-futures", ] [[package]] name = "anyhow" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "arbitrary" @@ -252,18 +252,18 @@ dependencies = [ [[package]] name = "arc-swap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" +checksum = "c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b" dependencies = [ "rustversion", ] [[package]] name = "archery" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e0a5f99dfebb87bb342d0f53bb92c81842e100bbb915223e38349580e5441d" +checksum = "33ca55ee147b1926dbea904f50fe4902494e97bc742205abbbf10c709e43815f" dependencies = [ "triomphe", ] @@ -310,7 +310,7 @@ checksum = "e7e89fe77d1f0f4fe5b96dfc940923d88d17b6a773808124f21e764dfb063c6a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -328,7 +328,7 @@ dependencies = [ "fnv", "hashbrown 0.15.5", "itertools 0.13.0", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "num-integer", "num-traits", "zeroize", @@ -348,7 +348,7 @@ dependencies = [ "digest 0.10.7", "educe", "itertools 0.13.0", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "num-traits", "paste", "zeroize", @@ -361,7 +361,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -370,11 +370,11 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" dependencies = [ - "num-bigint 0.4.6", + "num-bigint 0.4.8", "num-traits", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -418,7 +418,7 @@ dependencies = [ "ark-relations", "ark-std", "educe", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "num-integer", "num-traits", "tracing", @@ -446,7 +446,7 @@ dependencies = [ "ark-std", "arrayvec", "digest 0.10.7", - "num-bigint 0.4.6", + "num-bigint 0.4.8", ] [[package]] @@ -457,7 +457,7 @@ checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -479,7 +479,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" dependencies = [ "num-traits", - "rand 0.8.6", + "rand 0.8.7", ] [[package]] @@ -496,9 +496,9 @@ checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] name = "asn1-rs" @@ -512,7 +512,7 @@ dependencies = [ "nom 7.1.3", "num-traits", "rusticata-macros", - "thiserror 2.0.18", + "thiserror 2.0.20", "time", ] @@ -524,7 +524,7 @@ checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", "synstructure", ] @@ -536,7 +536,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -565,15 +565,15 @@ dependencies = [ [[package]] name = "astral-tokio-tar" -version = "0.6.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb50a7aae84a03bf55b067832bc376f4961b790c97e64d3eacee97d389b90277" +checksum = "b18457efd137254e016bbde5e1d88df61c4e1a5ae2223746e56123bac6af2463" dependencies = [ - "filetime", "futures-core", "libc", "portable-atomic", "rustc-hash", + "rustix", "tokio", "tokio-stream", "xattr", @@ -581,9 +581,9 @@ dependencies = [ [[package]] name = "astro-float" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96034cc871c05bb65ad7fb77e6a8bebf45d8b055ed0311769e2f83a1d373c1ec" +checksum = "2cf6ecd69dd6fbe3763187ff2fa2b0e475b79f04ed86f631a7bc6b04ede0355e" dependencies = [ "astro-float-macro", "astro-float-num", @@ -591,9 +591,9 @@ dependencies = [ [[package]] name = "astro-float-macro" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05cfe0f6df5a74fb25b9e713470ad77e091f35f798730673c8772f26ed438963" +checksum = "9c007205ae7076600c8a59022866990afac02ff186f9031839f67ecce4df2146" dependencies = [ "astro-float-num", "proc-macro2", @@ -603,9 +603,9 @@ dependencies = [ [[package]] name = "astro-float-num" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86887daca11d02e0b04f37a9cb81888aae881397fb48ff66494e356aea97554a" +checksum = "bc7f6a0312e8f5845f84241b21bd2394d49940b6bc333c6a84f992e6dc9ebb85" dependencies = [ "itertools 0.10.5", "lazy_static", @@ -698,18 +698,18 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "async-trait" -version = "0.1.89" +version = "0.1.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] @@ -763,7 +763,7 @@ dependencies = [ "manyhow", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -779,7 +779,7 @@ dependencies = [ "proc-macro2", "quote", "quote-use", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -805,9 +805,9 @@ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "aws-lc-rs" -version = "1.17.3" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00bdb5da18dac48ca2cc7cd4a98e533e8635a58e2361d13a1a4ee3888e0d72f1" +checksum = "ce2b2dcc879c3bae0d371e77c99f2238400ef24ec001394befa67b6e543add9e" dependencies = [ "aws-lc-sys", "zeroize", @@ -815,9 +815,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.43.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43103168cc76fe62678a375e722fc9cb3a0146159ac5828bc4f0dfd755c2224c" +checksum = "f09fae7be8bb3174e05c6afdb34199e6dc0c7c04ba9fa237b1967adfbde27483" dependencies = [ "cc", "cmake", @@ -995,6 +995,12 @@ dependencies = [ "match-lookup", ] +[[package]] +name = "base45" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240e56f4d3c453c36faacb695c535a4d5f8c7d23dac175014f32eb0a71012a03" + [[package]] name = "base58" version = "0.2.0" @@ -1013,6 +1019,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + [[package]] name = "base64ct" version = "1.8.3" @@ -1034,7 +1046,7 @@ version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", "cexpr", "clang-sys", "itertools 0.13.0", @@ -1043,7 +1055,7 @@ dependencies = [ "regex", "rustc-hash", "shlex 1.3.0", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -1065,9 +1077,9 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitcoin_hashes" -version = "0.14.2" +version = "0.14.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ed83caece3afc59919481b33b472e1432d1abc4641ed9100be142ef5110b406" +checksum = "bca4c7abb40c8817d77403c880988cfd484f23ab2365726afb2f798363e2c4a2" dependencies = [ "hex-conservative", ] @@ -1080,15 +1092,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.12.1" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84d7ced0ae9557296835c32bf1b1e02b44c746701f898460fb000d7eaa84f00a" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "bitvec" -version = "1.0.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +checksum = "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837" dependencies = [ "funty", "radium", @@ -1122,9 +1134,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" dependencies = [ "hybrid-array", ] @@ -1155,7 +1167,7 @@ checksum = "ee04c4c84f1f811b017f2fbb7dd8815c976e7ca98593de9c1e2afad0f636bff4" dependencies = [ "async-stream", "base64 0.22.1", - "bitflags 2.12.1", + "bitflags 2.13.1", "bollard-buildkit-proto", "bollard-stubs", "bytes", @@ -1173,7 +1185,7 @@ dependencies = [ "log", "num", "pin-project-lite", - "rand 0.9.4", + "rand 0.9.5", "rustls", "rustls-native-certs", "rustls-pki-types", @@ -1181,7 +1193,7 @@ dependencies = [ "serde_derive", "serde_json", "serde_urlencoded", - "thiserror 2.0.18", + "thiserror 2.0.20", "time", "tokio", "tokio-stream", @@ -1198,8 +1210,8 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85a885520bf6249ab931a764ffdb87b0ceef48e6e7d807cfdb21b751e086e1ad" dependencies = [ - "prost 0.14.3", - "prost-types 0.14.3", + "prost 0.14.4", + "prost-types 0.14.4", "tonic", "tonic-prost", "ureq", @@ -1214,7 +1226,7 @@ dependencies = [ "base64 0.22.1", "bollard-buildkit-proto", "bytes", - "prost 0.14.3", + "prost 0.14.4", "serde", "serde_json", "serde_repr", @@ -1223,9 +1235,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" +checksum = "a88b7ea17d208c4193f2c1e6de3c35fe71f98c96982d5ced308bdcc749ff6e1f" dependencies = [ "borsh-derive", "bytes", @@ -1234,15 +1246,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfcfdc083699101d5a7965e49925975f2f55060f94f9a05e7187be95d530ca59" +checksum = "d8f347189c62a579b8cd5f80714efa178f52e461dc2e6d701d264f5ff22e566c" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -1278,6 +1290,7 @@ dependencies = [ name = "bridge_program" version = "0.1.0" dependencies = [ + "authenticated_transfer_core", "bridge_core", "lee_core", "vault_core", @@ -1324,22 +1337,22 @@ checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" [[package]] name = "bytemuck" -version = "1.25.0" +version = "1.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.10.2" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +checksum = "fc0e56a716f1e132ff6bf4bdac1c944a3fcdc1cae65f70a4a2a1ac3b401d2d1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] @@ -1359,9 +1372,9 @@ dependencies = [ [[package]] name = "bytesize" -version = "2.3.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bd91ee7b2422bcb158d90ef4d14f75ef67f340943fc4149891dcce8f8b972a3" +checksum = "7354288c522e7e980fafd2075d63d1285794c3a6a16cdd492f189ea406e5f18b" dependencies = [ "serde_core", ] @@ -1378,9 +1391,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.2.2" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +checksum = "bb1307f12aa967b5a58416e87b3653360e0fd614a016b6e970db08fecbb1b80d" dependencies = [ "serde_core", ] @@ -1405,7 +1418,7 @@ dependencies = [ "semver", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -1425,9 +1438,9 @@ dependencies = [ [[package]] name = "cbindgen" -version = "0.29.3" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95537b45400390270fae69ac098d057c8f5399001cde9d04f700c105ddfff2d" +checksum = "2ecb53484c9c167ba674026b656d8a27d7657a58e6066aa902bfb1a4aa00ae20" dependencies = [ "clap", "heck", @@ -1437,16 +1450,16 @@ dependencies = [ "quote", "serde", "serde_json", - "syn 2.0.117", + "syn 2.0.119", "tempfile", "toml 0.9.12+spec-1.1.0", ] [[package]] name = "cc" -version = "1.2.63" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" +checksum = "509591b7bcd67f4ef775afad7662703b4935daaa6ec0e5605cfb1090b32a2b6d" dependencies = [ "find-msvc-tools", "jobserver", @@ -1456,9 +1469,9 @@ dependencies = [ [[package]] name = "ccm" -version = "0.6.0-rc.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4edea5ea70a1285565ac264767613d6c88351a9a0557e7af793a0942590baaed" +checksum = "5e7415d7ee93607d3cea8e980aa5f250b0d63564c770e87c0e0cabafd063df98" dependencies = [ "aead 0.6.1", "cipher 0.5.2", @@ -1489,9 +1502,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" [[package]] name = "cfgsync-adapter" @@ -1510,7 +1523,7 @@ version = "0.1.0" source = "git+https://github.com/logos-blockchain/logos-blockchain-testing.git?rev=db880d61155db3a4f32177ef16b0f1e4bf22b1f6#db880d61155db3a4f32177ef16b0f1e4bf22b1f6" dependencies = [ "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -1521,19 +1534,19 @@ dependencies = [ "anyhow", "axum 0.7.9", "cfgsync-artifacts", - "reqwest", + "reqwest 0.12.28", "serde", "serde_json", "serde_yaml", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", ] [[package]] name = "chacha20" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" dependencies = [ "cfg-if", "cipher 0.5.2", @@ -1546,18 +1559,21 @@ name = "chain_state" version = "0.1.0" dependencies = [ "anyhow", + "async-stream", "borsh", "common", + "ed25519-dalek", "futures", "lee", "lee_core", "log", "logos-blockchain-core", "logos-blockchain-zone-sdk", + "num-bigint 0.4.8", "serde", "serde_json", "testnet_initial_state", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", ] @@ -1572,9 +1588,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "js-sys", @@ -1649,16 +1665,16 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ - "block-buffer 0.12.0", + "block-buffer 0.12.1", "crypto-common 0.2.2", "inout 0.2.2", ] [[package]] name = "clang-sys" -version = "1.8.1" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +checksum = "157a8ba7b480713b56f4c09fd13fc3e0a22a5dfab8097ba61cbc5feef950788a" dependencies = [ "glob", "libc", @@ -1667,9 +1683,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.6.1" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca" dependencies = [ "clap_builder", "clap_derive", @@ -1677,9 +1693,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.6.0" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889" dependencies = [ "anstream", "anstyle", @@ -1690,14 +1706,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.6.1" +version = "4.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" +checksum = "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] @@ -1743,7 +1759,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" dependencies = [ - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -1754,7 +1770,7 @@ checksum = "a9dbbdc4b4d349732bc6690de10a9de952bd39ba6a065c586e26600b6b0b91f5" dependencies = [ "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -1811,7 +1827,7 @@ dependencies = [ "serde_with", "sha2 0.10.9", "system_accounts", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -1825,22 +1841,22 @@ dependencies = [ [[package]] name = "config" -version = "0.15.23" +version = "0.15.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f316c6237b2d38be61949ecd15268a4c6ca32570079394a2444d9ce2c72a72d8" +checksum = "b85f248a4de22d204ceabc6299d89d2c70fbd7f09fea53c06c852369652d8139" dependencies = [ "convert_case 0.6.0", "pathdiff", "serde_core", - "toml 1.1.2+spec-1.1.0", - "winnow 1.0.3", + "toml 1.1.4+spec-1.1.0", + "winnow 1.0.4", ] [[package]] name = "console" -version = "0.16.3" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" +checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c" dependencies = [ "encode_unicode", "libc", @@ -1860,9 +1876,9 @@ dependencies = [ [[package]] name = "console_log" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be8aed40e4edbf4d3b4431ab260b63fdc40f5780a4766824329ea0f1eefe3c0f" +checksum = "86919cef3e37b9356ccf54d4421208c17ecfda01beae61393e7ffd72916c0ef1" dependencies = [ "log", "web-sys", @@ -2128,7 +2144,7 @@ dependencies = [ "log", "ping_core", "programs", - "rand 0.8.6", + "rand 0.8.7", "risc0-zkvm", "sequencer_service_rpc", "serde", @@ -2183,18 +2199,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.15" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -2211,9 +2227,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" [[package]] name = "crunchy" @@ -2241,7 +2257,7 @@ checksum = "1a52aa3fcda4e6302a9f48734f234d35d4721b96f8fe07d073f07ce9df4f0271" dependencies = [ "cpubits", "ctutils", - "getrandom 0.4.2", + "getrandom 0.4.3", "hybrid-array", "num-traits", "rand_core 0.10.1", @@ -2266,7 +2282,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ - "getrandom 0.4.2", + "getrandom 0.4.3", "hybrid-array", "rand_core 0.10.1", ] @@ -2359,7 +2375,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.117", + "syn 2.0.119", "synthez", ] @@ -2402,7 +2418,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2458,7 +2474,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2471,7 +2487,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2482,7 +2498,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2493,7 +2509,7 @@ checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ "darling_core 0.23.0", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2510,15 +2526,15 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" +checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" [[package]] name = "data-encoding-macro" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3259c913752a86488b501ed8680446a5ed2d5aeac6e596cb23ba3800768ea32c" +checksum = "c6a127ecbb3c4632e1525380e04c0c3fcf8dcb44d32a79ea290d8a36906edcd8" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -2526,12 +2542,43 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccc2776f0c61eca1ca32528f85548abd1a4be8fb53d1b21c013e4f18da1e7090" +checksum = "c54e03a951783e8b327515db3f2a2fd0e3bed362a96b066f341ce66ed49b4ead" dependencies = [ "data-encoding", - "syn 2.0.117", + "syn 3.0.3", +] + +[[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]] @@ -2547,9 +2594,9 @@ dependencies = [ [[package]] name = "der" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71fd89660b2dc699704064e59e9dba0147b903e85319429e131620d022be411b" +checksum = "a69dedd701da44b0536442edf09c81a64b0ab97a7a4a5e3d1971f00027cbc63d" dependencies = [ "const-oid 0.10.2", "zeroize", @@ -2564,7 +2611,7 @@ dependencies = [ "asn1-rs", "displaydoc", "nom 7.1.3", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "num-traits", "rusticata-macros", ] @@ -2575,7 +2622,6 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ - "powerfmt", "serde_core", ] @@ -2609,7 +2655,7 @@ checksum = "d08b3a0bcc0d079199cd476b2cae8435016ec11d1c0986c6901c5ac223041534" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2620,7 +2666,7 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2641,7 +2687,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2651,7 +2697,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2673,7 +2719,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.117", + "syn 2.0.119", "unicode-xid", ] @@ -2701,7 +2747,7 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ - "block-buffer 0.12.0", + "block-buffer 0.12.1", "const-oid 0.10.2", "crypto-common 0.2.2", "ctutils", @@ -2743,7 +2789,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", "block2", "libc", "objc2", @@ -2751,13 +2797,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] @@ -2826,8 +2872,8 @@ checksum = "9ac1e888d6830712d565b2f3a974be3200be9296bc1b03db8251a4cbf18a4a34" dependencies = [ "digest 0.10.7", "futures", - "rand 0.8.6", - "reqwest", + "rand 0.8.7", + "reqwest 0.12.28", "thiserror 1.0.69", "tokio", ] @@ -2873,14 +2919,14 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.17.0-rc.22" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c72d1455753a703ad4b90ed2a759f2bc4562024a303176439cf6e593b5ade4" +checksum = "c0681a4fc24c767085329728d8dfba959af91228aa4610cca4f8ce317ba46ae0" dependencies = [ - "der 0.8.0", + "der 0.8.1", "digest 0.11.3", - "elliptic-curve 0.14.0", - "rfc6979 0.6.0-pre.0", + "elliptic-curve 0.14.1", + "rfc6979 0.6.0", "signature 3.0.0", "spki 0.8.0", "zeroize", @@ -2921,14 +2967,14 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "either" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "either_of" @@ -2969,9 +3015,9 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3273f1195b6f6253ebda493d6742c8baa9b26a291674cd96d92a0f09e90e9b46" +checksum = "9d65aa39b3a5c1c9c1b745c9a019234bb7a21b77abcb4f4d266d706e2d577d65" dependencies = [ "base16ct 1.0.0", "crypto-bigint 0.7.5", @@ -3024,7 +3070,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -3044,34 +3090,34 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "enum-ordinalize" -version = "4.3.2" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1091a7bb1f8f2c4b28f1fe2cef4980ca2d410a3d727d67ecc3178c9b0800f0" +checksum = "89dd01549b09589510cf0647475075d12071456586d70f5c75c98ae2a5537677" dependencies = [ "enum-ordinalize-derive", ] [[package]] name = "enum-ordinalize-derive" -version = "4.3.2" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" +checksum = "a65863d15a4ce2888bd2f0f543cc963d3879c3a022c8ee43f6141d479a3ac815" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] name = "env_filter" -version = "1.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" +checksum = "900d271a03799a1ee8d1ca9b19893b48ca674a9284fefcfb85f05e74ed314217" dependencies = [ "log", "regex", @@ -3079,9 +3125,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.10" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" +checksum = "de671bd27a75a797dc9ae289ba1e77276e75e2026408aab65185384e2d5cd3f6" dependencies = [ "anstream", "anstyle", @@ -3135,11 +3181,10 @@ dependencies = [ [[package]] name = "event-listener" -version = "5.4.1" +version = "5.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" dependencies = [ - "concurrent-queue", "parking", "pin-project-lite", ] @@ -3228,21 +3273,21 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] name = "fastbloom" -version = "0.14.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7f34442dbe69c60fe8eaf58a8cafff81a1f278816d8ab4db255b3bef4ac3c4" +checksum = "ef975e30683b2d965054bb0a836f8973857c4ebf6acf274fe46617cd285060d8" dependencies = [ - "getrandom 0.3.4", + "foldhash 0.2.0", "libm", - "rand 0.9.4", + "portable-atomic", "siphasher", ] [[package]] name = "fastrand" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" [[package]] name = "faucet_core" @@ -3280,7 +3325,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee93edf3c501f0035bbeffeccfed0b79e14c311f12195ec0e661e114a0f60da4" dependencies = [ "portable-atomic", - "rand 0.10.1", + "rand 0.10.2", "web-time", ] @@ -3340,9 +3385,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" [[package]] name = "flate2" @@ -3393,13 +3438,13 @@ dependencies = [ [[package]] name = "foreign-types-macros" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +checksum = "ea5190182e6915eb873ddbc16e23b711b6eb1f9c00a0d0a3a91b5f6228475225" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] @@ -3456,9 +3501,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" dependencies = [ "futures-channel", "futures-core", @@ -3481,9 +3526,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -3491,15 +3536,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-executor" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" dependencies = [ "futures-core", "futures-task", @@ -3508,9 +3553,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-lite" @@ -3524,13 +3569,13 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] @@ -3546,15 +3591,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-timer" @@ -3568,9 +3613,9 @@ dependencies = [ [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-channel", "futures-core", @@ -3589,7 +3634,7 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bafc7e33650ab9f05dcc16325f05d56b8d10393114e31a19a353b86fa60cfe7" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", "cfg-if", "log", "managed", @@ -3635,9 +3680,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "1.4.3" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e55f16dcf0e9c00efbe2e655ffe45fc98e7066b52bc92f8a79e64060a79351" +checksum = "337d46834ee672ab3e48caca2cb0c78cc174fb12b3a68d0d88f99a0519a5e36e" dependencies = [ "rustversion", "serde_core", @@ -3664,26 +3709,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", - "js-sys", "libc", "r-efi 5.3.0", "wasip2", - "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "js-sys", "libc", "r-efi 6.0.0", "rand_core 0.10.1", - "wasip2", - "wasip3", "wasm-bindgen", ] @@ -3708,9 +3749,9 @@ dependencies = [ "quote", "serde", "serde_json", - "syn 2.0.117", + "syn 2.0.119", "textwrap", - "thiserror 2.0.18", + "thiserror 2.0.20", "typed-builder", ] @@ -3733,15 +3774,15 @@ checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "glob" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" [[package]] name = "globset" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e47d37d2ae4464254884b60ab7071be2b876a9c35b696bd018ddcc76847309cd" +checksum = "07c34a9410465b45bd9787443bc7370f37735bad04b0f0cd57ff1a3186c98988" dependencies = [ "aho-corasick", "bstr", @@ -3756,7 +3797,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", "ignore", "walkdir", ] @@ -3849,9 +3890,9 @@ checksum = "17e2ac29387b1aa07a1e448f7bb4f35b500787971e965b02842b900afa5c8f6f" [[package]] name = "h2" -version = "0.4.16" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9f37a958b41b3b19ee2707c06439c0e9e547e847223eb791ecb0cb821c65e27" +checksum = "839c0e8a181239723652be9062bb56ca5bf5f64011f73b623f6f4fc59086a228" dependencies = [ "atomic-waker", "bytes", @@ -4027,10 +4068,10 @@ dependencies = [ "idna", "ipnet", "once_cell", - "rand 0.9.4", + "rand 0.9.5", "ring", "socket2 0.5.10", - "thiserror 2.0.18", + "thiserror 2.0.20", "tinyvec", "tokio", "tracing", @@ -4050,10 +4091,10 @@ dependencies = [ "moka", "once_cell", "parking_lot", - "rand 0.9.4", + "rand 0.9.5", "resolv-conf", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tracing", ] @@ -4133,18 +4174,15 @@ dependencies = [ [[package]] name = "html-escape" -version = "0.2.13" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" -dependencies = [ - "utf8-width", -] +checksum = "c9356095b4b41197bba32173600e1582792cda618f65d12f68e2e77d273413c5" [[package]] name = "http" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" dependencies = [ "bytes", "itoa", @@ -4152,9 +4190,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" dependencies = [ "bytes", "http", @@ -4162,9 +4200,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" dependencies = [ "bytes", "futures-core", @@ -4202,9 +4240,9 @@ dependencies = [ [[package]] name = "humantime" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" +checksum = "15cdd26707701c53297e2fa6afb323d55fbc1d0810c3aec078ae3ef0424c3c15" [[package]] name = "humantime-serde" @@ -4218,9 +4256,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" dependencies = [ "ctutils", "subtle", @@ -4230,13 +4268,12 @@ dependencies = [ [[package]] name = "hydration_context" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8714ae4adeaa846d838f380fbd72f049197de629948f91bf045329e0cf0a283" +checksum = "7bbbeb23ee808258cef2c5585ff0dc8e41da21a8dde943f6b290da153a042a96" dependencies = [ "futures", "js-sys", - "once_cell", "or_poisoned", "pin-project-lite", "serde", @@ -4246,9 +4283,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" +checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72" dependencies = [ "atomic-waker", "bytes", @@ -4268,9 +4305,9 @@ dependencies = [ [[package]] name = "hyper-named-pipe" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b7d8abf35697b81a825e386fc151e0d503e8cb5fcb93cc8669c376dfd6f278" +checksum = "fab3637d6b04a8037af8a266fdf6cf92ea957e8c53981a2bf6136572531025bf" dependencies = [ "hex", "hyper", @@ -4278,7 +4315,6 @@ dependencies = [ "pin-project-lite", "tokio", "tower-service", - "winapi", ] [[package]] @@ -4345,10 +4381,12 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.4", + "socket2 0.6.5", + "system-configuration 0.7.0", "tokio", "tower-service", "tracing", + "windows-registry", ] [[package]] @@ -4392,9 +4430,9 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" dependencies = [ "displaydoc", "potential_utf", @@ -4406,9 +4444,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" dependencies = [ "displaydoc", "litemap", @@ -4419,9 +4457,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -4433,16 +4471,17 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" [[package]] name = "icu_properties" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" dependencies = [ + "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", @@ -4453,15 +4492,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" [[package]] name = "icu_provider" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" dependencies = [ "displaydoc", "icu_locale_core", @@ -4472,12 +4511,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "ident_case" version = "1.0.1" @@ -4528,7 +4561,7 @@ dependencies = [ "if-addrs", "ipnet", "log", - "netlink-packet-core 0.8.1", + "netlink-packet-core 0.8.2", "netlink-packet-route 0.28.0", "netlink-proto", "netlink-sys", @@ -4553,7 +4586,7 @@ dependencies = [ "hyper", "hyper-util", "log", - "rand 0.9.4", + "rand 0.9.5", "tokio", "url", "xmltree", @@ -4561,9 +4594,9 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.32" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b17771570a2b94107741a7b033f19132c2eee21d59d21b24d2ced26500bd66e" +checksum = "00b69833ed729dc5aa7d19541d96d6cf8e9137194207a04916d658e43168402f" dependencies = [ "crossbeam-deque", "globset", @@ -4615,7 +4648,7 @@ dependencies = [ "storage", "tempfile", "testnet_initial_state", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "url", ] @@ -4666,7 +4699,7 @@ dependencies = [ "indexer_core", "lee", "lee_core", - "schemars 1.2.1", + "schemars 1.2.2", "serde", "serde_json", "serde_with", @@ -4678,7 +4711,7 @@ version = "0.1.0" dependencies = [ "indexer_service_protocol", "jsonrpsee", - "schemars 1.2.1", + "schemars 1.2.2", "serde_json", ] @@ -4707,9 +4740,9 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.18.4" +version = "0.18.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25470f23803092da7d239834776d653104d551bc4d7eacaf31e6837854b8e9eb" +checksum = "9433806cd6b4ec1aba79c021c7e4c58fb4c3b9977c085062e611ac929998fb0c" dependencies = [ "console", "portable-atomic", @@ -4770,15 +4803,18 @@ dependencies = [ "anyhow", "async-trait", "authenticated_transfer_core", + "borsh", "bridge_core", "bridge_lock_core", "bytesize", + "chain_state", "common", "cross_zone_inbox_core", "cross_zone_marker_core", "cross_zone_outbox_core", "cucumber", "faucet_core", + "futures", "hex", "indexer_ffi", "indexer_service", @@ -4789,11 +4825,13 @@ dependencies = [ "lee_core", "log", "logos-blockchain-core", + "logos-blockchain-http-api-common", "logos-blockchain-key-management-system-service", "logos-blockchain-zone-sdk", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "ping_core", "programs", + "reqwest 0.12.28", "risc0-zkvm", "sequencer_core", "sequencer_service", @@ -4808,7 +4846,7 @@ dependencies = [ "testing-framework-app", "testing-framework-core", "testnet_initial_state", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tracing", "tracing-subscriber 0.3.23", @@ -4839,7 +4877,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d40460c0ce33d6ce4b0630ad68ff63d6661961c48b6dba35e5a4d81cfb48222" dependencies = [ - "socket2 0.6.4", + "socket2 0.6.5", "widestring", "windows-registry", "windows-result 0.4.1", @@ -4848,9 +4886,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" +checksum = "6a756c3fac73139e83f14c2d742155dd2b78d3ee56597b419a0579b7bdd6dd78" [[package]] name = "is_terminal_polyfill" @@ -4927,26 +4965,55 @@ dependencies = [ [[package]] name = "jiff" -version = "0.2.28" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4603d3033e49e2b0e31229fcab20a5d40089c607d975cd9c80551dc69eed9102" +checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" dependencies = [ + "defmt", + "jiff-core", "jiff-static", + "jiff-tzdb-platform", "log", "portable-atomic", "portable-atomic-util", "serde_core", + "windows-link 0.2.1", +] + +[[package]] +name = "jiff-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +dependencies = [ + "defmt", ] [[package]] name = "jiff-static" -version = "0.2.28" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "782d32378dddf207193ac91cefb848ad41abb58195c95168e1291227a0832b47" +checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" dependencies = [ + "jiff-core", "proc-macro2", "quote", - "syn 2.0.117", + "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]] @@ -4990,28 +5057,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.99" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] @@ -5024,7 +5090,7 @@ dependencies = [ "jsonptr", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -5047,7 +5113,7 @@ dependencies = [ "pest_derive", "regex", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -5095,7 +5161,7 @@ dependencies = [ "rustls-pki-types", "rustls-platform-verifier", "soketto", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-rustls", "tokio-util", @@ -5119,11 +5185,11 @@ dependencies = [ "jsonrpsee-types", "parking_lot", "pin-project", - "rand 0.9.4", + "rand 0.9.5", "rustc-hash", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-stream", "tower 0.5.3", @@ -5148,7 +5214,7 @@ dependencies = [ "rustls-platform-verifier", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tower 0.5.3", "url", @@ -5164,7 +5230,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -5186,7 +5252,7 @@ dependencies = [ "serde", "serde_json", "soketto", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-stream", "tokio-util", @@ -5203,7 +5269,7 @@ dependencies = [ "http", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -5261,13 +5327,13 @@ dependencies = [ [[package]] name = "k256" -version = "0.14.0-rc.14" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "905d38bdbb43bb506efa0a428b3e969ff244549832a86b18591492f503adfe37" +checksum = "93f50113171a713f4a4231ef82eb26703607139b35dcb56241f0ceab2ae1f7d8" dependencies = [ "cpubits", - "ecdsa 0.17.0-rc.22", - "elliptic-curve 0.14.0", + "ecdsa 0.17.0", + "elliptic-curve 0.14.1", "primeorder", "sha2 0.11.0", "signature 3.0.0", @@ -5310,7 +5376,7 @@ dependencies = [ "futures", "glob", "kameo", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", ] @@ -5323,7 +5389,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -5372,10 +5438,10 @@ dependencies = [ "lee", "lee_core", "ml-kem", - "rand 0.8.6", + "rand 0.8.7", "serde", "sha2 0.10.9", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -5383,16 +5449,16 @@ name = "keycard-rs" version = "0.1.0" source = "git+https://github.com/keycard-tech/keycard-rs?rev=9535a657ba04b1e6916de51777e22b4837c1a84d#9535a657ba04b1e6916de51777e22b4837c1a84d" dependencies = [ - "aes 0.9.1", + "aes 0.9.2", "base64 0.21.7", "cbc", "ccm", "generic-array 0.14.7", "getrandom 0.2.17", - "getrandom 0.4.2", + "getrandom 0.4.3", "hkdf 0.13.0", "hmac 0.13.0", - "k256 0.14.0-rc.14", + "k256 0.14.0", "pbkdf2", "pcsc", "rand_core 0.6.4", @@ -5413,8 +5479,8 @@ dependencies = [ "lee", "log", "pcsc", - "rand 0.8.6", - "thiserror 2.0.18", + "rand 0.8.7", + "thiserror 2.0.20", "zeroize", ] @@ -5436,7 +5502,7 @@ dependencies = [ "convert_case 0.6.0", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -5493,7 +5559,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-util", "tower 0.5.3", @@ -5516,7 +5582,7 @@ dependencies = [ "serde", "serde-value", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -5540,7 +5606,7 @@ dependencies = [ "pin-project", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-util", "tracing", @@ -5548,9 +5614,9 @@ dependencies = [ [[package]] name = "lazy-regex" -version = "3.6.0" +version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bae91019476d3ec7147de9aa291cadb6d870abf2f3015d2da73a90325ac1496" +checksum = "4994ba703f78b083e2f7946dac9251abd83fd43a0365f030e99b69be5b4b9ef9" dependencies = [ "lazy-regex-proc_macros", "once_cell", @@ -5559,14 +5625,14 @@ dependencies = [ [[package]] name = "lazy-regex-proc_macros" -version = "3.6.0" +version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4de9c1e1439d8b7b3061b2d209809f447ca33241733d9a3c01eabf2dc8d94358" +checksum = "fd97232314824e6dbef1918a871bb93f51070455e3715bf26e19a6d01aa977a0" dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -5578,12 +5644,6 @@ dependencies = [ "spin", ] -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "lee" version = "0.1.0" @@ -5596,7 +5656,7 @@ dependencies = [ "k256 0.13.4", "lee_core", "log", - "rand 0.8.6", + "rand 0.8.7", "risc0-binfmt", "risc0-zkvm", "serde", @@ -5604,7 +5664,7 @@ dependencies = [ "sha2 0.10.9", "test-case", "test_methods", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -5621,7 +5681,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -5637,16 +5697,16 @@ dependencies = [ [[package]] name = "leptos" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efa3982e7fe36c1de68f91f3c9083124f389a975523881f3d7e3363362feda41" +checksum = "705e2951f3688e0c4f66bbb7a2702282782dcee716971dbd6209c2619d272479" dependencies = [ "any_spawner", "base64 0.22.1", "cfg-if", "either_of", "futures", - "getrandom 0.4.2", + "getrandom 0.4.3", "hydration_context", "leptos_config", "leptos_dom", @@ -5656,7 +5716,7 @@ dependencies = [ "oco_ref", "or_poisoned", "paste", - "rand 0.9.4", + "rand 0.9.5", "reactive_graph", "rustc-hash", "rustc_version", @@ -5667,7 +5727,7 @@ dependencies = [ "server_fn", "slotmap", "tachys", - "thiserror 2.0.18", + "thiserror 2.0.20", "throw_error", "typed-builder", "typed-builder-macro", @@ -5679,9 +5739,9 @@ dependencies = [ [[package]] name = "leptos_axum" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ac7734eed700b0170dffbfc93b03491ed1f306622d79625323a21ed0eedac0" +checksum = "513e2dd5fe81512b53304429b9ca77cceb954d23af88921c0c33119380f07cbe" dependencies = [ "any_spawner", "axum 0.8.9", @@ -5709,7 +5769,7 @@ dependencies = [ "config", "regex", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "typed-builder", ] @@ -5742,7 +5802,7 @@ dependencies = [ "quote", "rstml", "serde", - "syn 2.0.117", + "syn 2.0.119", "walkdir", ] @@ -5763,9 +5823,9 @@ dependencies = [ [[package]] name = "leptos_macro" -version = "0.8.16" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9360df573fb57582384a8b7640a3de94ce6501d49be3b69f637cf11a42da484b" +checksum = "96de6e8da9d4f1a7b74b447b317d590ebabb38709f588f7ee20564b773ccbcce" dependencies = [ "attribute-derive", "cfg-if", @@ -5781,7 +5841,7 @@ dependencies = [ "rstml", "rustc_version", "server_fn_macro", - "syn 2.0.117", + "syn 2.0.119", "uuid", ] @@ -5802,9 +5862,9 @@ dependencies = [ [[package]] name = "leptos_router" -version = "0.8.13" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c15158449162e099e2273442f7fd9b924f5cefd935d52af5755ec62aa819fa52" +checksum = "318c035b5995324c2f60900978ac67da3b21e6062a6e904f8b93b38eddc4e3a2" dependencies = [ "any_spawner", "either_of", @@ -5819,7 +5879,7 @@ dependencies = [ "rustc_version", "send_wrapper", "tachys", - "thiserror 2.0.18", + "thiserror 2.0.20", "url", "wasm-bindgen", "web-sys", @@ -5834,7 +5894,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -5867,9 +5927,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.186" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libloading" @@ -5883,18 +5943,18 @@ dependencies = [ [[package]] name = "liblzma" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6033b77c21d1f56deeae8014eb9fbe7bdf1765185a6c508b5ca82eeaed7f899" +checksum = "2fe0a34ca854fd4f20c07f696fc8675aec78f87d88d29f5e10257a7490a1b2e1" dependencies = [ "liblzma-sys", ] [[package]] name = "liblzma-sys" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a60851d15cd8c5346eca4ab8babff585be2ae4bc8097c067291d3ffe2add3b6" +checksum = "a0dad045e4b1b7b170be4b60b54b780cafb4490165461bac7d1cf7b703f61d5f" dependencies = [ "cc", "libc", @@ -5936,7 +5996,7 @@ dependencies = [ "multiaddr", "pin-project", "rw-stream-sink", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -5968,9 +6028,9 @@ dependencies = [ "libp2p-swarm", "quick-protobuf", "quick-protobuf-codec", - "rand 0.8.6", + "rand 0.8.7", "rand_core 0.6.4", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", "web-time", ] @@ -6003,9 +6063,9 @@ dependencies = [ "parking_lot", "pin-project", "quick-protobuf", - "rand 0.8.6", + "rand 0.8.7", "rw-stream-sink", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", "unsigned-varint 0.8.0", "web-time", @@ -6050,7 +6110,7 @@ dependencies = [ "libp2p-swarm", "quick-protobuf", "quick-protobuf-codec", - "rand 0.8.6", + "rand 0.8.7", "regex", "serde", "sha2 0.10.9", @@ -6075,7 +6135,7 @@ dependencies = [ "quick-protobuf", "quick-protobuf-codec", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", ] @@ -6091,11 +6151,11 @@ dependencies = [ "hkdf 0.12.4", "k256 0.13.4", "multihash", - "prost 0.14.3", - "rand 0.8.6", + "prost 0.14.4", + "rand 0.8.7", "serde", "sha2 0.10.9", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", "zeroize", ] @@ -6118,11 +6178,11 @@ dependencies = [ "libp2p-swarm", "quick-protobuf", "quick-protobuf-codec", - "rand 0.8.6", + "rand 0.8.7", "serde", "sha2 0.10.9", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", "uint", "web-time", @@ -6140,7 +6200,7 @@ dependencies = [ "libp2p-core", "libp2p-identity", "libp2p-swarm", - "rand 0.8.6", + "rand 0.8.7", "smallvec", "socket2 0.5.10", "tokio", @@ -6179,11 +6239,11 @@ dependencies = [ "libp2p-tls", "quinn", "quinn-proto", - "rand 0.8.6", + "rand 0.8.7", "ring", "rustls", "socket2 0.5.10", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tracing", ] @@ -6200,7 +6260,7 @@ dependencies = [ "libp2p-core", "libp2p-identity", "libp2p-swarm", - "rand 0.8.6", + "rand 0.8.7", "smallvec", "tracing", ] @@ -6215,7 +6275,7 @@ dependencies = [ "libp2p-core", "libp2p-identity", "libp2p-swarm", - "rand 0.8.6", + "rand 0.8.7", "tracing", ] @@ -6234,7 +6294,7 @@ dependencies = [ "libp2p-identity", "libp2p-swarm-derive", "multistream-select", - "rand 0.8.6", + "rand 0.8.7", "smallvec", "tokio", "tracing", @@ -6249,7 +6309,7 @@ checksum = "dd297cf53f0cb3dee4d2620bb319ae47ef27c702684309f682bdb7e55a18ae9c" dependencies = [ "heck", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -6263,7 +6323,7 @@ dependencies = [ "if-watch", "libc", "libp2p-core", - "socket2 0.6.4", + "socket2 0.6.5", "tokio", "tracing", ] @@ -6282,7 +6342,7 @@ dependencies = [ "ring", "rustls", "rustls-webpki", - "thiserror 2.0.18", + "thiserror 2.0.20", "x509-parser", "yasna", ] @@ -6304,9 +6364,9 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.17" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" +checksum = "28d0a00925a9f930d679b6789b721e3a7f9ed110f41b86d2497caa780c3a070a" dependencies = [ "libc", ] @@ -6343,7 +6403,7 @@ checksum = "47a1ccadd0bb5a32c196da536fd72c59183de24a055f6bf0513bf845fefab862" dependencies = [ "ark-bn254", "ark-ff", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "thiserror 1.0.69", ] @@ -6361,9 +6421,9 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" [[package]] name = "lock_api" @@ -6376,14 +6436,14 @@ dependencies = [ [[package]] name = "log" -version = "0.4.31" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "113b30b4cd05f7c06868fdb2854f66a7b9fece9a48425351cd532e810d74024f" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "logos-blockchain-api-service" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "bytes", @@ -6404,7 +6464,7 @@ dependencies = [ "overwatch", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-stream", "tracing", @@ -6413,7 +6473,7 @@ dependencies = [ [[package]] name = "logos-blockchain-blend" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "logos-blockchain-blend-crypto", "logos-blockchain-blend-message", @@ -6425,7 +6485,7 @@ dependencies = [ [[package]] name = "logos-blockchain-blend-crypto" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "blake2", "logos-blockchain-groth16", @@ -6433,13 +6493,13 @@ dependencies = [ "logos-blockchain-poseidon2", "logos-blockchain-utils", "rs-merkle-tree", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] name = "logos-blockchain-blend-message" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "blake2", "derivative", @@ -6456,7 +6516,7 @@ dependencies = [ "logos-blockchain-utils", "serde", "serde_with", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", "zeroize", ] @@ -6464,7 +6524,7 @@ dependencies = [ [[package]] name = "logos-blockchain-blend-network" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "either", "futures", @@ -6479,16 +6539,18 @@ dependencies = [ "logos-blockchain-key-management-system-keys", "logos-blockchain-libp2p", "logos-blockchain-log-targets", + "logos-blockchain-utils", + "tokio", "tracing", ] [[package]] name = "logos-blockchain-blend-proofs" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "ed25519-dalek", - "generic-array 1.4.3", + "generic-array 1.4.5", "hex", "logos-blockchain-blend-crypto", "logos-blockchain-codec", @@ -6497,16 +6559,16 @@ dependencies = [ "logos-blockchain-poq", "logos-blockchain-poseidon2", "logos-blockchain-utils", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "zeroize", ] [[package]] name = "logos-blockchain-blend-scheduling" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "derivative", @@ -6523,9 +6585,9 @@ dependencies = [ "logos-blockchain-log-targets", "logos-blockchain-utils", "multiaddr", - "rand 0.8.6", + "rand 0.8.7", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-stream", "tracing", @@ -6534,7 +6596,7 @@ dependencies = [ [[package]] name = "logos-blockchain-blend-service" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "fork_stream", @@ -6559,10 +6621,10 @@ dependencies = [ "logos-blockchain-tracing", "logos-blockchain-utils", "overwatch", - "rand 0.8.6", + "rand 0.8.7", "serde", "serde_with", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-stream", "tracing", @@ -6571,7 +6633,7 @@ dependencies = [ [[package]] name = "logos-blockchain-chain-broadcast-service" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "derivative", @@ -6585,7 +6647,7 @@ dependencies = [ [[package]] name = "logos-blockchain-chain-leader-service" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "futures", @@ -6605,9 +6667,9 @@ dependencies = [ "logos-blockchain-utils", "logos-blockchain-wallet-service", "overwatch", - "rand 0.8.6", + "rand 0.8.7", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-stream", "tracing", @@ -6617,7 +6679,7 @@ dependencies = [ [[package]] name = "logos-blockchain-chain-network-service" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "backon", @@ -6638,10 +6700,10 @@ dependencies = [ "logos-blockchain-utils", "lru", "overwatch", - "rand 0.8.6", + "rand 0.8.7", "serde", "serde_with", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-stream", "tracing", @@ -6651,7 +6713,7 @@ dependencies = [ [[package]] name = "logos-blockchain-chain-service" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "bytes", @@ -6672,7 +6734,7 @@ dependencies = [ "overwatch", "serde", "serde_with", - "thiserror 2.0.18", + "thiserror 2.0.20", "time", "tokio", "tracing", @@ -6682,8 +6744,8 @@ dependencies = [ [[package]] name = "logos-blockchain-circuits-build" -version = "0.5.5" -source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.5#32f1ac43f331f0eeff3a2a0aec0f153564d03583" +version = "0.5.6" +source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.6#07c439356435eb6a2f1f4a8daa973bd04bd0b088" dependencies = [ "dirs", "fd-lock", @@ -6694,16 +6756,16 @@ dependencies = [ [[package]] name = "logos-blockchain-circuits-common" -version = "0.5.5" -source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.5#32f1ac43f331f0eeff3a2a0aec0f153564d03583" +version = "0.5.6" +source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.6#07c439356435eb6a2f1f4a8daa973bd04bd0b088" dependencies = [ "logos-blockchain-circuits-types", ] [[package]] name = "logos-blockchain-circuits-poc-sys" -version = "0.5.5" -source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.5#32f1ac43f331f0eeff3a2a0aec0f153564d03583" +version = "0.5.6" +source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.6#07c439356435eb6a2f1f4a8daa973bd04bd0b088" dependencies = [ "logos-blockchain-circuits-build", "logos-blockchain-circuits-common", @@ -6712,8 +6774,8 @@ dependencies = [ [[package]] name = "logos-blockchain-circuits-pol-sys" -version = "0.5.5" -source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.5#32f1ac43f331f0eeff3a2a0aec0f153564d03583" +version = "0.5.6" +source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.6#07c439356435eb6a2f1f4a8daa973bd04bd0b088" dependencies = [ "logos-blockchain-circuits-build", "logos-blockchain-circuits-common", @@ -6722,8 +6784,8 @@ dependencies = [ [[package]] name = "logos-blockchain-circuits-poq-sys" -version = "0.5.5" -source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.5#32f1ac43f331f0eeff3a2a0aec0f153564d03583" +version = "0.5.6" +source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.6#07c439356435eb6a2f1f4a8daa973bd04bd0b088" dependencies = [ "logos-blockchain-circuits-build", "logos-blockchain-circuits-common", @@ -6733,15 +6795,15 @@ dependencies = [ [[package]] name = "logos-blockchain-circuits-prover" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "rust-rapidsnark", ] [[package]] name = "logos-blockchain-circuits-signature-sys" -version = "0.5.5" -source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.5#32f1ac43f331f0eeff3a2a0aec0f153564d03583" +version = "0.5.6" +source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.6#07c439356435eb6a2f1f4a8daa973bd04bd0b088" dependencies = [ "logos-blockchain-circuits-build", "logos-blockchain-circuits-common", @@ -6750,8 +6812,8 @@ dependencies = [ [[package]] name = "logos-blockchain-circuits-types" -version = "0.5.5" -source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.5#32f1ac43f331f0eeff3a2a0aec0f153564d03583" +version = "0.5.6" +source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.6#07c439356435eb6a2f1f4a8daa973bd04bd0b088" dependencies = [ "bytes", "libc", @@ -6760,30 +6822,30 @@ dependencies = [ [[package]] name = "logos-blockchain-codec" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "hex", "logos-blockchain-codec-macros", "logos-blockchain-groth16", "logos-blockchain-utils", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] name = "logos-blockchain-codec-macros" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "hex", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "logos-blockchain-common-http-client" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "futures", "hex", @@ -6795,10 +6857,10 @@ dependencies = [ "logos-blockchain-http-api-common", "logos-blockchain-key-management-system-keys", "logos-blockchain-log-targets", - "reqwest", + "reqwest 0.12.28", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio-util", "url", ] @@ -6806,7 +6868,7 @@ dependencies = [ [[package]] name = "logos-blockchain-config" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "hex", "logos-blockchain-codec", @@ -6818,15 +6880,15 @@ dependencies = [ "logos-blockchain-node", "logos-blockchain-tracing", "logos-blockchain-utils", - "num-bigint 0.4.6", - "rand 0.8.6", + "num-bigint 0.4.8", + "rand 0.8.7", "time", ] [[package]] name = "logos-blockchain-core" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "ark-ff", "bincode", @@ -6847,11 +6909,11 @@ dependencies = [ "logos-blockchain-utils", "logos-blockchain-utxotree", "multiaddr", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "rpds", "serde", "strum 0.27.2", - "thiserror 2.0.18", + "thiserror 2.0.20", "time", "tracing", ] @@ -6859,7 +6921,7 @@ dependencies = [ [[package]] name = "logos-blockchain-cryptarchia-engine" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "logos-blockchain-codec", "logos-blockchain-pol", @@ -6867,7 +6929,7 @@ dependencies = [ "rpds", "serde", "serde_with", - "thiserror 2.0.18", + "thiserror 2.0.20", "time", "tokio", "tracing", @@ -6876,7 +6938,7 @@ dependencies = [ [[package]] name = "logos-blockchain-cryptarchia-sync" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "bytes", "futures", @@ -6884,10 +6946,10 @@ dependencies = [ "libp2p-stream", "logos-blockchain-core", "logos-blockchain-cryptarchia-engine", - "rand 0.8.6", + "rand 0.8.7", "serde", "serde_with", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tracing", ] @@ -6895,35 +6957,34 @@ dependencies = [ [[package]] name = "logos-blockchain-dynamic-merkle" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ - "rpds", "serde", ] [[package]] name = "logos-blockchain-groth16" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "ark-bn254", "ark-ec", "ark-ff", "ark-groth16", "ark-serialize", - "generic-array 1.4.3", + "generic-array 1.4.5", "hex", - "num-bigint 0.4.6", - "rand 0.8.6", + "num-bigint 0.4.8", + "rand 0.8.7", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] name = "logos-blockchain-http-api-common" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "axum 0.7.9", "logos-blockchain-core", @@ -6944,12 +7005,12 @@ dependencies = [ [[package]] name = "logos-blockchain-key-management-system-keys" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "bytes", "ed25519-dalek", - "generic-array 1.4.3", + "generic-array 1.4.5", "hex", "logos-blockchain-codec", "logos-blockchain-groth16", @@ -6958,11 +7019,11 @@ dependencies = [ "logos-blockchain-poseidon2", "logos-blockchain-utils", "logos-blockchain-zksign", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "rand_core 0.6.4", "serde", "subtle", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tracing", "x25519-dalek", @@ -6972,17 +7033,17 @@ dependencies = [ [[package]] name = "logos-blockchain-key-management-system-macros" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "logos-blockchain-key-management-system-operators" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "logos-blockchain-blend-proofs", @@ -7000,7 +7061,7 @@ dependencies = [ [[package]] name = "logos-blockchain-key-management-system-service" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "logos-blockchain-key-management-system-keys", @@ -7009,7 +7070,7 @@ dependencies = [ "logos-blockchain-tracing", "overwatch", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tracing", ] @@ -7017,7 +7078,7 @@ dependencies = [ [[package]] name = "logos-blockchain-ledger" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "derivative", "logos-blockchain-blend-crypto", @@ -7031,19 +7092,19 @@ dependencies = [ "logos-blockchain-pol", "logos-blockchain-utils", "logos-blockchain-utxotree", - "num-bigint 0.4.6", - "rand 0.8.6", + "num-bigint 0.4.8", + "rand 0.8.7", "rpds", "serde", "serde_arrays", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", ] [[package]] name = "logos-blockchain-libp2p" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "backon", @@ -7060,10 +7121,10 @@ dependencies = [ "natpmp", "netdev", "num_enum", - "rand 0.8.6", + "rand 0.8.7", "serde", "serde_with", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tracing", "zerocopy", @@ -7072,7 +7133,7 @@ dependencies = [ [[package]] name = "logos-blockchain-log-targets" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "logos-blockchain-log-targets-macros", ] @@ -7080,28 +7141,28 @@ dependencies = [ [[package]] name = "logos-blockchain-log-targets-macros" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "logos-blockchain-merkle-tree" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "logos-blockchain-dynamic-merkle", "rpds", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] name = "logos-blockchain-mmr" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "ark-ff", "logos-blockchain-groth16", @@ -7109,13 +7170,13 @@ dependencies = [ "logos-blockchain-utils", "rpds", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] name = "logos-blockchain-network-service" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "futures", @@ -7126,7 +7187,7 @@ dependencies = [ "logos-blockchain-tracing", "logos-blockchain-utils", "overwatch", - "rand 0.8.6", + "rand 0.8.7", "rand_chacha 0.3.1", "serde", "tokio", @@ -7138,7 +7199,7 @@ dependencies = [ [[package]] name = "logos-blockchain-node" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "axum 0.7.9", @@ -7176,15 +7237,15 @@ dependencies = [ "logos-blockchain-tx-service", "logos-blockchain-utils", "logos-blockchain-wallet-service", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "nutype", "overwatch", - "rand 0.8.6", + "rand 0.8.7", "serde", "serde_json", "serde_with", "serde_yaml", - "thiserror 2.0.18", + "thiserror 2.0.20", "time", "tokio", "tokio-stream", @@ -7200,7 +7261,7 @@ dependencies = [ [[package]] name = "logos-blockchain-poc" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "logos-blockchain-circuits-poc-sys", "logos-blockchain-circuits-prover", @@ -7208,7 +7269,7 @@ dependencies = [ "logos-blockchain-groth16", "logos-blockchain-log-targets", "logos-blockchain-proofs-error", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "serde", "serde_json", "tracing", @@ -7217,7 +7278,7 @@ dependencies = [ [[package]] name = "logos-blockchain-pol" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "astro-float", "logos-blockchain-circuits-pol-sys", @@ -7227,7 +7288,7 @@ dependencies = [ "logos-blockchain-log-targets", "logos-blockchain-proofs-error", "logos-blockchain-utils", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "num-traits", "serde", "serde_json", @@ -7237,7 +7298,7 @@ dependencies = [ [[package]] name = "logos-blockchain-poq" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "logos-blockchain-circuits-poq-sys", "logos-blockchain-circuits-prover", @@ -7246,39 +7307,38 @@ dependencies = [ "logos-blockchain-log-targets", "logos-blockchain-pol", "logos-blockchain-proofs-error", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "serde", "serde_json", - "thiserror 2.0.18", "tracing", ] [[package]] name = "logos-blockchain-poseidon2" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "ark-bn254", "ark-ff", "jf-poseidon2", - "num-bigint 0.4.6", + "num-bigint 0.4.8", ] [[package]] name = "logos-blockchain-proofs-error" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "logos-blockchain-circuits-types", "logos-blockchain-groth16", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] name = "logos-blockchain-sdp-service" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "logos-blockchain-chain-service", @@ -7288,7 +7348,7 @@ dependencies = [ "logos-blockchain-tracing", "overwatch", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "time", "tokio", "tracing", @@ -7297,7 +7357,7 @@ dependencies = [ [[package]] name = "logos-blockchain-services-utils" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "bytes", @@ -7306,14 +7366,14 @@ dependencies = [ "logos-blockchain-log-targets", "overwatch", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", ] [[package]] name = "logos-blockchain-storage-service" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "bytes", @@ -7327,7 +7387,7 @@ dependencies = [ "overwatch", "rocksdb", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tracing", ] @@ -7335,7 +7395,7 @@ dependencies = [ [[package]] name = "logos-blockchain-system-sig-service" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-ctrlc", "async-trait", @@ -7347,7 +7407,7 @@ dependencies = [ [[package]] name = "logos-blockchain-time-service" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "futures", @@ -7360,7 +7420,7 @@ dependencies = [ "serde", "serde_with", "sntpc", - "thiserror 2.0.18", + "thiserror 2.0.20", "time", "tokio", "tokio-stream", @@ -7370,7 +7430,7 @@ dependencies = [ [[package]] name = "logos-blockchain-tracing" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "flate2", "logos-blockchain-log-targets", @@ -7380,7 +7440,7 @@ dependencies = [ "opentelemetry-otlp", "opentelemetry-semantic-conventions", "opentelemetry_sdk", - "rand 0.8.6", + "rand 0.8.7", "serde", "tokio", "tonic", @@ -7396,14 +7456,14 @@ dependencies = [ [[package]] name = "logos-blockchain-tracing-service" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "logos-blockchain-log-targets", "logos-blockchain-tracing", "overwatch", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "time", "tokio", "tracing", @@ -7414,7 +7474,7 @@ dependencies = [ [[package]] name = "logos-blockchain-tui-zone" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "bincode", "chrono", @@ -7425,8 +7485,8 @@ dependencies = [ "logos-blockchain-groth16", "logos-blockchain-key-management-system-service", "logos-blockchain-zone-sdk", - "rand 0.8.6", - "reqwest", + "rand 0.8.7", + "reqwest 0.12.28", "serde", "serde_json", "tokio", @@ -7439,7 +7499,7 @@ dependencies = [ [[package]] name = "logos-blockchain-tx-service" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "futures", @@ -7454,7 +7514,7 @@ dependencies = [ "overwatch", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-stream", "tracing", @@ -7464,7 +7524,7 @@ dependencies = [ [[package]] name = "logos-blockchain-utils" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "blake2", @@ -7475,12 +7535,12 @@ dependencies = [ "logos-blockchain-log-targets", "multiaddr", "overwatch", - "rand 0.8.6", + "rand 0.8.7", "serde", "serde_ignored", "serde_with", "serde_yaml", - "thiserror 2.0.18", + "thiserror 2.0.20", "time", "tokio", "tracing", @@ -7489,7 +7549,7 @@ dependencies = [ [[package]] name = "logos-blockchain-utxotree" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "ark-ff", "logos-blockchain-dynamic-merkle", @@ -7502,7 +7562,7 @@ dependencies = [ [[package]] name = "logos-blockchain-wallet" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "logos-blockchain-core", "logos-blockchain-cryptarchia-engine", @@ -7511,17 +7571,17 @@ dependencies = [ "logos-blockchain-log-targets", "logos-blockchain-mmr", "logos-blockchain-utils", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "rpds", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", ] [[package]] name = "logos-blockchain-wallet-service" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "bytes", @@ -7541,7 +7601,7 @@ dependencies = [ "logos-blockchain-wallet", "overwatch", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tracing", ] @@ -7549,7 +7609,7 @@ dependencies = [ [[package]] name = "logos-blockchain-zksign" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "logos-blockchain-circuits-prover", "logos-blockchain-circuits-signature-sys", @@ -7558,18 +7618,18 @@ dependencies = [ "logos-blockchain-log-targets", "logos-blockchain-poseidon2", "logos-blockchain-proofs-error", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "serde", "serde-big-array", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", ] [[package]] name = "logos-blockchain-zone-sdk" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "async-trait", "futures", @@ -7580,11 +7640,11 @@ dependencies = [ "logos-blockchain-http-api-common", "logos-blockchain-key-management-system-service", "logos-blockchain-log-targets", - "rand 0.8.6", - "reqwest", + "rand 0.8.7", + "reqwest 0.12.28", "rpds", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tracing", ] @@ -7706,7 +7766,7 @@ dependencies = [ "manyhow-macros", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -7728,7 +7788,7 @@ checksum = "757aee279b8bdbb9f9e676796fd459e4207a1f986e87886700abf589f5abf771" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -7760,9 +7820,9 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "matrixmultiply" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08" +checksum = "3f607c237553f086e7043417a51df26b2eb899d3caff94e6a67592ff992fedc7" dependencies = [ "autocfg", "rawpointer", @@ -7770,15 +7830,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.1" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "memmap2" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" dependencies = [ "libc", ] @@ -7809,7 +7869,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", "block", "core-graphics-types", "foreign-types 0.5.0", @@ -7846,7 +7906,7 @@ dependencies = [ "metrics-util", "quanta", "rustls", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tracing", ] @@ -7862,7 +7922,7 @@ dependencies = [ "hashbrown 0.16.1", "metrics", "quanta", - "rand 0.9.4", + "rand 0.9.5", "rand_xoshiro", "rapidhash", "sketches-ddsketch", @@ -7902,9 +7962,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" dependencies = [ "libc", "wasi", @@ -7948,7 +8008,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -7964,9 +8024,9 @@ dependencies = [ [[package]] name = "moka" -version = "0.12.15" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957228ad12042ee839f93c8f257b62b4c0ab5eaae1d4fa60de53b27c9d7c5046" +checksum = "4293f18e7567a1caf3c584855554377025c65e0aa445344d04171f5ad63d19b9" dependencies = [ "crossbeam-channel", "crossbeam-epoch", @@ -8017,12 +8077,13 @@ dependencies = [ [[package]] name = "multibase" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8694bb4835f452b0e3bb06dbebb1d6fc5385b6ca1caf2e55fd165c042390ec77" +checksum = "7e0e4a371cbf1dfd666b658ba137763edb23c45beb43cfe369b5593cd6b437b6" dependencies = [ "base-x", "base256emoji", + "base45", "data-encoding", "data-encoding-macro", ] @@ -8126,9 +8187,9 @@ dependencies = [ [[package]] name = "netlink-packet-core" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3463cbb78394cb0141e2c926b93fc2197e473394b761986eca3b9da2c63ae0f4" +checksum = "b897d7bd4f0af82e68d40d0344cf37e97f9c97ddf74a098de3e4da05e96ca395" dependencies = [ "paste", ] @@ -8153,10 +8214,10 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ce3636fa715e988114552619582b530481fd5ef176a1e5c1bf024077c2c9445" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", "libc", "log", - "netlink-packet-core 0.8.1", + "netlink-packet-core 0.8.2", ] [[package]] @@ -8173,16 +8234,17 @@ dependencies = [ [[package]] name = "netlink-proto" -version = "0.12.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b65d130ee111430e47eed7896ea43ca693c387f097dd97376bffafbf25812128" +checksum = "93af8261786086024cd5e96e0a991dd65ced07bbf7c233a487bbc96b971d5539" dependencies = [ "bytes", - "futures", + "futures-channel", + "futures-util", "log", - "netlink-packet-core 0.8.1", + "netlink-packet-core 0.8.2", "netlink-sys", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -8210,7 +8272,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", "cfg-if", "cfg_aliases", "libc", @@ -8222,7 +8284,7 @@ version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", "cfg-if", "cfg_aliases", "libc", @@ -8288,7 +8350,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ - "num-bigint 0.4.6", + "num-bigint 0.4.8", "num-complex", "num-integer", "num-iter", @@ -8309,9 +8371,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" dependencies = [ "num-integer", "num-traits", @@ -8328,7 +8390,7 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand 0.8.6", + "rand 0.8.7", "smallvec", "zeroize", ] @@ -8356,25 +8418,24 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "num-integer" -version = "0.1.46" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" dependencies = [ "num-traits", ] [[package]] name = "num-iter" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -8385,7 +8446,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "num-bigint 0.4.6", + "num-bigint 0.4.8", "num-integer", "num-traits", ] @@ -8419,7 +8480,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -8442,7 +8503,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.117", + "syn 2.0.119", "urlencoding", ] @@ -8479,7 +8540,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", ] [[package]] @@ -8525,7 +8586,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed0423ff9973dea4d6bd075934fdda86ebb8c05bdf9d6b0507067d4a1226371d" dependencies = [ "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -8571,7 +8632,7 @@ version = "0.10.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77823a27f0babb03091cb9ed9ef80af3b39dbc82f97e8fa530374b7dafd87a45" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", "cfg-if", "foreign-types 0.3.2", "libc", @@ -8587,7 +8648,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -8610,22 +8671,22 @@ dependencies = [ [[package]] name = "opentelemetry" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bcd6ae87133e903af7ef497404dda70c60d0ea14895fc8a5e6722754fc2a0" +checksum = "b0142c63252a9e054e68a4c61a5778f7b14f576274d593f8ce883d191a099682" dependencies = [ "futures-core", "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] name = "opentelemetry-appender-tracing" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef6a1ac5ca3accf562b8c306fa8483c85f4390f768185ab775f242f7fe8fdcc2" +checksum = "2c0080f0dc1d7c786f467cd85a4e395fcab11ee852004f39a29a18ab7c25d837" dependencies = [ "opentelemetry", "tracing", @@ -8635,67 +8696,69 @@ dependencies = [ [[package]] name = "opentelemetry-http" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d" +checksum = "5683015d09e2df236ef005b17f6f196f0d5f6313c4fa43a7b6a53b52776e4331" dependencies = [ "async-trait", "bytes", "http", "opentelemetry", - "reqwest", + "reqwest 0.13.4", ] [[package]] name = "opentelemetry-otlp" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f69cd6acbb9af919df949cd1ec9e5e7fdc2ef15d234b6b795aaa525cc02f71f" +checksum = "9966929966d17620d7c316c643ba62631826e10021409357772d5eea84f62c35" dependencies = [ "http", "opentelemetry", "opentelemetry-http", "opentelemetry-proto", "opentelemetry_sdk", - "prost 0.14.3", - "reqwest", - "thiserror 2.0.18", + "prost 0.14.4", + "reqwest 0.13.4", + "thiserror 2.0.20", "tokio", "tonic", + "tonic-types", ] [[package]] name = "opentelemetry-proto" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7175df06de5eaee9909d4805a3d07e28bb752c34cab57fa9cff549da596b30f" +checksum = "56d658ba1faf63f7b9c492cfbe6e0ec365440a16132d3270c1065f7b33f1b638" dependencies = [ "opentelemetry", "opentelemetry_sdk", - "prost 0.14.3", + "prost 0.14.4", "tonic", "tonic-prost", ] [[package]] name = "opentelemetry-semantic-conventions" -version = "0.31.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e62e29dfe041afb8ed2a6c9737ab57db4907285d999ef8ad3a59092a36bdc846" +checksum = "c913ac17a6c451661ee255f4625d143e51647ae78ebd969b75e41c4442f4fe47" [[package]] name = "opentelemetry_sdk" -version = "0.31.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ae4f5991976fd48df6d843de219ca6d31b01daaab2dad5af2badeded372bd" +checksum = "9b59f80e1ac4d5ff7a2db8fb6c80badb7f0f3f858211fba08dd9aaec750894f9" dependencies = [ "futures-channel", "futures-executor", "futures-util", "opentelemetry", "percent-encoding", - "rand 0.9.4", - "thiserror 2.0.18", + "portable-atomic", + "rand 0.9.5", + "thiserror 2.0.20", "tokio", "tokio-stream", ] @@ -8708,7 +8771,7 @@ checksum = "969ccca8ffc4fb105bd131a228107d5c9dd89d9d627edf3295cbe979156f9712" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -8740,7 +8803,7 @@ dependencies = [ "async-trait", "futures", "overwatch-derive", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-stream", "tokio-util", @@ -8756,7 +8819,7 @@ dependencies = [ "manyhow", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -8826,7 +8889,7 @@ dependencies = [ "regex", "regex-syntax", "structmeta", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -8872,7 +8935,7 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd833ecf8967e65934c49d3521a175929839bf6d0e497f3bd0d3a2ca08943da" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", "pcsc-sys", ] @@ -8967,7 +9030,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -9005,7 +9068,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared", - "rand 0.8.6", + "rand 0.8.7", ] [[package]] @@ -9034,7 +9097,7 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -9115,15 +9178,15 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" dependencies = [ - "der 0.8.0", + "der 0.8.1", "spki 0.8.0", ] [[package]] name = "pkg-config" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" [[package]] name = "plotters" @@ -9181,9 +9244,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "portable-atomic-util" @@ -9209,9 +9272,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" dependencies = [ "zerovec", ] @@ -9264,7 +9327,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -9283,14 +9346,15 @@ dependencies = [ [[package]] name = "primeorder" -version = "0.14.0-rc.14" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e56e6d67fdf5744e9e245ae571450fe584b91f5af261d0e40163b618e53a1f6" +checksum = "5c9f42978c78a00e3d68f69fc03e57a234debae69da4020a4fb588fcdcd07b06" dependencies = [ - "elliptic-curve 0.14.0", + "elliptic-curve 0.14.1", "once_cell", "primefield", "serdect 0.4.3", + "wnaf", ] [[package]] @@ -9307,7 +9371,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit 0.25.12+spec-1.1.0", + "toml_edit 0.25.13+spec-1.1.0", ] [[package]] @@ -9344,6 +9408,16 @@ dependencies = [ "quote", ] +[[package]] +name = "proc-macro-error-attr3" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0084e6206a967a2dad822180626b2f6b07a3b379325e8f1ec0438e33a469ba7" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "proc-macro-error2" version = "2.0.1" @@ -9353,7 +9427,19 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", +] + +[[package]] +name = "proc-macro-error3" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cf066225f2373bc711684792b69bdeac0356019b007e721090c24d92d5d5a50" +dependencies = [ + "proc-macro-error-attr3", + "proc-macro2", + "quote", + "syn 3.0.3", ] [[package]] @@ -9369,9 +9455,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] @@ -9384,7 +9470,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", "version_check", "yansi", ] @@ -9450,7 +9536,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -9461,7 +9547,7 @@ checksum = "0fcebfa99f03ae51220778316b37d24981e36322c82c24848f48c5bd0f64cbdb" dependencies = [ "enum-as-inner", "mime", - "reqwest", + "reqwest 0.12.28", "serde", "time", "url", @@ -9473,9 +9559,9 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", "num-traits", - "rand 0.9.4", + "rand 0.9.5", "rand_chacha 0.9.0", "rand_xorshift", "unarray", @@ -9493,12 +9579,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1" dependencies = [ "bytes", - "prost-derive 0.14.3", + "prost-derive 0.14.4", ] [[package]] @@ -9511,20 +9597,20 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "prost-derive" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" dependencies = [ "anyhow", "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -9538,11 +9624,11 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" +checksum = "f94967dc7688f3054c7fac87473ffae4cc4c3904800e2d9f5b857246d8963b0a" dependencies = [ - "prost 0.14.3", + "prost 0.14.4", ] [[package]] @@ -9607,9 +9693,9 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.9" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" dependencies = [ "bytes", "cfg_aliases", @@ -9619,8 +9705,8 @@ dependencies = [ "quinn-udp", "rustc-hash", "rustls", - "socket2 0.6.4", - "thiserror 2.0.18", + "socket2 0.6.5", + "thiserror 2.0.20", "tokio", "tracing", "web-time", @@ -9628,21 +9714,22 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.15" +version = "0.11.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fcb935c5bec503c2f0e306bdd3e58bb9029dcb14fa8d9ac76e3a5256ac0763e" +checksum = "04759210543be93709136e28212294a659ef5001836ff4eab4d663e4529bba83" dependencies = [ "bytes", "fastbloom", - "getrandom 0.3.4", + "getrandom 0.4.3", "lru-slab", - "rand 0.9.4", + "rand 0.10.2", + "rand_pcg", "ring", "rustc-hash", "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.18", + "thiserror 2.0.20", "tinyvec", "tracing", "web-time", @@ -9650,23 +9737,23 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.4", + "socket2 0.6.5", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "quote" -version = "1.0.45" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -9690,7 +9777,7 @@ dependencies = [ "proc-macro-utils", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -9713,9 +9800,9 @@ checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -9724,9 +9811,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.5", @@ -9734,12 +9821,12 @@ dependencies = [ [[package]] name = "rand" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ "chacha20", - "getrandom 0.4.2", + "getrandom 0.4.3", "rand_core 0.10.1", ] @@ -9787,6 +9874,15 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" +[[package]] +name = "rand_pcg" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core 0.10.1", +] + [[package]] name = "rand_xorshift" version = "0.4.0" @@ -9820,7 +9916,7 @@ version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", ] [[package]] @@ -9882,7 +9978,7 @@ dependencies = [ "send_wrapper", "serde", "slotmap", - "thiserror 2.0.18", + "thiserror 2.0.20", "web-sys", ] @@ -9905,15 +10001,15 @@ dependencies = [ [[package]] name = "reactive_stores_macro" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d8e790a5ae5ddf9b7fa380c728375b06858e0cca7d063a73b3408320c523e1" +checksum = "68072edd607edd30b9ebf57d984ba45d8ab8809e598d0f6046278373fb76a5a0" dependencies = [ "convert_case 0.11.0", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -9922,7 +10018,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", ] [[package]] @@ -9933,34 +10029,34 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.17", "libredox", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] name = "ref-cast" -version = "1.0.25" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.25" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -9970,9 +10066,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -9981,9 +10077,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "reqwest" @@ -9993,6 +10089,7 @@ checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64 0.22.1", "bytes", + "encoding_rs", "futures-channel", "futures-core", "futures-util", @@ -10006,6 +10103,7 @@ dependencies = [ "hyper-util", "js-sys", "log", + "mime", "native-tls", "percent-encoding", "pin-project-lite", @@ -10031,6 +10129,37 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "reqwest" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower 0.5.3", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "resolv-conf" version = "0.7.6" @@ -10049,11 +10178,11 @@ dependencies = [ [[package]] name = "rfc6979" -version = "0.6.0-pre.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9935425142ac6e252364413291d96c8bc9898d0876a801824c7af4eae397b689" +checksum = "b4a459cddafb3fe76b31fd8f1108007566c40301feb64dc7b54656eb7388172b" dependencies = [ - "ctutils", + "crypto-bigint 0.7.5", "hmac 0.13.0", ] @@ -10079,9 +10208,9 @@ checksum = "3df6368f71f205ff9c33c076d170dd56ebf68e8161c733c0caa07a7a5509ed53" [[package]] name = "risc0-binfmt" -version = "3.0.4" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1883f0c5d19b865f395209a137dcb29e56dc49951424967b8d0114c129f46e77" +checksum = "d836c6ad82f4ced7c61d5feedf905a17780312e393aa681d29cc0bbc5131672b" dependencies = [ "anyhow", "borsh", @@ -10090,7 +10219,7 @@ dependencies = [ "elf", "lazy_static", "postcard", - "rand 0.9.4", + "rand 0.9.5", "risc0-zkp", "risc0-zkvm-platform", "ruint", @@ -10101,9 +10230,9 @@ dependencies = [ [[package]] name = "risc0-build" -version = "3.0.5" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f89937fa1c424b188cc4cabf65335736eca9c1e3df79c127f48636f55682f3a4" +checksum = "bd8216cdd9f573808a94769767480b06ad1e74ae60841c9582fdf51b8e29ba53" dependencies = [ "anyhow", "cargo_metadata", @@ -10139,9 +10268,9 @@ dependencies = [ [[package]] name = "risc0-circuit-keccak" -version = "4.0.5" +version = "4.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f543c60287fece797a5da4209384ab1bfebd9644fcfe591e11b1aa85f1a02f8" +checksum = "7c731e12429eb4457e1ddc69c56ee7343a1e10b86e4aa55bc8f4d2b13734abb9" dependencies = [ "anyhow", "bytemuck", @@ -10161,9 +10290,9 @@ dependencies = [ [[package]] name = "risc0-circuit-keccak-sys" -version = "4.0.2" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8eae53a7bf1c09828dfd46ed5c942cefbf4bef3c4400f6758001569a834c462" +checksum = "7ca44fa0f46c2d0a2a3cbbb8cdfb9bc7941ec9baea0d1c8dff5e6710d890aee2" dependencies = [ "cc", "derive_more", @@ -10175,9 +10304,9 @@ dependencies = [ [[package]] name = "risc0-circuit-recursion" -version = "4.0.4" +version = "4.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2347e909c6b2a65584b5898f3802eec5b8c1b4b45329edfdd8587b6a04dd3357" +checksum = "40dd640122abcc67d4d4e4f055c68cbc3ad2efb8589c65c2b23d354632971b60" dependencies = [ "anyhow", "bytemuck", @@ -10186,7 +10315,7 @@ dependencies = [ "hex", "lazy-regex", "metal", - "rand 0.9.4", + "rand 0.9.5", "rayon", "risc0-circuit-recursion-sys", "risc0-core", @@ -10200,9 +10329,9 @@ dependencies = [ [[package]] name = "risc0-circuit-recursion-sys" -version = "4.0.2" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "132be7ccca4b39ec957cc37d5083ca2aee171407922352002c9812452a890b39" +checksum = "d75beadf2a106377bb16bd000d3bde141b12c08aa47ba80c28e4068f379bb1ab" dependencies = [ "glob", "risc0-build-kernel", @@ -10212,9 +10341,9 @@ dependencies = [ [[package]] name = "risc0-circuit-rv32im" -version = "4.0.4" +version = "4.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61676419814a818fdb5e10066b13c5488b3f54aa9668794bd06c99bc91bff1f2" +checksum = "cb11231aa4b74bcc0c8d16597893fbd7ea6f6a9ebbc35e16bfd06b467c7ee104" dependencies = [ "anyhow", "bit-vec", @@ -10230,7 +10359,7 @@ dependencies = [ "num-traits", "paste", "postcard", - "rand 0.9.4", + "rand 0.9.5", "rayon", "ringbuffer", "risc0-binfmt", @@ -10246,9 +10375,9 @@ dependencies = [ [[package]] name = "risc0-circuit-rv32im-sys" -version = "4.0.2" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d677ec41e475534e18e58889ef0626dcdabf5e918804ef847da0c0bbf300b3" +checksum = "e93ed1e691220660df5ac7af4864d8cf8a42e7fe615ef27171652658ec8cb9f1" dependencies = [ "cc", "derive_more", @@ -10260,9 +10389,9 @@ dependencies = [ [[package]] name = "risc0-core" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b956a976b8ce4713694dcc6c370b522a42ccef4ba45da5b6e57dbf26cdb7b1" +checksum = "d6eb2d2b2c6cac0e43cbb2202daacee1a2f24d0dfa03fd08887a11dc6defdcc1" dependencies = [ "bytemuck", "nvtx", @@ -10272,9 +10401,9 @@ dependencies = [ [[package]] name = "risc0-groth16" -version = "3.0.4" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc57e76bb87193d154ac5ee6ee352fbd7edabddab36f02a81f40a048e5ca14f9" +checksum = "b0ca702ea7d0162766defe7ed6a79bda4a747ad9e2684000a6edd14df0a6d1f3" dependencies = [ "anyhow", "ark-bn254", @@ -10285,7 +10414,7 @@ dependencies = [ "bytemuck", "cfg-if", "hex", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "num-traits", "risc0-binfmt", "risc0-core", @@ -10309,9 +10438,9 @@ dependencies = [ [[package]] name = "risc0-zkos-v1compat" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bd70cb45b5d37d025f25663b87c6b9dc9df7f413ee2068531a57f50b0eb95db" +checksum = "b8b0b598ba7946354b10ca5c56e382de801e6c7fce9fccad0396ec436bc5072b" dependencies = [ "include_bytes_aligned", "no_std_strings", @@ -10320,9 +10449,9 @@ dependencies = [ [[package]] name = "risc0-zkp" -version = "3.0.4" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f40d362a6c146ec6dc69208f539b92fd86e47b0dbc2083801423034a38155a2" +checksum = "21c0c921e5e2d44197940d387a45e29c6165e318b5a168fdfdbd50f50ba03678" dependencies = [ "anyhow", "blake2", @@ -10337,7 +10466,7 @@ dependencies = [ "ndarray", "parking_lot", "paste", - "rand 0.9.4", + "rand 0.9.5", "rand_core 0.9.5", "rayon", "risc0-core", @@ -10351,9 +10480,9 @@ dependencies = [ [[package]] name = "risc0-zkvm" -version = "3.0.5" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22b7eafb5d85be59cbd9da83f662cf47d834f1b836e14f675d1530b12c666867" +checksum = "a5d4f24ec767f71a1663a4d24cf9d02b6bfee44c64647cae677227817051007a" dependencies = [ "addr2line 0.24.2", "anyhow", @@ -10370,11 +10499,11 @@ dependencies = [ "hex", "keccak 0.1.6", "lazy-regex", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "num-traits", "object 0.36.7", "prost 0.13.5", - "rand 0.9.4", + "rand 0.9.5", "rayon", "risc0-binfmt", "risc0-build", @@ -10400,9 +10529,9 @@ dependencies = [ [[package]] name = "risc0-zkvm-platform" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4db893788c416287e2e1a87e6b8f5302511a04a45329e699d6a32a16874fd24f" +checksum = "2eb37a97ff7e8e4ee1b2a1c43ec143b4887759883c343507af9e4787a57914cd" dependencies = [ "bytemuck", "cfg-if", @@ -10474,9 +10603,9 @@ dependencies = [ "futures", "light-poseidon", "quote", - "rand 0.9.4", + "rand 0.9.5", "syn 1.0.109", - "thiserror 2.0.18", + "thiserror 2.0.20", "tiny-keccak", "tokio", ] @@ -10511,9 +10640,9 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.117", + "syn 2.0.119", "syn_derive", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -10525,7 +10654,7 @@ dependencies = [ "futures-channel", "futures-util", "log", - "netlink-packet-core 0.8.1", + "netlink-packet-core 0.8.2", "netlink-packet-route 0.28.0", "netlink-proto", "netlink-sys", @@ -10552,8 +10681,8 @@ checksum = "f5e99bff0393163bb25029a6af25d3d8d202ba5b5438a74d1bd8789f5c822970" dependencies = [ "borsh", "proptest", - "rand 0.8.6", - "rand 0.9.4", + "rand 0.8.7", + "rand 0.9.5", "ruint-macro", "serde_core", "valuable", @@ -10587,7 +10716,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.117", + "syn 2.0.119", "walkdir", ] @@ -10609,21 +10738,21 @@ dependencies = [ "anyhow", "cc", "chkstk_stub", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "num-traits", ] [[package]] name = "rustc-demangle" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" +checksum = "b74b56ffa8bb2830709a538c2cbcae9aa062db0d2a42563bfb09bdaae44020eb" [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustc_version" @@ -10649,7 +10778,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", "errno", "libc", "linux-raw-sys", @@ -10658,9 +10787,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.40" +version = "0.23.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" dependencies = [ "aws-lc-rs", "log", @@ -10686,9 +10815,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.1" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" dependencies = [ "web-time", "zeroize", @@ -10723,9 +10852,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.13" +version = "0.103.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +checksum = "0527518605e68109d875e248ea259b6758801cf165e4b2c2733ae3b51f12535a" dependencies = [ "aws-lc-rs", "ring", @@ -10735,9 +10864,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "ruzstd" @@ -10767,9 +10896,9 @@ checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "rzup" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d2aed296f203fa64bcb4b52069356dd86d6ec578593985b919b6995bee1f0ae" +checksum = "96909a7ea8fdf7e18da727d7facbc43eea8a4f77635e7ec75a69794dede16fb6" dependencies = [ "hex", "rsa", @@ -10779,7 +10908,7 @@ dependencies = [ "sha2 0.10.9", "strum 0.27.2", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.20", "toml 0.8.23", "yaml-rust2", ] @@ -10825,9 +10954,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" +checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" dependencies = [ "dyn-clone", "ref-cast", @@ -10838,14 +10967,14 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d115b50f4aaeea07e79c1912f645c7513d81715d0420f8bc77a18c6260b307f" +checksum = "d98c67716b46af2f0b8cf752abc930f6f9aecfbf671ecfb531db8a31dbe4e2ba" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] @@ -10868,7 +10997,7 @@ checksum = "22f968c5ea23d555e670b449c1c5e7b2fc399fdaec1d304a17cd48e288abc107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -10894,7 +11023,7 @@ checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" dependencies = [ "base16ct 1.0.0", "ctutils", - "der 0.8.0", + "der 0.8.1", "hybrid-array", "subtle", "zeroize", @@ -10915,7 +11044,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -10980,10 +11109,10 @@ dependencies = [ "logos-blockchain-key-management-system-service", "logos-blockchain-zone-sdk", "mempool", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "ping_core", "programs", - "rand 0.8.6", + "rand 0.8.7", "risc0-zkvm", "sequencer_core_metrics", "sequencer_stake_core", @@ -11029,7 +11158,7 @@ dependencies = [ "log", "mempool", "mockall", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "num-traits", "sequencer_core", "sequencer_stake_core", @@ -11037,7 +11166,7 @@ dependencies = [ "system_accounts", "tempfile", "test_programs", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-util", ] @@ -11059,7 +11188,7 @@ dependencies = [ "sequencer_rpc_server_actor_metrics", "sequencer_service_protocol", "sequencer_service_rpc", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", ] @@ -11139,24 +11268,28 @@ dependencies = [ name = "sequencer_storage_actor" version = "0.1.0" dependencies = [ + "chain_state", "common", "itertools 0.14.0", "kameo", "lee", "lee_core", "log", + "logos-blockchain-zone-sdk", "mockall", + "serde", + "serde_json", "storage", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", ] [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -11192,33 +11325,33 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] name = "serde_derive_internals" -version = "0.29.1" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +checksum = "f852137cce035d6a4df67ccce505ff6b3e9fd3a10e3e52b24dc71e650bb1a9bd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] @@ -11233,9 +11366,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.150" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", @@ -11263,18 +11396,18 @@ checksum = "f3faaf9e727533a19351a43cc5a8de957372163c7d35cc48c90b75cdda13c352" dependencies = [ "percent-encoding", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] name = "serde_repr" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] @@ -11309,9 +11442,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.20.0" +version = "3.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e72c1c2cb7b223fafb600a619537a871c2818583d619401b785e7c0b746ccde2" +checksum = "ee78f1fbe43ac4a0e47aadb3dbd357b69eb0d3793e948624cd03dd2750ab1c0a" dependencies = [ "base64 0.22.1", "bs58", @@ -11319,8 +11452,9 @@ dependencies = [ "hex", "indexmap 1.9.3", "indexmap 2.14.0", + "jiff", "schemars 0.9.0", - "schemars 1.2.1", + "schemars 1.2.2", "serde_core", "serde_json", "serde_with_macros", @@ -11329,14 +11463,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.20.0" +version = "3.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b90c488738ecb4fb0262f41f43bc40efc5868d9fb744319ddf5f5317f417bfac" +checksum = "8705578779c2b6bd90d84d66eb2e206b708b1a4d7b9f17641b293545bf1c7e46" dependencies = [ "darling 0.23.0", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -11374,9 +11508,9 @@ dependencies = [ [[package]] name = "server_fn" -version = "0.8.12" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d60e4c1dfccd91fe0990141f69f1d5cf5679797ad53aa1b45e5bd658eb119f0" +checksum = "be8559dd05af1b5b7e363a150616589d5a88af5187273f7f331ba0dae8922812" dependencies = [ "axum 0.8.9", "base64 0.22.1", @@ -11399,7 +11533,7 @@ dependencies = [ "serde_json", "serde_qs", "server_fn_macro_default", - "thiserror 2.0.18", + "thiserror 2.0.20", "throw_error", "tokio", "tower 0.5.3", @@ -11423,7 +11557,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.117", + "syn 2.0.119", "xxhash-rust", ] @@ -11434,14 +11568,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63eb08f80db903d3c42f64e60ebb3875e0305be502bdc064ec0a0eab42207f00" dependencies = [ "server_fn_macro", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "sha1" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8" dependencies = [ "cfg-if", "cpufeatures 0.2.17", @@ -11554,9 +11688,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" [[package]] name = "siphasher" @@ -11597,9 +11731,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" [[package]] name = "smart-default" @@ -11609,7 +11743,7 @@ checksum = "0eb01866308440fc64d6c44d9e86c5cc17adfe33c4d6eed55da9145044d0ffc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -11620,9 +11754,9 @@ checksum = "e8e2fb0f499abb4d162f2bedad68f5ef91a1682b5a03596ddb67efd37768d100" [[package]] name = "snap" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" +checksum = "199905e6153d6405f9728fe44daace35f8f837bbf830bb6e85fbd5828709a886" [[package]] name = "sntpc" @@ -11646,9 +11780,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", "windows-sys 0.61.2", @@ -11666,7 +11800,7 @@ dependencies = [ "http", "httparse", "log", - "rand 0.8.6", + "rand 0.8.7", "sha1", ] @@ -11696,7 +11830,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" dependencies = [ "base64ct", - "der 0.8.0", + "der 0.8.1", ] [[package]] @@ -11716,9 +11850,9 @@ dependencies = [ "digest 0.10.7", "hex", "keccak 0.1.6", - "rand 0.8.6", + "rand 0.8.7", "sha3 0.10.9", - "thiserror 2.0.18", + "thiserror 2.0.20", "zerocopy", "zeroize", ] @@ -11730,7 +11864,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d904e7009df136af5297832a3ace3370cd14ff1546a232f4f185036c2736fcac" dependencies = [ "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -11757,7 +11891,7 @@ dependencies = [ "rocksdb", "system_accounts", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.20", "zstd", ] @@ -11785,7 +11919,7 @@ dependencies = [ "proc-macro2", "quote", "structmeta-derive", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -11796,7 +11930,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -11826,7 +11960,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -11838,7 +11972,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -11866,9 +12000,20 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" dependencies = [ "proc-macro2", "quote", @@ -11884,7 +12029,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -11904,7 +12049,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -11913,7 +12058,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d8a928f38f1bc873f28e0d2ba8298ad65374a6ac2241dabd297271531a736cd" dependencies = [ - "syn 2.0.117", + "syn 2.0.119", "synthez-codegen", "synthez-core", ] @@ -11924,7 +12069,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fb83b8df4238e11746984dfb3819b155cd270de0e25847f45abad56b3671047" dependencies = [ - "syn 2.0.117", + "syn 2.0.119", "synthez-core", ] @@ -11937,7 +12082,7 @@ dependencies = [ "proc-macro2", "quote", "sealed", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -11960,7 +12105,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -11971,7 +12116,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.1", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -12000,9 +12145,9 @@ dependencies = [ [[package]] name = "tachys" -version = "0.2.15" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2989c94c59db8497727875aa561d4d0daa3cc79b5774d5ced48263f7091beff1" +checksum = "a92ba81187437cc5df4281f2326a2e13cc81e8f96448292d1112388e2025ca66" dependencies = [ "any_spawner", "async-trait", @@ -12060,7 +12205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.2", + "getrandom 0.4.3", "once_cell", "rustix", "windows-sys 0.61.2", @@ -12080,7 +12225,7 @@ dependencies = [ "percent-encoding", "pest", "pest_derive", - "rand 0.8.6", + "rand 0.8.7", "regex", "serde", "serde_json", @@ -12122,7 +12267,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -12133,7 +12278,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", "test-case-core", ] @@ -12156,7 +12301,7 @@ dependencies = [ "lee_core", "log", "logos-blockchain-key-management-system-service", - "num-bigint 0.4.6", + "num-bigint 0.4.8", "programs", "sequencer_core", "sequencer_service", @@ -12234,7 +12379,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-stream", "tokio-util", @@ -12245,7 +12390,7 @@ dependencies = [ [[package]] name = "testing-framework" version = "0.0.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=97d5e104fc20ce6e2fb404f8a9364afcb181a3e5#97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=4a0564b71b825d19ab1446e4b089aebc2ee8167a#4a0564b71b825d19ab1446e4b089aebc2ee8167a" dependencies = [ "anyhow", "async-trait", @@ -12273,9 +12418,9 @@ dependencies = [ "logos-blockchain-time-service", "logos-blockchain-tx-service", "logos-blockchain-utils", - "num-bigint 0.4.6", - "rand 0.8.6", - "reqwest", + "num-bigint 0.4.8", + "rand 0.8.7", + "reqwest 0.12.28", "serde", "serde_json", "serde_yaml", @@ -12286,7 +12431,7 @@ dependencies = [ "testing-framework-runner-compose", "testing-framework-runner-k8s", "testing-framework-runner-local", - "thiserror 2.0.18", + "thiserror 2.0.20", "time", "tokio", "tracing", @@ -12301,7 +12446,7 @@ dependencies = [ "async-trait", "testing-framework-core", "testing-framework-runner-local", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", ] @@ -12318,12 +12463,12 @@ dependencies = [ "futures", "parking_lot", "prometheus-http-query", - "rand 0.8.6", - "reqwest", + "rand 0.8.7", + "reqwest 0.12.28", "serde", "serde_json", "serde_yaml", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tracing", ] @@ -12335,13 +12480,13 @@ source = "git+https://github.com/logos-blockchain/logos-blockchain-testing.git?r dependencies = [ "anyhow", "async-trait", - "reqwest", + "reqwest 0.12.28", "serde", "serde_json", "tempfile", "tera", "testing-framework-core", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-retry", "tracing", @@ -12360,14 +12505,14 @@ dependencies = [ "cfgsync-core", "k8s-openapi", "kube", - "reqwest", + "reqwest 0.12.28", "rustls", "serde", "serde_json", "serde_yaml", "tempfile", "testing-framework-core", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-retry", "tracing", @@ -12381,13 +12526,13 @@ source = "git+https://github.com/logos-blockchain/logos-blockchain-testing.git?r dependencies = [ "async-trait", "fs_extra", - "reqwest", + "reqwest 0.12.28", "serde", "serde_yaml", "sha2 0.10.9", "tempfile", "testing-framework-core", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tokio-retry", "tracing", @@ -12427,11 +12572,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.20", ] [[package]] @@ -12442,25 +12587,25 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] @@ -12476,12 +12621,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.47" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" dependencies = [ "deranged", - "itoa", "num-conv", "powerfmt", "serde_core", @@ -12491,15 +12635,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" dependencies = [ "num-conv", "time-core", @@ -12516,9 +12660,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" dependencies = [ "displaydoc", "zerovec", @@ -12536,9 +12680,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" dependencies = [ "tinyvec_macros", ] @@ -12568,9 +12712,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.52.3" +version = "1.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" dependencies = [ "bytes", "libc", @@ -12578,7 +12722,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.4", + "socket2 0.6.5", "tokio-macros", "tracing", "windows-sys 0.61.2", @@ -12586,13 +12730,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.7.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] @@ -12612,7 +12756,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a129d95275ebf4c493ec53bf0f8cd95f5ac161bc4f381700809a54f595d4470" dependencies = [ "pin-project-lite", - "rand 0.10.1", + "rand 0.10.2", "tokio", ] @@ -12628,9 +12772,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b" dependencies = [ "futures-core", "pin-project-lite", @@ -12652,14 +12796,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" dependencies = [ "bytes", "futures-core", "futures-io", "futures-sink", + "libc", "pin-project-lite", "slab", "tokio", @@ -12694,15 +12839,15 @@ dependencies = [ [[package]] name = "toml" -version = "1.1.2+spec-1.1.0" +version = "1.1.4+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +checksum = "3aace63f4bbcdfc2c965b059de67119c89c4017a70d633be6c104910f67056f5" dependencies = [ "serde_core", "serde_spanned 1.1.1", "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", - "winnow 1.0.3", + "winnow 1.0.4", ] [[package]] @@ -12748,23 +12893,23 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.12+spec-1.1.0" +version = "0.25.13+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" +checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b" dependencies = [ "indexmap 2.14.0", "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", - "winnow 1.0.3", + "winnow 1.0.4", ] [[package]] name = "toml_parser" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" dependencies = [ - "winnow 1.0.3", + "winnow 1.0.4", ] [[package]] @@ -12775,9 +12920,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "toml_writer" -version = "1.1.1+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" [[package]] name = "tonic" @@ -12798,7 +12943,7 @@ dependencies = [ "hyper-util", "percent-encoding", "pin-project", - "socket2 0.6.4", + "socket2 0.6.5", "sync_wrapper", "tokio", "tokio-stream", @@ -12815,7 +12960,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0" dependencies = [ "bytes", - "prost 0.14.3", + "prost 0.14.4", + "tonic", +] + +[[package]] +name = "tonic-types" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab1b02061f83d519bba3caa167f88f261ef05720ab8ebc954ade70de3348e8" +dependencies = [ + "prost 0.14.4", + "prost-types 0.14.4", "tonic", ] @@ -12860,7 +13016,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ "base64 0.22.1", - "bitflags 2.12.1", + "bitflags 2.13.1", "bytes", "futures-core", "futures-util", @@ -12914,7 +13070,7 @@ checksum = "050686193eb999b4bb3bc2acfa891a13da00f79734704c4b8b4ef1a10b368a3c" dependencies = [ "crossbeam-channel", "symlink", - "thiserror 2.0.18", + "thiserror 2.0.20", "time", "tracing-subscriber 0.3.23", ] @@ -12927,7 +13083,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -12987,7 +13143,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8d1ad78bf74c1790b0825ddc35ad1bb9498736c51c8437796b81cadf4916cd8" dependencies = [ "loki-api", - "reqwest", + "reqwest 0.12.28", "serde", "serde_json", "snap", @@ -13002,9 +13158,9 @@ dependencies = [ [[package]] name = "tracing-opentelemetry" -version = "0.32.1" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac28f2d093c6c477eaa76b23525478f38de514fa9aeb1285738d4b97a9552fc" +checksum = "adbc64cba7137545b8044cb1fe9814f7aacf3c6b5f9b45be8bb5db538befdb26" dependencies = [ "js-sys", "opentelemetry", @@ -13060,14 +13216,14 @@ checksum = "b19a4867a870f6edc4c283f2b455804b1879c0baf0e642f26b03ed8ee262d9d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "triomphe" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd69c5aa8f924c7519d6372789a74eac5b94fb0f8fcf0d4a97eb0bfc3e785f39" +checksum = "b40688ea6389c8171614b25491f71d4a27946e0c7ce2da1c6de27e25abf1a0ae" [[package]] name = "try-lock" @@ -13086,9 +13242,9 @@ dependencies = [ "http", "httparse", "log", - "rand 0.9.4", + "rand 0.9.5", "sha1", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -13124,7 +13280,7 @@ checksum = "076a02dc54dd46795c2e9c8282ed40bcfb1e22747e955de9389a1de28190fb26" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -13141,9 +13297,9 @@ checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "typetag" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5a897b12c6c1151ad0b138b8db50252dc301f93bc3b027db05eec82aeed298c" +checksum = "c90e86058a30d42a1a928dfb4b49bb33c98c3a2b4909492e6b0881cd94798ec2" dependencies = [ "erased-serde", "inventory", @@ -13154,13 +13310,13 @@ dependencies = [ [[package]] name = "typetag-impl" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf808357c6ed7e13ba0f3277ec8d8f21b2d501274895104263985330c726c1c5" +checksum = "f153acc4e99a5f2a5aefa09fb078be54e26271b2813f6041200b224c098d8328" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] @@ -13171,9 +13327,9 @@ checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "uint" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909988d098b2f738727b161a106cfc7cab00c539c2687a8836f8e565976fb53e" +checksum = "6f9227a75a5a540a464c832ad4a4195dbdbecd8787610a56262721fde6f04f90" dependencies = [ "byteorder", "crunchy", @@ -13274,11 +13430,11 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0" +checksum = "972d7902c8735f2695410b8aed7df6ed12a47394aa1c8d7af49f0497b731a94d" dependencies = [ - "base64 0.22.1", + "base64 0.23.1", "flate2", "log", "percent-encoding", @@ -13291,11 +13447,11 @@ dependencies = [ [[package]] name = "ureq-proto" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c" +checksum = "da5f78b09e6941e1a0f2e30e695e4b120377b54d5e0aec11b594bb57b3971613" dependencies = [ - "base64 0.22.1", + "base64 0.23.1", "http", "httparse", "log", @@ -13320,12 +13476,6 @@ version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" -[[package]] -name = "utf8-width" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1292c0d970b54115d14f2492fe0170adf21d68a1de108eebc51c1df4f346a091" - [[package]] name = "utf8-zero" version = "0.8.1" @@ -13365,7 +13515,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -13377,7 +13527,7 @@ dependencies = [ "axum 0.7.9", "mime_guess", "regex", - "reqwest", + "reqwest 0.12.28", "rust-embed", "serde", "serde_json", @@ -13394,11 +13544,11 @@ checksum = "e2eebbbfe4093922c2b6734d7c679ebfebd704a0d7e56dfcb0d05818ce28977d" [[package]] name = "uuid" -version = "1.23.2" +version = "1.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7" +checksum = "2cefc03fd367c0c6d4305de1b312cf00248c4114f4a0418ce6a6af769e3b0bd9" dependencies = [ - "getrandom 0.4.2", + "getrandom 0.4.3", "js-sys", "serde_core", "wasm-bindgen", @@ -13422,16 +13572,15 @@ dependencies = [ [[package]] name = "validator_derive" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7df16e474ef958526d1205f6dda359fdfab79d9aa6d54bafcb92dcd07673dca" +checksum = "240e4b81c20a1d6d50d1d7265c658dfbd204e8b9ac4d80f3c931f39462196335" dependencies = [ - "darling 0.20.11", - "once_cell", - "proc-macro-error2", + "darling 0.23.0", + "proc-macro-error3", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -13518,7 +13667,7 @@ dependencies = [ "log", "optfield", "programs", - "rand 0.8.6", + "rand 0.8.7", "rpassword", "sequencer_service_rpc", "serde", @@ -13527,7 +13676,7 @@ dependencies = [ "system_accounts", "tempfile", "testnet_initial_state", - "thiserror 2.0.18", + "thiserror 2.0.20", "token_core", "tokio", "url", @@ -13570,27 +13719,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.3+wasi-0.2.9" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen 0.51.0", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.122" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" dependencies = [ "cfg-if", "once_cell", @@ -13601,9 +13741,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.72" +version = "0.4.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" +checksum = "6b7777d5cc23d0e91404e53ce2d5e8ec7acae3026b16233dba62cd3246457950" dependencies = [ "js-sys", "wasm-bindgen", @@ -13611,9 +13751,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.122" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -13621,48 +13761,26 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.122" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.122" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap 2.14.0", - "wasm-encoder", - "wasmparser", -] - [[package]] name = "wasm-streams" version = "0.4.2" @@ -13691,9 +13809,9 @@ dependencies = [ [[package]] name = "wasm_split_helpers" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0cb6d1008be3c4c5abc31a407bfb8c8449ae14efc8561c1db821f79b9614b0a" +checksum = "ab578aae2fe2916edaea06843187d50f87b0965622da0ceef648edca27b385ba" dependencies = [ "async-once-cell", "wasm_split_macros", @@ -13701,33 +13819,21 @@ dependencies = [ [[package]] name = "wasm_split_macros" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a659ffe5c7f4538aa6357c07e3d73221cc61eba03bd9a081e14bc91ed09b8c" +checksum = "3e653af7ee4a9ef0fce481a9ec6f43cb78de20d0cdb4f4f5862e1dc6e407e6c8" dependencies = [ "base16", "quote", "sha2 0.10.9", - "syn 2.0.117", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags 2.12.1", - "hashbrown 0.15.5", - "indexmap 2.14.0", - "semver", + "syn 2.0.119", ] [[package]] name = "web-sys" -version = "0.3.99" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" +checksum = "c435338968042f4f59a557f690a253676d47ce13ceb55d70100e7facf6620a30" dependencies = [ "js-sys", "wasm-bindgen", @@ -13749,23 +13855,23 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e" dependencies = [ - "webpki-root-certs 1.0.7", + "webpki-root-certs 1.0.9", ] [[package]] name = "webpki-root-certs" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" +checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" dependencies = [ "rustls-pki-types", ] [[package]] name = "webpki-roots" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" +checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" dependencies = [ "rustls-pki-types", ] @@ -13916,7 +14022,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -13927,7 +14033,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -14195,112 +14301,24 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" dependencies = [ "memchr", ] -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - [[package]] name = "wit-bindgen" version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap 2.14.0", - "prettyplease", - "syn 2.0.117", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn 2.0.117", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags 2.12.1", - "indexmap 2.14.0", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap 2.14.0", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] - [[package]] name = "wnaf" -version = "0.14.0-rc.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f86421f2a70c9e6cab8d84c99fb62d8761d355bd1285443a7e7ccad15aa515f2" +checksum = "ab12e7090f27e2ffd9322651492942d50c2926094af30601e1964337db39daf1" dependencies = [ "ff 0.14.0", "group 0.14.0", @@ -14328,9 +14346,9 @@ dependencies = [ [[package]] name = "writeable" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" [[package]] name = "wyz" @@ -14366,7 +14384,7 @@ dependencies = [ "nom 7.1.3", "oid-registry", "rusticata-macros", - "thiserror 2.0.18", + "thiserror 2.0.20", "time", ] @@ -14382,9 +14400,9 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.28" +version = "0.8.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" +checksum = "e450f9b2ed1dff33c94c12589a87338689467b9c4f5d8a5710bd09a847d2c8a7" [[package]] name = "xmltree" @@ -14397,9 +14415,9 @@ dependencies = [ [[package]] name = "xxhash-rust" -version = "0.8.15" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3" +checksum = "aee1b19627c7c60102ab80d3a9cbe18de90bfe03bfa6c3715447681f0e8c8af6" [[package]] name = "yaml-rust2" @@ -14429,9 +14447,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -14446,28 +14464,28 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.50" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1" +checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.50" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639" +checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -14487,35 +14505,35 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", "synstructure", ] [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "zerotrie" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" dependencies = [ "displaydoc", "yoke", @@ -14524,9 +14542,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ "yoke", "zerofrom", @@ -14535,13 +14553,13 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.3" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] @@ -14573,15 +14591,15 @@ dependencies = [ "flate2", "indexmap 2.14.0", "memchr", - "thiserror 2.0.18", + "thiserror 2.0.20", "zopfli", ] [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" [[package]] name = "zopfli" diff --git a/Cargo.toml b/Cargo.toml index e6d6c9b6c..2630ff252 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -211,15 +211,16 @@ async-stream = "0.3.6" strum = { version = "0.28.0", features = ["derive"] } mockall = "0.15.0" -logos-blockchain-common-http-client = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" } -logos-blockchain-key-management-system-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" } -logos-blockchain-codec = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" } -logos-blockchain-core = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" } -logos-blockchain-chain-broadcast-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" } -logos-blockchain-chain-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" } -logos-blockchain-zone-sdk = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" } -logos-blockchain-http-api-common = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" } -logos-blockchain-testing-framework = { package = "testing-framework", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "97d5e104fc20ce6e2fb404f8a9364afcb181a3e5" } +logos-blockchain-common-http-client = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "4a0564b71b825d19ab1446e4b089aebc2ee8167a" } +logos-blockchain-key-management-system-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "4a0564b71b825d19ab1446e4b089aebc2ee8167a" } +logos-blockchain-codec = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "4a0564b71b825d19ab1446e4b089aebc2ee8167a" } +logos-blockchain-core = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "4a0564b71b825d19ab1446e4b089aebc2ee8167a" } +logos-blockchain-chain-broadcast-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "4a0564b71b825d19ab1446e4b089aebc2ee8167a" } +logos-blockchain-chain-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "4a0564b71b825d19ab1446e4b089aebc2ee8167a" } +logos-blockchain-zone-sdk = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "4a0564b71b825d19ab1446e4b089aebc2ee8167a" } +logos-blockchain-http-api-common = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "4a0564b71b825d19ab1446e4b089aebc2ee8167a" } + +logos-blockchain-testing-framework = { package = "testing-framework", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "4a0564b71b825d19ab1446e4b089aebc2ee8167a" } testing-framework-app = { git = "https://github.com/logos-blockchain/logos-blockchain-testing.git", rev = "db880d61155db3a4f32177ef16b0f1e4bf22b1f6" } testing-framework-core = { git = "https://github.com/logos-blockchain/logos-blockchain-testing.git", rev = "db880d61155db3a4f32177ef16b0f1e4bf22b1f6" } diff --git a/artifacts/lee/privacy_preserving_circuit/privacy_preserving_circuit.bin b/artifacts/lee/privacy_preserving_circuit/privacy_preserving_circuit.bin index bdb7c684b..c56ab5e49 100644 Binary files a/artifacts/lee/privacy_preserving_circuit/privacy_preserving_circuit.bin and b/artifacts/lee/privacy_preserving_circuit/privacy_preserving_circuit.bin differ diff --git a/artifacts/lez/programs/amm.bin b/artifacts/lez/programs/amm.bin index 5908e7e35..9543f6ac9 100644 Binary files a/artifacts/lez/programs/amm.bin and b/artifacts/lez/programs/amm.bin differ diff --git a/artifacts/lez/programs/associated_token_account.bin b/artifacts/lez/programs/associated_token_account.bin index 27ce81da7..08679aac8 100644 Binary files a/artifacts/lez/programs/associated_token_account.bin and b/artifacts/lez/programs/associated_token_account.bin differ diff --git a/artifacts/lez/programs/authenticated_transfer.bin b/artifacts/lez/programs/authenticated_transfer.bin index b203abed2..7223396b7 100644 Binary files a/artifacts/lez/programs/authenticated_transfer.bin and b/artifacts/lez/programs/authenticated_transfer.bin differ diff --git a/artifacts/lez/programs/bridge.bin b/artifacts/lez/programs/bridge.bin index 8740f78c9..e06885ab4 100644 Binary files a/artifacts/lez/programs/bridge.bin and b/artifacts/lez/programs/bridge.bin differ diff --git a/artifacts/lez/programs/bridge_lock.bin b/artifacts/lez/programs/bridge_lock.bin index 6639f16b3..669e1d14b 100644 Binary files a/artifacts/lez/programs/bridge_lock.bin and b/artifacts/lez/programs/bridge_lock.bin differ diff --git a/artifacts/lez/programs/clock.bin b/artifacts/lez/programs/clock.bin index 59d14a880..8ebd2f490 100644 Binary files a/artifacts/lez/programs/clock.bin and b/artifacts/lez/programs/clock.bin differ diff --git a/artifacts/lez/programs/cross_zone_inbox.bin b/artifacts/lez/programs/cross_zone_inbox.bin index 343a18bc5..5c870374d 100644 Binary files a/artifacts/lez/programs/cross_zone_inbox.bin and b/artifacts/lez/programs/cross_zone_inbox.bin differ diff --git a/artifacts/lez/programs/cross_zone_outbox.bin b/artifacts/lez/programs/cross_zone_outbox.bin index 95e647aac..4926abf73 100644 Binary files a/artifacts/lez/programs/cross_zone_outbox.bin and b/artifacts/lez/programs/cross_zone_outbox.bin differ diff --git a/artifacts/lez/programs/faucet.bin b/artifacts/lez/programs/faucet.bin index cbe6c3100..8f0ba5b06 100644 Binary files a/artifacts/lez/programs/faucet.bin and b/artifacts/lez/programs/faucet.bin differ diff --git a/artifacts/lez/programs/pinata.bin b/artifacts/lez/programs/pinata.bin index 6850d7532..a43ee0273 100644 Binary files a/artifacts/lez/programs/pinata.bin and b/artifacts/lez/programs/pinata.bin differ diff --git a/artifacts/lez/programs/pinata_token.bin b/artifacts/lez/programs/pinata_token.bin index 62d1fe279..2c2a3650c 100644 Binary files a/artifacts/lez/programs/pinata_token.bin and b/artifacts/lez/programs/pinata_token.bin differ diff --git a/artifacts/lez/programs/ping_receiver.bin b/artifacts/lez/programs/ping_receiver.bin index 60b71e942..022cd9a13 100644 Binary files a/artifacts/lez/programs/ping_receiver.bin and b/artifacts/lez/programs/ping_receiver.bin differ diff --git a/artifacts/lez/programs/ping_sender.bin b/artifacts/lez/programs/ping_sender.bin index 6a75873ac..e65d235a5 100644 Binary files a/artifacts/lez/programs/ping_sender.bin and b/artifacts/lez/programs/ping_sender.bin differ diff --git a/artifacts/lez/programs/sequencer_stake.bin b/artifacts/lez/programs/sequencer_stake.bin index 314e927b0..fcd8c6145 100644 Binary files a/artifacts/lez/programs/sequencer_stake.bin and b/artifacts/lez/programs/sequencer_stake.bin differ diff --git a/artifacts/lez/programs/token.bin b/artifacts/lez/programs/token.bin index d5205c4c0..9afb28aaa 100644 Binary files a/artifacts/lez/programs/token.bin and b/artifacts/lez/programs/token.bin differ diff --git a/artifacts/lez/programs/vault.bin b/artifacts/lez/programs/vault.bin index a1bd960f5..e92dffd4f 100644 Binary files a/artifacts/lez/programs/vault.bin and b/artifacts/lez/programs/vault.bin differ diff --git a/artifacts/lez/programs/wrapped_token.bin b/artifacts/lez/programs/wrapped_token.bin index 4bad6b150..c86547283 100644 Binary files a/artifacts/lez/programs/wrapped_token.bin and b/artifacts/lez/programs/wrapped_token.bin differ diff --git a/integration_tests/Cargo.toml b/integration_tests/Cargo.toml index 56aab0f18..a523c3682 100644 --- a/integration_tests/Cargo.toml +++ b/integration_tests/Cargo.toml @@ -40,9 +40,11 @@ sequencer_stake_core.workspace = true programs.workspace = true test_programs.workspace = true testnet_initial_state.workspace = true +chain_state.workspace = true logos-blockchain-core.workspace = true logos-blockchain-key-management-system-service.workspace = true +logos-blockchain-http-api-common.workspace = true logos-blockchain-testing-framework.workspace = true logos-blockchain-zone-sdk.workspace = true testing-framework-app.workspace = true @@ -52,6 +54,9 @@ testing-framework-core.workspace = true anyhow.workspace = true async-trait.workspace = true bytesize.workspace = true +borsh.workspace = true +reqwest.workspace = true +futures.workspace = true cucumber = { features = [ "macros", "output-junit", diff --git a/integration_tests/tests/bridge.rs b/integration_tests/tests/bridge.rs index 6fc48c6a8..23dc4f54e 100644 --- a/integration_tests/tests/bridge.rs +++ b/integration_tests/tests/bridge.rs @@ -3,21 +3,42 @@ reason = "We don't care about these in tests" )] -use std::time::Duration; +use std::{collections::HashSet, ops::Deref as _, time::Duration}; use anyhow::Context as _; +use borsh::BorshSerialize; use common::transaction::LeeTransaction; +use futures::StreamExt as _; use integration_tests::{ TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext, utils::{account_balance, get_account}, + wait_for_indexer_to_catch_up, }; use lee::{ - execute_and_prove, privacy_preserving_transaction, program::Program, public_transaction, + AccountId, execute_and_prove, privacy_preserving_transaction, program::Program, + public_transaction, }; use lee_core::{InputAccountIdentity, account::AccountWithMetadata}; +use logos_blockchain_core::mantle::ops::channel::deposit::DepositOp; +use logos_blockchain_http_api_common::bodies::{ + channel::ChannelDepositRequestBody, + wallet::{ + balance::WalletBalanceResponseBody, + transfer_funds::{WalletTransferFundsRequestBody, WalletTransferFundsResponseBody}, + }, +}; +use logos_blockchain_zone_sdk::{ + CommonHttpClient, ZoneMessage, + adapter::NodeHttpClient, + node_types::{ChannelId, Inputs}, + sequencer::ZoneSequencer, +}; use sequencer_service_rpc::RpcClient as _; +use test_fixtures::{config::bedrock_channel_id, public_mention}; use tokio::test; -// const TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK: Duration = Duration::from_mins(2); +use wallet::cli::{Command, execute_subcommand, programs::bridge::BridgeSubcommand}; + +const TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK: Duration = Duration::from_mins(2); #[test] async fn public_bridge_deposit_invocation_is_dropped() -> anyhow::Result<()> { @@ -227,386 +248,388 @@ async fn private_bridge_deposit_invocation_is_dropped() -> anyhow::Result<()> { Ok(()) } -// async fn submit_bedrock_deposit( -// bedrock_addr: std::net::SocketAddr, -// bedrock_account_pk: &str, -// recipient_id: AccountId, -// amount: u64, -// ) -> anyhow::Result<()> { -// #[derive(BorshSerialize)] -// struct DepositMetadata { -// recipient_id: AccountId, -// } - -// // Encode deposit metadata -// let metadata = borsh::to_vec(&DepositMetadata { recipient_id }) -// .context("Failed to encode deposit metadata")? -// .try_into() -// .context("Encoded metadata is too big")?; - -// let channel_id = integration_tests::config::bedrock_channel_id(); -// let client = reqwest::Client::new(); - -// let mut balance = bedrock_wallet_balance(bedrock_addr, bedrock_account_pk).await?; - -// log::info!( -// "Queried Bedrock balance for key {bedrock_account_pk}: {:?}", -// balance.balance -// ); - -// if balance.balance < amount { -// anyhow::bail!( -// "Bedrock wallet with key {bedrock_account_pk} has insufficient balance {:?} for -// deposit amount {:?}", balance.balance, -// amount -// ); -// } - -// let mut selected_note_id = balance -// .notes -// .iter() -// .find_map(|(note_id, value)| (*value == amount).then_some(*note_id)); - -// if selected_note_id.is_none() { -// let transfer_body = WalletTransferFundsRequestBody { -// tip: None, -// change_public_key: balance.address, -// funding_public_keys: vec![balance.address], -// recipient_public_key: balance.address, -// amount, -// }; - -// let transfer_response = client -// .post(format!( -// "http://{bedrock_addr}/wallet/transactions/transfer-funds" -// )) -// .json(&transfer_body) -// .send() -// .await -// .context("Failed to submit Bedrock transfer-funds request")?; -// let transfer_response = check_response_success(transfer_response).await?; - -// let transfer: WalletTransferFundsResponseBody = transfer_response -// .json() -// .await -// .context("Failed to decode Bedrock transfer-funds response")?; - -// log::info!( -// "Submitted transfer-funds to create exact deposit note, tx hash {:?}", -// transfer.hash -// ); - -// let mut found_note = None; -// for _ in 0..20 { -// tokio::time::sleep(Duration::from_millis(500)).await; -// balance = bedrock_wallet_balance(bedrock_addr, bedrock_account_pk).await?; -// found_note = balance -// .notes -// .iter() -// .find_map(|(note_id, value)| (*value == amount).then_some(*note_id)); -// if found_note.is_some() { -// break; -// } -// } - -// selected_note_id = found_note; -// } - -// let Some(selected_note_id) = selected_note_id else { -// anyhow::bail!( -// "Failed to locate exact-value note {amount:?} for Bedrock deposit; available notes: -// {:?}", balance.notes, -// ); -// }; - -// let body = ChannelDepositRequestBody { -// tip: None, -// deposit: DepositOp { -// channel_id, -// inputs: Inputs::new(selected_note_id), -// metadata, -// }, -// change_public_key: balance.address, -// funding_public_keys: vec![balance.address], -// max_tx_fee: u64::MAX.into(), -// }; - -// let response = client -// .post(format!("http://{bedrock_addr}/channel/deposit")) -// .json(&body) -// .send() -// .await -// .context("Failed to submit Bedrock deposit request")?; -// let response = check_response_success(response).await?; - -// let body_text = response -// .text() -// .await -// .unwrap_or_else(|_| "".to_owned()); -// log::info!( -// "Successfully submitted Bedrock deposit request for recipient {recipient_id} and amount -// {amount}, response body: {body_text}", ); - -// Ok(()) -// } - -// /// The Bedrock wallet state of `bedrock_account_pk`: its total balance and the -// /// notes it owns, keyed by note id. -// async fn bedrock_wallet_balance( -// bedrock_addr: std::net::SocketAddr, -// bedrock_account_pk: &str, -// ) -> anyhow::Result { -// let response = reqwest::Client::new() -// .get(format!( -// "http://{bedrock_addr}/wallet/{bedrock_account_pk}/balance" -// )) -// .send() -// .await -// .context("Failed to query Bedrock wallet balance")?; - -// check_response_success(response) -// .await? -// .json::() -// .await -// .context("Failed to decode Bedrock balance response") -// } - -// async fn check_response_success(response: reqwest::Response) -> anyhow::Result -// { if response.status().is_success() { -// Ok(response) -// } else { -// let status = response.status(); -// let body_text = response.text().await.unwrap_or_default(); -// anyhow::bail!("Request failed with status {status} and body {body_text}"); -// } -// } - -// async fn wait_for_vault_balance( -// ctx: &TestContext, -// vault_id: AccountId, -// expected_balance: u128, -// ) -> anyhow::Result<()> { -// let timeout = TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK -// + Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS); -// tokio::time::timeout(timeout, async { -// loop { -// let balance = account_balance(ctx, vault_id).await?; -// if balance == expected_balance { -// return Ok(()); -// } -// tokio::time::sleep(Duration::from_millis(500)).await; -// } -// }) -// .await -// .with_context(|| { -// format!("Timed out waiting for vault {vault_id} balance to reach {expected_balance}") -// })? -// } - -// /// Test deposit and withdraw round trip. -// /// -// /// Implemented as one test instead of two separate tests for deposit and withdraw, because the -// /// withdraw test depends on the deposit to set up the necessary state (funds in vault) for -// testing /// withdraw functionality. -// #[test] -// async fn bedrock_deposit_claim_and_withdraw_round_trip_succeeds() -> anyhow::Result<()> { -// let mut ctx = TestContext::new().await?; - -// let bedrock_account_pk = "2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26"; -// let recipient_id = ctx.existing_public_accounts()[0]; -// let amount = 1_u64; -// let vault_program_id = programs::vault().id(); -// let recipient_vault_id = vault_core::compute_vault_account_id(vault_program_id, -// recipient_id); - -// let vault_balance_before = account_balance(&ctx, recipient_vault_id).await?; -// let recipient_balance_before = account_balance(&ctx, recipient_id).await?; - -// // Submit deposit to Bedrock -// submit_bedrock_deposit(ctx.bedrock_addr(), bedrock_account_pk, recipient_id, amount) -// .await -// .context("Failed to submit Bedrock deposit for round-trip setup")?; - -// // Wait for vault to receive the deposit (minted from bridge to vault) -// wait_for_vault_balance( -// &ctx, -// recipient_vault_id, -// vault_balance_before + u128::from(amount), -// ) -// .await?; - -// // Now claim funds from vault back to recipient -// let nonces = ctx -// .wallet() -// .get_accounts_nonces(&[recipient_id]) -// .await -// .context("Failed to get nonce for vault claim")?; - -// let signing_key = ctx -// .wallet() -// .storage() -// .key_chain() -// .pub_account_signing_key(recipient_id) -// .with_context(|| format!("Missing signing key for account {recipient_id}"))?; - -// let claim_message = public_transaction::Message::try_new( -// vault_program_id, -// vec![recipient_id, recipient_vault_id], -// nonces, -// vault_core::Instruction::Claim { -// amount: u128::from(amount), -// }, -// ) -// .context("Failed to build vault claim message")?; - -// let claim_witness_set = -// public_transaction::WitnessSet::for_message(&claim_message, &[signing_key]); -// let claim_tx = LeeTransaction::Public(lee::PublicTransaction::new( -// claim_message, -// claim_witness_set, -// )); - -// let claim_hash = ctx.sequencer_client().send_transaction(claim_tx).await?; - -// tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; - -// let claim_on_chain = ctx.sequencer_client().get_transaction(claim_hash).await?; -// let vault_balance_after_claim = account_balance(&ctx, recipient_vault_id).await?; -// let recipient_balance_after_claim = account_balance(&ctx, recipient_id).await?; - -// assert!( -// claim_on_chain.is_some(), -// "Vault claim transaction must be included on-chain" -// ); -// assert_eq!( -// vault_balance_after_claim, vault_balance_before, -// "Vault balance should return to initial state after claim" -// ); -// assert_eq!( -// recipient_balance_after_claim, -// recipient_balance_before + u128::from(amount), -// "Recipient balance should increase by claimed amount" -// ); - -// // The indexer must replay the deposit and claim blocks and reach the same -// // state as the sequencer — including the bridge system account the deposit -// // modifies, which is the case the hot fix unblocks. -// wait_for_indexer_to_catch_up(&ctx).await?; -// let bridge_account_id = system_accounts::bridge_account_id(); -// for account_id in [recipient_id, recipient_vault_id, bridge_account_id] { -// let indexer_account = indexer_service_rpc::RpcClient::get_account( -// // `deref` is needed for correct trait resolution -// // of the async `get_account` method on `RpcClient` -// ctx.indexer_client().deref(), -// account_id.into(), -// ) -// .await?; -// let sequencer_account = get_account(&ctx, account_id).await?; -// assert_eq!( -// indexer_account, -// sequencer_account.into(), -// "Indexer and sequencer diverged for account {account_id} after deposit" -// ); -// } - -// // Withdraw back to Bedrock and wait for finalized withdraw event. -// let sender_id = recipient_id; - -// let observer = create_zone_indexer_observer(ctx.bedrock_addr())?; -// let observe_fut = -// wait_for_finalized_withdraw_op(&observer, ctx.bedrock_addr(), amount, -// bedrock_account_pk); - -// let withdraw_fut = execute_subcommand( -// ctx.wallet_mut(), -// Command::Bridge(BridgeSubcommand::Withdraw { -// from: public_mention(sender_id), -// amount, -// bedrock_account_pk: bedrock_account_pk.to_owned(), -// }), -// ); - -// let (observe_result, withdraw_result) = tokio::join!(observe_fut, withdraw_fut); - -// withdraw_result.context("Failed to execute wallet bridge withdraw command")?; - -// observe_result -// .context("Failed while waiting for finalized withdraw event from zone indexer")?; - -// // Sleep to observe sequencer log about validated withdraw event -// tokio::time::sleep(Duration::from_secs(1)).await; - -// Ok(()) -// } - -// fn create_zone_indexer_observer( -// bedrock_addr: std::net::SocketAddr, -// ) -> anyhow::Result> { -// let bedrock_url = integration_tests::config::addr_to_url( -// integration_tests::config::UrlProtocol::Http, -// bedrock_addr, -// ) -// .context("Failed to convert Bedrock addr to URL for zone indexer observer")?; - -// let node = NodeHttpClient::new(CommonHttpClient::new(None), bedrock_url); - -// Ok(ZoneIndexer::new( -// integration_tests::config::bedrock_channel_id(), -// node, -// )) -// } - -// /// Waits for a finalized withdraw that pays `expected_amount` to `receiver_pk`. -// /// -// /// A withdraw op releases channel-owned notes and carries nothing but their -// /// ids — the value and recipient live in the note itself. A released note keeps -// /// its id, value and public key, so the pairing is checked on the receiver's -// /// Bedrock wallet: one of the released notes must land there with the expected -// /// value. -// async fn wait_for_finalized_withdraw_op( -// observer: &ZoneIndexer, -// bedrock_addr: std::net::SocketAddr, -// expected_amount: u64, -// receiver_pk: &str, -// ) -> anyhow::Result<()> { -// let timeout = TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK -// + Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS); - -// tokio::time::timeout(timeout, async { -// // The wallet can trail the channel event, so released notes accumulate -// // across polls instead of being checked once when first observed. -// let mut released_notes = HashSet::new(); - -// loop { -// let stream = observer -// .follow() -// .await -// .context("Failed to read zone indexer message batch")?; -// let mut stream = std::pin::pin!(stream); - -// while let Some(message) = stream.next().await { -// log::info!("Observed zone message {message:?}"); - -// if let ZoneMessage::Withdraw(withdraw) = message { -// released_notes.extend(withdraw.inputs.iter().copied()); -// } -// } - -// if !released_notes.is_empty() { -// let balance = bedrock_wallet_balance(bedrock_addr, receiver_pk).await?; -// if released_notes -// .iter() -// .any(|note_id| balance.notes.get(note_id) == Some(&expected_amount)) -// { -// return Ok(()); -// } -// } - -// tokio::time::sleep(Duration::from_millis(500)).await; -// } -// }) -// .await -// .with_context(|| { -// format!("Timed out waiting for finalized withdraw message with amount {expected_amount}") -// })? -// } +async fn submit_bedrock_deposit( + bedrock_addr: std::net::SocketAddr, + bedrock_account_pk: &str, + recipient_id: AccountId, + amount: u64, +) -> anyhow::Result<()> { + #[derive(BorshSerialize)] + struct DepositMetadata { + recipient_id: AccountId, + } + + // Encode deposit metadata + let metadata = borsh::to_vec(&DepositMetadata { recipient_id }) + .context("Failed to encode deposit metadata")? + .try_into() + .context("Encoded metadata is too big")?; + + let channel_id = integration_tests::config::bedrock_channel_id(); + let client = reqwest::Client::new(); + + let mut balance = bedrock_wallet_balance(bedrock_addr, bedrock_account_pk).await?; + + log::info!( + "Queried Bedrock balance for key {bedrock_account_pk}: {:?}", + balance.balance + ); + + if balance.balance < amount { + anyhow::bail!( + "Bedrock wallet with key {bedrock_account_pk} has insufficient balance {:?} for +deposit amount {:?}", + balance.balance, + amount + ); + } + + let mut selected_note_id = balance + .notes + .iter() + .find_map(|(note_id, value)| (*value == amount).then_some(*note_id)); + + if selected_note_id.is_none() { + let transfer_body = WalletTransferFundsRequestBody { + tip: None, + change_public_key: balance.address, + funding_public_keys: vec![balance.address], + recipient_public_key: balance.address, + amount, + }; + + let transfer_response = client + .post(format!( + "http://{bedrock_addr}/wallet/transactions/transfer-funds" + )) + .json(&transfer_body) + .send() + .await + .context("Failed to submit Bedrock transfer-funds request")?; + let transfer_response = check_response_success(transfer_response).await?; + + let transfer: WalletTransferFundsResponseBody = transfer_response + .json() + .await + .context("Failed to decode Bedrock transfer-funds response")?; + + log::info!( + "Submitted transfer-funds to create exact deposit note, tx hash {:?}", + transfer.hash + ); + + let mut found_note = None; + for _ in 0..20 { + tokio::time::sleep(Duration::from_millis(500)).await; + balance = bedrock_wallet_balance(bedrock_addr, bedrock_account_pk).await?; + found_note = balance + .notes + .iter() + .find_map(|(note_id, value)| (*value == amount).then_some(*note_id)); + if found_note.is_some() { + break; + } + } + + selected_note_id = found_note; + } + + let Some(selected_note_id) = selected_note_id else { + anyhow::bail!( + "Failed to locate exact-value note {amount:?} for Bedrock deposit; available notes: +{:?}", + balance.notes, + ); + }; + + let body = ChannelDepositRequestBody { + tip: None, + deposit: DepositOp { + channel_id, + inputs: Inputs::new(selected_note_id), + metadata, + }, + change_public_key: balance.address, + funding_public_keys: vec![balance.address], + max_tx_fee: u64::MAX.into(), + }; + + let response = client + .post(format!("http://{bedrock_addr}/channel/deposit")) + .json(&body) + .send() + .await + .context("Failed to submit Bedrock deposit request")?; + let response = check_response_success(response).await?; + + let body_text = response + .text() + .await + .unwrap_or_else(|_| "".to_owned()); + log::info!( + "Successfully submitted Bedrock deposit request for recipient {recipient_id} and amount +{amount}, response body: {body_text}", + ); + + Ok(()) +} + +/// The Bedrock wallet state of `bedrock_account_pk`: its total balance and the +/// notes it owns, keyed by note id. +async fn bedrock_wallet_balance( + bedrock_addr: std::net::SocketAddr, + bedrock_account_pk: &str, +) -> anyhow::Result { + let response = reqwest::Client::new() + .get(format!( + "http://{bedrock_addr}/wallet/{bedrock_account_pk}/balance" + )) + .send() + .await + .context("Failed to query Bedrock wallet balance")?; + + check_response_success(response) + .await? + .json::() + .await + .context("Failed to decode Bedrock balance response") +} + +async fn check_response_success(response: reqwest::Response) -> anyhow::Result { + if response.status().is_success() { + Ok(response) + } else { + let status = response.status(); + let body_text = response.text().await.unwrap_or_default(); + anyhow::bail!("Request failed with status {status} and body {body_text}"); + } +} + +async fn wait_for_vault_balance( + ctx: &TestContext, + vault_id: AccountId, + expected_balance: u128, +) -> anyhow::Result<()> { + let timeout = TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK + .saturating_add(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)); + tokio::time::timeout(timeout, async { + loop { + let balance = account_balance(ctx, vault_id).await?; + if balance == expected_balance { + return Ok(()); + } + tokio::time::sleep(Duration::from_millis(500)).await; + } + }) + .await + .with_context(|| { + format!("Timed out waiting for vault {vault_id} balance to reach {expected_balance}") + })? +} + +/// Test deposit and withdraw round trip. +/// +/// Implemented as one test instead of two separate tests for deposit and withdraw, because the +/// withdraw test depends on the deposit to set up the necessary state (funds in vault) for +/// testing withdraw functionality. +#[test] +async fn bedrock_deposit_claim_and_withdraw_round_trip_succeeds() -> anyhow::Result<()> { + let mut ctx = TestContext::new().await?; + + let bedrock_account_pk = "2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26"; + let recipient_id = ctx.existing_public_accounts()[0]; + let amount = 1_u64; + let vault_program_id = programs::vault().id(); + let recipient_vault_id = vault_core::compute_vault_account_id(vault_program_id, recipient_id); + + let vault_balance_before = account_balance(&ctx, recipient_vault_id).await?; + let recipient_balance_before = account_balance(&ctx, recipient_id).await?; + + // Submit deposit to Bedrock + submit_bedrock_deposit(ctx.bedrock_addr(), bedrock_account_pk, recipient_id, amount) + .await + .context("Failed to submit Bedrock deposit for round-trip setup")?; + + // Wait for vault to receive the deposit (minted from bridge to vault) + wait_for_vault_balance( + &ctx, + recipient_vault_id, + vault_balance_before + u128::from(amount), + ) + .await?; + + // Now claim funds from vault back to recipient + let nonces = ctx + .wallet() + .get_accounts_nonces(&[recipient_id]) + .await + .context("Failed to get nonce for vault claim")?; + + let signing_key = ctx + .wallet() + .storage() + .key_chain() + .pub_account_signing_key(recipient_id) + .with_context(|| format!("Missing signing key for account {recipient_id}"))?; + + let claim_message = public_transaction::Message::try_new( + vault_program_id, + vec![recipient_id, recipient_vault_id], + nonces, + vault_core::Instruction::Claim { + amount: u128::from(amount), + }, + ) + .context("Failed to build vault claim message")?; + + let claim_witness_set = + public_transaction::WitnessSet::for_message(&claim_message, &[signing_key]); + let claim_tx = LeeTransaction::Public(lee::PublicTransaction::new( + claim_message, + claim_witness_set, + )); + + let claim_hash = ctx.sequencer_client().send_transaction(claim_tx).await?; + + tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; + + let claim_on_chain = ctx.sequencer_client().get_transaction(claim_hash).await?; + let vault_balance_after_claim = account_balance(&ctx, recipient_vault_id).await?; + let recipient_balance_after_claim = account_balance(&ctx, recipient_id).await?; + + assert!( + claim_on_chain.is_some(), + "Vault claim transaction must be included on-chain" + ); + assert_eq!( + vault_balance_after_claim, vault_balance_before, + "Vault balance should return to initial state after claim" + ); + assert_eq!( + recipient_balance_after_claim, + recipient_balance_before + u128::from(amount), + "Recipient balance should increase by claimed amount" + ); + + // The indexer must replay the deposit and claim blocks and reach the same + // state as the sequencer — including the bridge system account the deposit + // modifies, which is the case the hot fix unblocks. + wait_for_indexer_to_catch_up(&ctx).await?; + let bridge_account_id = system_accounts::bridge_account_id(); + for account_id in [recipient_id, recipient_vault_id, bridge_account_id] { + let indexer_account = indexer_service_rpc::RpcClient::get_account( + // `deref` is needed for correct trait resolution + // of the async `get_account` method on `RpcClient` + ctx.indexer_client().deref(), + account_id.into(), + ) + .await?; + let sequencer_account = get_account(&ctx, account_id).await?; + assert_eq!( + indexer_account, + sequencer_account.into(), + "Indexer and sequencer diverged for account {account_id} after deposit" + ); + } + + // Withdraw back to Bedrock and wait for finalized withdraw event. + let sender_id = recipient_id; + + let mut observer = create_zone_indexer_observer(ctx.bedrock_addr(), bedrock_channel_id())?; + let observe_fut = wait_for_finalized_withdraw_op( + &mut observer, + ctx.bedrock_addr(), + amount, + bedrock_account_pk, + ); + + let withdraw_fut = execute_subcommand( + ctx.wallet_mut(), + Command::Bridge(BridgeSubcommand::Withdraw { + from: public_mention(sender_id), + amount, + bedrock_account_pk: bedrock_account_pk.to_owned(), + }), + ); + + let (observe_result, withdraw_result) = tokio::join!(observe_fut, withdraw_fut); + + withdraw_result.context("Failed to execute wallet bridge withdraw command")?; + + observe_result + .context("Failed while waiting for finalized withdraw event from zone indexer")?; + + // Sleep to observe sequencer log about validated withdraw event + tokio::time::sleep(Duration::from_secs(1)).await; + + Ok(()) +} + +fn create_zone_indexer_observer( + bedrock_addr: std::net::SocketAddr, + channel_id: ChannelId, +) -> anyhow::Result> { + let bedrock_url = integration_tests::config::addr_to_url( + integration_tests::config::UrlProtocol::Http, + bedrock_addr, + ) + .context("Failed to convert Bedrock addr to URL for zone indexer observer")?; + + let node = NodeHttpClient::new(CommonHttpClient::new(None), bedrock_url); + + Ok(chain_state::consistency::new_indexer( + channel_id, node, None, + )) +} + +/// Waits for a finalized withdraw that pays `expected_amount` to `receiver_pk`. +/// +/// A withdraw op releases channel-owned notes and carries nothing but their +/// ids — the value and recipient live in the note itself. A released note keeps +/// its id, value and public key, so the pairing is checked on the receiver's +/// Bedrock wallet: one of the released notes must land there with the expected +/// value. +async fn wait_for_finalized_withdraw_op( + observer: &mut ZoneSequencer, + bedrock_addr: std::net::SocketAddr, + expected_amount: u64, + receiver_pk: &str, +) -> anyhow::Result<()> { + let timeout = TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK + .saturating_add(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)); + + tokio::time::timeout(timeout, async { + // The wallet can trail the channel event, so released notes accumulate + // across polls instead of being checked once when first observed. + let mut released_notes = HashSet::new(); + + loop { + let stream = chain_state::consistency::next_messages(observer); + let mut stream = std::pin::pin!(stream); + + while let Some((message, _)) = stream.next().await { + log::info!("Observed zone message {message:?}"); + + if let ZoneMessage::Withdraw(withdraw) = message { + released_notes.extend(withdraw.inputs.iter().copied()); + } + } + + if !released_notes.is_empty() { + let balance = bedrock_wallet_balance(bedrock_addr, receiver_pk).await?; + if released_notes + .iter() + .any(|note_id| balance.notes.get(note_id) == Some(&expected_amount)) + { + return Ok(()); + } + } + + tokio::time::sleep(Duration::from_millis(500)).await; + } + }) + .await + .with_context(|| { + format!("Timed out waiting for finalized withdraw message with amount {expected_amount}") + })? +} diff --git a/integration_tests/tests/wallet_ffi.rs b/integration_tests/tests/wallet_ffi.rs index f2bb19f47..97035328d 100644 --- a/integration_tests/tests/wallet_ffi.rs +++ b/integration_tests/tests/wallet_ffi.rs @@ -169,13 +169,13 @@ unsafe extern "C" { fn wallet_ffi_free_transfer_result(result: *mut FfiTransferResult); - // fn wallet_ffi_bridge_withdraw( - // handle: *mut WalletHandle, - // from: *const FfiBytes32, - // amount: u64, - // bedrock_account_pk: *const FfiBytes32, - // out_result: *mut FfiTransferResult, - // ) -> error::WalletFfiError; + fn wallet_ffi_bridge_withdraw( + handle: *mut WalletHandle, + from: *const FfiBytes32, + amount: u64, + bedrock_account_pk: *const FfiBytes32, + out_result: *mut FfiTransferResult, + ) -> error::WalletFfiError; fn wallet_ffi_get_vault_balance( handle: *mut WalletHandle, @@ -1536,68 +1536,68 @@ fn restore_keys_from_seed_ffi() -> Result<()> { Ok(()) } -// #[test] -// fn test_wallet_ffi_bridge_withdraw() -> Result<()> { -// let ctx = BlockingTestContext::new()?; -// let home = tempfile::tempdir()?; -// let FfiCreateWalletOutput { -// wallet: wallet_ffi_handle, -// mnemonic: _, -// } = new_wallet_ffi_with_test_context_config(&ctx, home.path())?; -// let from: FfiBytes32 = ctx.ctx().existing_public_accounts()[0].into(); -// let bridge_account: FfiBytes32 = system_accounts::bridge_account_id().into(); -// let bedrock_account_pk = FfiBytes32::from_bytes([0x42; 32]); -// let amount = 100_u64; - -// let mut transfer_result = FfiTransferResult::default(); -// unsafe { -// wallet_ffi_bridge_withdraw( -// wallet_ffi_handle, -// &raw const from, -// amount, -// &raw const bedrock_account_pk, -// &raw mut transfer_result, -// ) -// .unwrap(); -// } - -// log::info!("Waiting for next block creation"); -// std::thread::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)); - -// let from_balance = unsafe { -// let mut out_balance: [u8; 16] = [0; 16]; -// wallet_ffi_get_balance( -// wallet_ffi_handle, -// &raw const from, -// true, -// &raw mut out_balance, -// ) -// .unwrap(); -// u128::from_le_bytes(out_balance) -// }; - -// let bridge_balance = unsafe { -// let mut out_balance: [u8; 16] = [0; 16]; -// wallet_ffi_get_balance( -// wallet_ffi_handle, -// &raw const bridge_account, -// true, -// &raw mut out_balance, -// ) -// .unwrap(); -// u128::from_le_bytes(out_balance) -// }; - -// assert_eq!(from_balance, 9900); -// assert_eq!(bridge_balance, 1_000_100); - -// unsafe { -// wallet_ffi_free_transfer_result(&raw mut transfer_result); -// wallet_ffi_destroy(wallet_ffi_handle); -// } - -// Ok(()) -// } +#[test] +fn test_wallet_ffi_bridge_withdraw() -> Result<()> { + let ctx = BlockingTestContext::new_default()?; + let home = tempfile::tempdir()?; + let FfiCreateWalletOutput { + wallet: wallet_ffi_handle, + mnemonic: _, + } = new_wallet_ffi_with_test_context_config(&ctx, home.path())?; + let from: FfiBytes32 = ctx.ctx().existing_public_accounts()[0].into(); + let bridge_account: FfiBytes32 = system_accounts::bridge_account_id().into(); + let bedrock_account_pk = FfiBytes32::from_bytes([0x42; 32]); + let amount = 100_u64; + + let mut transfer_result = FfiTransferResult::default(); + unsafe { + wallet_ffi_bridge_withdraw( + wallet_ffi_handle, + &raw const from, + amount, + &raw const bedrock_account_pk, + &raw mut transfer_result, + ) + .unwrap(); + } + + log::info!("Waiting for next block creation"); + std::thread::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)); + + let from_balance = unsafe { + let mut out_balance: [u8; 16] = [0; 16]; + wallet_ffi_get_balance( + wallet_ffi_handle, + &raw const from, + true, + &raw mut out_balance, + ) + .unwrap(); + u128::from_le_bytes(out_balance) + }; + + let bridge_balance = unsafe { + let mut out_balance: [u8; 16] = [0; 16]; + wallet_ffi_get_balance( + wallet_ffi_handle, + &raw const bridge_account, + true, + &raw mut out_balance, + ) + .unwrap(); + u128::from_le_bytes(out_balance) + }; + + assert_eq!(from_balance, 9900); + assert_eq!(bridge_balance, 1_000_100); + + unsafe { + wallet_ffi_free_transfer_result(&raw mut transfer_result); + wallet_ffi_destroy(wallet_ffi_handle); + } + + Ok(()) +} #[test] fn test_wallet_ffi_transfer_generic_public() -> Result<()> { diff --git a/lez/chain_state/Cargo.toml b/lez/chain_state/Cargo.toml index 0a0610a51..443cb6c54 100644 --- a/lez/chain_state/Cargo.toml +++ b/lez/chain_state/Cargo.toml @@ -21,6 +21,9 @@ log.workspace = true serde.workspace = true thiserror.workspace = true tokio.workspace = true +num-bigint.workspace = true +ed25519-dalek.workspace = true +async-stream.workspace = true [dev-dependencies] testnet_initial_state.workspace = true diff --git a/lez/chain_state/src/chain.rs b/lez/chain_state/src/chain.rs index c96bacc26..f987ff0c3 100644 --- a/lez/chain_state/src/chain.rs +++ b/lez/chain_state/src/chain.rs @@ -7,7 +7,7 @@ use common::block::Block; use lee::V03State; use log::warn; use logos_blockchain_core::mantle::ops::channel::MsgId; -use logos_blockchain_zone_sdk::Slot; +use logos_blockchain_zone_sdk::sequencer::SequencerCheckpoint; use crate::{ AcceptOutcome, BlockIngestError, StallReason, @@ -247,7 +247,7 @@ impl ChainState { &mut self, this_msg: MsgId, block: &Block, - l1_slot: Slot, + checkpoint: SequencerCheckpoint, ) -> AcceptOutcome { // Match by `MsgId` or block hash (re-inscriptions, restored entries). if let Some(idx) = self.head_position_of(this_msg, block) { @@ -264,7 +264,7 @@ impl ChainState { { self.finalize_through(idx); } - self.apply_finalized_direct(block, l1_slot) + self.apply_finalized_direct(block, checkpoint) } /// Moves `head_blocks[0..=idx]` into the final tier (already validated in head). @@ -284,7 +284,11 @@ impl ChainState { /// Applies a finalized block straight to the final tier. On success the /// finalized chain is authoritative, so head rebases onto it. - fn apply_finalized_direct(&mut self, block: &Block, l1_slot: Slot) -> AcceptOutcome { + fn apply_finalized_direct( + &mut self, + block: &Block, + checkpoint: SequencerCheckpoint, + ) -> AcceptOutcome { // A finalized block at or below the final tip is a re-delivery: // idempotent. A *different* block at the tip height falls through // to validation and parks. @@ -310,7 +314,7 @@ impl ChainState { AcceptOutcome::Applied } Err(err) => { - self.record_final_stall(block, l1_slot, err.clone()); + self.record_final_stall(block, checkpoint, err.clone()); AcceptOutcome::Parked(err) } } @@ -334,9 +338,14 @@ impl ChainState { } /// First stall is stored verbatim; later ones only bump `orphans_since`. - fn record_final_stall(&mut self, block: &Block, l1_slot: Slot, error: BlockIngestError) { + fn record_final_stall( + &mut self, + block: &Block, + checkpoint: SequencerCheckpoint, + error: BlockIngestError, + ) { self.final_stall = Some(self.final_stall.take().map_or_else( - || StallReason::new(Some(&block.header), l1_slot, error), + || StallReason::new(Some(&block.header), checkpoint, error), StallReason::escalate, )); } @@ -348,6 +357,7 @@ mod tests { HashType, test_utils::{create_transaction_native_token_transfer, produce_dummy_block}, }; + use logos_blockchain_zone_sdk::Slot; use testnet_initial_state::{initial_pub_accounts_private_keys, initial_state}; use super::*; @@ -356,8 +366,13 @@ mod tests { MsgId::from([n; 32]) } - fn slot(n: u64) -> Slot { - Slot::from(n) + fn checkpoint(msg: MsgId, n: u64) -> SequencerCheckpoint { + SequencerCheckpoint { + last_msg_id: msg, + pending_txs: vec![], + lib: [1_u8; 32].into(), + lib_slot: Slot::from(n), + } } /// `head_state` equals `final_state` replayed through `head_blocks`. @@ -481,7 +496,7 @@ mod tests { // Finalize through block 2. assert!(matches!( - chain.apply_finalized(msg(2), &block2, slot(100)), + chain.apply_finalized(msg(2), &block2, checkpoint(msg(2), 100)), AcceptOutcome::Applied )); assert_eq!(chain.final_tip().expect("final tip").block_id, 2); @@ -494,7 +509,7 @@ mod tests { let mut chain = ChainState::new(initial_state()); let genesis = produce_dummy_block(1, None, vec![]); assert!(matches!( - chain.apply_finalized(msg(1), &genesis, slot(10)), + chain.apply_finalized(msg(1), &genesis, checkpoint(msg(1), 10)), AcceptOutcome::Applied )); assert_eq!(chain.final_tip().expect("final tip").block_id, 1); @@ -506,12 +521,12 @@ mod tests { fn invalid_finalized_block_sets_final_stall() { let mut chain = ChainState::new(initial_state()); let genesis = produce_dummy_block(1, None, vec![]); - chain.apply_finalized(msg(1), &genesis, slot(10)); + chain.apply_finalized(msg(1), &genesis, checkpoint(msg(1), 10)); // Skip-ahead finalized block, not in head: parks the final tier. let bad = produce_dummy_block(3, Some(genesis.header.hash), vec![]); assert!(matches!( - chain.apply_finalized(msg(3), &bad, slot(20)), + chain.apply_finalized(msg(3), &bad, checkpoint(msg(3), 20)), AcceptOutcome::Parked(_) )); let stall = chain.final_stall().expect("final stall recorded"); @@ -743,8 +758,8 @@ mod tests { let mut chain = ChainState::new(initial_state()); let genesis = produce_dummy_block(1, None, vec![]); let block2 = produce_dummy_block(2, Some(genesis.header.hash), vec![]); - chain.apply_finalized(msg(1), &genesis, slot(10)); - chain.apply_finalized(msg(2), &block2, slot(20)); + chain.apply_finalized(msg(1), &genesis, checkpoint(msg(1), 10)); + chain.apply_finalized(msg(2), &block2, checkpoint(msg(2), 20)); // Finalized is irreversible: an adopted competitor at (or below) the // final tip is ignored, not reorged onto. @@ -820,7 +835,7 @@ mod tests { let mut alias = genesis.clone(); alias.header.block_id = 6; assert!(matches!( - chain.apply_finalized(msg(66), &alias, slot(10)), + chain.apply_finalized(msg(66), &alias, checkpoint(msg(66), 10)), AcceptOutcome::Parked(_) )); assert_eq!(chain.head_tip().expect("head tip").block_id, 1); @@ -841,7 +856,7 @@ mod tests { // Block 2 finalizes re-inscribed under a fresh MsgId: matched by hash, // finalized through, and the head above it survives. assert!(matches!( - chain.apply_finalized(msg(42), &block2, slot(5)), + chain.apply_finalized(msg(42), &block2, checkpoint(msg(42), 5)), AcceptOutcome::Applied )); assert_eq!(chain.final_tip().expect("final tip").block_id, 2); @@ -867,7 +882,7 @@ mod tests { let block3 = produce_dummy_block(3, Some(block2.header.hash), vec![tx3]); chain.apply_adopted(msg(3), &block3); - chain.apply_finalized(msg(2), &block2, slot(10)); + chain.apply_finalized(msg(2), &block2, checkpoint(msg(2), 10)); // Head still reflects both transfers assert_eq!(chain.head_state().get_account_by_id(to).balance, 20020); @@ -905,13 +920,13 @@ mod tests { fn repeated_invalid_finalized_bumps_orphans_since() { let mut chain = ChainState::new(initial_state()); let genesis = produce_dummy_block(1, None, vec![]); - chain.apply_finalized(msg(1), &genesis, slot(10)); + chain.apply_finalized(msg(1), &genesis, checkpoint(msg(1), 10)); let bad3 = produce_dummy_block(3, Some(genesis.header.hash), vec![]); - chain.apply_finalized(msg(3), &bad3, slot(20)); + chain.apply_finalized(msg(3), &bad3, checkpoint(msg(3), 20)); let bad5 = produce_dummy_block(5, Some(bad3.header.hash), vec![]); assert!(matches!( - chain.apply_finalized(msg(5), &bad5, slot(30)), + chain.apply_finalized(msg(5), &bad5, checkpoint(msg(5), 30)), AcceptOutcome::Parked(_) )); @@ -924,16 +939,16 @@ mod tests { fn valid_finalized_successor_clears_final_stall() { let mut chain = ChainState::new(initial_state()); let genesis = produce_dummy_block(1, None, vec![]); - chain.apply_finalized(msg(1), &genesis, slot(10)); + chain.apply_finalized(msg(1), &genesis, checkpoint(msg(1), 10)); let bad = produce_dummy_block(3, Some(genesis.header.hash), vec![]); - chain.apply_finalized(msg(3), &bad, slot(20)); + chain.apply_finalized(msg(3), &bad, checkpoint(msg(3), 20)); assert!(chain.final_stall().is_some()); // The valid successor of the frozen final tip finalizes: stall clears. let block2 = produce_dummy_block(2, Some(genesis.header.hash), vec![]); assert!(matches!( - chain.apply_finalized(msg(2), &block2, slot(30)), + chain.apply_finalized(msg(2), &block2, checkpoint(msg(2), 30)), AcceptOutcome::Applied )); assert!(chain.final_stall().is_none()); @@ -955,7 +970,7 @@ mod tests { let block3 = produce_dummy_block(3, Some(block2.header.hash), vec![]); assert!(matches!( - chain.apply_finalized(msg(3), &block3, slot(10)), + chain.apply_finalized(msg(3), &block3, checkpoint(msg(3), 10)), AcceptOutcome::Applied )); assert_eq!(chain.final_tip().expect("final tip").block_id, 3); @@ -972,16 +987,16 @@ mod tests { let mut chain = ChainState::new(initial_state()); let genesis = produce_dummy_block(1, None, vec![]); let block2 = produce_dummy_block(2, Some(genesis.header.hash), vec![]); - chain.apply_finalized(msg(1), &genesis, slot(10)); - chain.apply_finalized(msg(2), &block2, slot(20)); + chain.apply_finalized(msg(1), &genesis, checkpoint(msg(1), 10)); + chain.apply_finalized(msg(2), &block2, checkpoint(msg(2), 20)); // Below the tip, and at the tip with a matching hash: idempotent. assert!(matches!( - chain.apply_finalized(msg(41), &genesis, slot(30)), + chain.apply_finalized(msg(41), &genesis, checkpoint(msg(41), 30)), AcceptOutcome::AlreadyApplied )); assert!(matches!( - chain.apply_finalized(msg(42), &block2, slot(30)), + chain.apply_finalized(msg(42), &block2, checkpoint(msg(42), 30)), AcceptOutcome::AlreadyApplied )); assert!(chain.final_stall().is_none()); @@ -994,14 +1009,14 @@ mod tests { let mut chain = ChainState::new(initial_state()); let genesis = produce_dummy_block(1, None, vec![]); let block2 = produce_dummy_block(2, Some(genesis.header.hash), vec![]); - chain.apply_finalized(msg(1), &genesis, slot(10)); - chain.apply_finalized(msg(2), &block2, slot(20)); + chain.apply_finalized(msg(1), &genesis, checkpoint(msg(1), 10)); + chain.apply_finalized(msg(2), &block2, checkpoint(msg(2), 20)); // A different finalized block at the final height: finalized is // irreversible, so this is a genuine stall, not a re-delivery. let block2_prime = produce_dummy_block(2, Some(HashType([9; 32])), vec![]); assert!(matches!( - chain.apply_finalized(msg(22), &block2_prime, slot(30)), + chain.apply_finalized(msg(22), &block2_prime, checkpoint(msg(22), 30)), AcceptOutcome::Parked(_) )); assert!(chain.final_stall().is_some()); @@ -1018,7 +1033,7 @@ mod tests { let mut chain = ChainState::new(initial_state()); let genesis = produce_dummy_block(1, None, vec![]); chain.apply_adopted(msg(1), &genesis); - chain.apply_finalized(msg(1), &genesis, slot(10)); + chain.apply_finalized(msg(1), &genesis, checkpoint(msg(1), 10)); // Head advances on a competing branch… let block2a = produce_dummy_block(2, Some(genesis.header.hash), vec![]); @@ -1029,7 +1044,7 @@ mod tests { let tx = create_transaction_native_token_transfer(from, 0, to, 10, &sign_key); let block2b = produce_dummy_block(2, Some(genesis.header.hash), vec![tx]); assert!(matches!( - chain.apply_finalized(msg(22), &block2b, slot(20)), + chain.apply_finalized(msg(22), &block2b, checkpoint(msg(22), 20)), AcceptOutcome::Applied )); diff --git a/lez/chain_state/src/consistency.rs b/lez/chain_state/src/consistency.rs index 5c87fcadf..80841b286 100644 --- a/lez/chain_state/src/consistency.rs +++ b/lez/chain_state/src/consistency.rs @@ -3,16 +3,30 @@ use anyhow::Result; use common::{HashType, block::Block}; -use futures::StreamExt as _; +use futures::{Stream, StreamExt as _}; use lee_core::BlockId; use log::warn; -use logos_blockchain_core::mantle::ops::channel::ChannelId; -use logos_blockchain_zone_sdk::{Slot, ZoneMessage, adapter, indexer::ZoneIndexer}; +use logos_blockchain_core::mantle::{ + gas::GasCost, + ops::{OpId as _, channel::ChannelId}, +}; +use logos_blockchain_zone_sdk::{ + Deposit, Slot, Withdraw, ZoneBlock, ZoneMessage, + adapter::{self, NodeHttpClient}, + sequencer::{ + DepositInfo, Event, FinalizedOp, FundingConfig, InscriptionInfo, SequencerCheckpoint, + WithdrawInfo, ZoneSequencer, + }, +}; /// Upper bound on the channel reads of the startup consistency check. const CHANNEL_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(60); +/// Default signing key bytes, necessary after merging zone indexer and sequecner. +pub const DEFULT_SIGNING_KEY_BYTES: [u8; 32] = [13; 32]; + /// Result of comparing a caller's stored chain against the channel. +#[derive(Debug)] pub enum ChainConsistency { /// Channel still serves our anchor block (the stored tip position, or the /// parked block while stalled). @@ -33,6 +47,7 @@ pub enum ChainConsistency { } /// The evidence behind a [`ChainConsistency::Inconsistent`]. +#[derive(Debug)] pub enum ChainMismatch { /// The channel serves a different block at the anchor's id. Block { @@ -94,12 +109,12 @@ impl std::fmt::Display for ChainMismatch { } } -/// A block that must still be inscribed at `slot` if the channel is the chain +/// A block that must still be inscribed at `checkpoint` if the channel is the chain /// the store was built from: the tip at the read cursor, or the recorded /// parked block while stalled. -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone)] pub struct Anchor { - slot: Slot, + checkpoint: SequencerCheckpoint, /// The anchor block's `(id, hash)`. /// /// `None` when anchored on an undeserializable inscription (no header was recorded). @@ -107,27 +122,32 @@ pub struct Anchor { } impl Anchor { - /// Builds an anchor at `slot` on the block `(id, hash)`, or a headerless - /// anchor (`None`) when only the slot is known. + /// Builds an anchor at `checkpoint` on the block `(id, hash)`, or a headerless + /// anchor (`None`) when only the checkpoint is known. #[must_use] - pub const fn new(slot: Slot, block: Option<(BlockId, HashType)>) -> Self { - Self { slot, block } + pub const fn new(checkpoint: SequencerCheckpoint, block: Option<(BlockId, HashType)>) -> Self { + Self { checkpoint, block } + } + + #[must_use] + pub const fn slot(&self) -> Slot { + self.checkpoint.lib_slot } /// Probes a channel message read at/after the anchor slot. /// See [`verify_chain_consistency`]. fn probe_anchor_slot(&self, msg: &ZoneMessage, slot: Slot) -> AnchorProbe { - if slot < self.slot { + if slot < self.slot() { return AnchorProbe::KeepLooking; } let Some((anchor_id, anchor_hash)) = self.block else { // Anchored on an undeserializable inscription: any message still // present at that slot means the history is intact. - return if slot == self.slot { + return if slot == self.slot() { AnchorProbe::SameChain } else { AnchorProbe::Mismatch(ChainMismatch::AnchorSlotChanged { - anchor_slot: self.slot, + anchor_slot: self.slot(), }) }; }; @@ -151,7 +171,7 @@ impl Anchor { if id > anchor_id { return AnchorProbe::Bail; } - if slot == self.slot { + if slot == self.slot() { // Older ids can share the anchor's slot on the same chain. return AnchorProbe::KeepLooking; } @@ -160,7 +180,7 @@ impl Anchor { AnchorProbe::Mismatch(ChainMismatch::ReinscribedBlock { channel: (id, hash), slot, - anchor_slot: self.slot, + anchor_slot: self.slot(), }) } } @@ -173,6 +193,7 @@ impl Anchor { /// sequencer) feeds it the same messages it replays. Run [`Self::check_frontier`] /// once the channel tip is known, then feed messages in slot order via /// [`Self::observe`] until a verdict is reached. +#[derive(Debug)] pub struct AnchorConsistencyCheck { anchor: Anchor, verdict: Option, @@ -192,7 +213,7 @@ impl AnchorConsistencyCheck { /// tip could not be read, leaving the verdict to the message scan. pub fn check_frontier(&mut self, channel_tip_slot: Option) { if self.verdict.is_none() { - self.verdict = frontier_verdict(self.anchor.slot, channel_tip_slot) + self.verdict = frontier_verdict(self.anchor.slot(), channel_tip_slot) .map(ChainConsistency::Inconsistent); } } @@ -236,6 +257,221 @@ enum AnchorProbe { KeepLooking, } +/// An indexer context for spawning. +#[derive(Clone)] +pub struct IndexerContext { + pub channel_id: ChannelId, + pub node: NodeHttpClient, +} + +impl IndexerContext { + #[must_use] + pub const fn new(channel_id: ChannelId, node: NodeHttpClient) -> Self { + Self { channel_id, node } + } +} + +#[must_use] +pub fn checkpoint_eq( + checkpoint_a: &SequencerCheckpoint, + checkpoint_b: &SequencerCheckpoint, +) -> bool { + (checkpoint_a.last_msg_id == checkpoint_b.last_msg_id) + && (checkpoint_a.lib == checkpoint_b.lib) + && (checkpoint_a.lib_slot == checkpoint_b.lib_slot) + && (checkpoint_a.pending_txs == checkpoint_b.pending_txs) +} + +#[must_use] +pub fn checkpoint_eq_opt( + checkpoint_a: Option<&SequencerCheckpoint>, + checkpoint_b: Option<&SequencerCheckpoint>, +) -> bool { + match (checkpoint_a, checkpoint_b) { + (None, None) => true, + (Some(checkpoint_a), Some(checkpoint_b)) => checkpoint_eq(checkpoint_a, checkpoint_b), + _ => false, + } +} + +/// Migration of indexer-specific functionality after indexer removal. +/// +/// Reads all finalized blocks into a stream. +pub fn next_messages( + indexer: &mut ZoneSequencer, +) -> impl Stream +where + N: adapter::Node + Clone + Sync + Send + 'static, +{ + async_stream::stream! { + loop { + match indexer.next_event().await { + Event::BlocksProcessed { + checkpoint, finalized: batch, .. + } => { + for fin_tx in batch { + for op in fin_tx.ops { + let zone_msg = match op { + FinalizedOp::Deposit(DepositInfo { + tx_hash, + op_id, + channel_id: _, + inputs, + notes, + amount, + metadata, + }) => ZoneMessage::Deposit(Deposit { + tx_hash, + op_id, + inputs, + notes, + amount, + metadata, + }), + FinalizedOp::Withdraw(WithdrawInfo { tx_hash, op }) => { + ZoneMessage::Withdraw(Withdraw { + tx_hash, + op_id: op.op_id(), + inputs: op.inputs, + }) + } + FinalizedOp::Inscription(InscriptionInfo { + tx_hash: _, + parent_msg: _, + this_msg, + payload, + }) => ZoneMessage::Block(ZoneBlock { + id: this_msg, + data: payload, + }), + }; + + // Clonuing checkpoint here can be a costly operation. + // ToDo: Consider refactoring, right now, we need checkpoint here to + // fully anchor an indexer, which in turn is needed for old interfaces. + yield (zone_msg, checkpoint.clone()); + } + } + }, + Event::Ready => break, + Event::MempoolPending(_) | Event::TurnNotification { .. } => {} + } + } + } +} + +/// Migration of indexer-specific functionality after indexer removal. +/// +/// Reads all finalized blocks into a stream. +/// +/// Owned variant for cases where it is easier to create indexer in stream. +pub fn next_messages_own( + node: N, + channel_id: ChannelId, + indexer_checkpoint: Option, +) -> impl Stream +where + N: adapter::Node + Clone + Sync + Send + 'static, +{ + let mut indexer = new_indexer(channel_id, node, indexer_checkpoint); + + async_stream::stream! { + loop { + match indexer.next_event().await { + Event::BlocksProcessed { + checkpoint, finalized: batch, .. + } => { + for fin_tx in batch { + for op in fin_tx.ops { + let zone_msg = match op { + FinalizedOp::Deposit(DepositInfo { + tx_hash, + op_id, + channel_id: _, + inputs, + notes, + amount, + metadata, + }) => ZoneMessage::Deposit(Deposit { + tx_hash, + op_id, + inputs, + notes, + amount, + metadata, + }), + FinalizedOp::Withdraw(WithdrawInfo { tx_hash, op }) => { + ZoneMessage::Withdraw(Withdraw { + tx_hash, + op_id: op.op_id(), + inputs: op.inputs, + }) + } + FinalizedOp::Inscription(InscriptionInfo { + tx_hash: _, + parent_msg: _, + this_msg, + payload, + }) => ZoneMessage::Block(ZoneBlock { + id: this_msg, + data: payload, + }), + }; + + // Clonuing checkpoint here can be a costly operation. + // ToDo: Consider refactoring, right now, we need checkpoint here to + // fully anchor an indexer, which in turn is needed for old interfaces. + yield (zone_msg, checkpoint.clone()); + } + } + }, + Event::Ready => break, + Event::MempoolPending(_) | Event::TurnNotification { .. } => {} + } + } + } +} + +/// Placeholder funding config for indexer, must be provided after merging zone indexer and +/// sequencer. +#[must_use] +pub fn funding_placeholder() -> FundingConfig { + FundingConfig { + funding_pk: num_bigint::BigUint::new_const(1).into(), + max_tx_fee: GasCost::new(u64::MAX), + priority_fee_percent: FundingConfig::DEFAULT_PRIORITY_FEE_PERCENT, + } +} + +/// Placeholder `signing_key` for indexer, must be provided after merging zone indexer and +/// sequencer. +/// +/// NOT AN EXACT STRUCT, have conversion into necessary key type. +/// +/// `ToDo`: Replace, when zone-sdk keys crate is accesable. +#[must_use] +pub fn signing_key_placeholder() -> ed25519_dalek::SigningKey { + ed25519_dalek::SigningKey::from_bytes(&DEFULT_SIGNING_KEY_BYTES) +} + +/// Initialize indexer from a checkpoint. +pub fn new_indexer( + channel_id: ChannelId, + node: N, + checkpoint: Option, +) -> ZoneSequencer +where + N: adapter::Node + Clone + Sync + Send + 'static, +{ + ZoneSequencer::init( + channel_id, + signing_key_placeholder().into(), + node, + funding_placeholder(), + checkpoint, + ) +} + /// Detects when a local store belongs to a different chain than the connected /// L1 (e.g. a wiped/restarted Bedrock) so startup can react instead of silently /// diverging. @@ -255,7 +491,7 @@ pub async fn verify_chain_consistency( anchor: &Anchor, ) -> Result where - N: adapter::Node + Clone + Sync, + N: adapter::Node + Clone + Sync + Send + 'static, { let mut check = AnchorConsistencyCheck::new(anchor.clone()); match node.channel_state(channel_id).await { @@ -266,19 +502,20 @@ where return Ok(check.finish()); } - // `next_messages` is exclusive, so `slot - 1` includes the anchor slot. - let Some(from_slot) = anchor.slot.into_inner().checked_sub(1) else { - return Ok(ChainConsistency::Inconclusive); - }; - - let zone_indexer = ZoneIndexer::new(channel_id, node.clone()); let scan = async { - let stream = zone_indexer - .next_messages(Some(Slot::from(from_slot))) - .await?; + let stream = next_messages_own(node.clone(), channel_id, Some(anchor.checkpoint.clone())); let mut stream = std::pin::pin!(stream); - while let Some((msg, slot)) = stream.next().await { + while let Some(( + msg, + SequencerCheckpoint { + last_msg_id: _, + pending_txs: _, + lib: _, + lib_slot: slot, + }, + )) = stream.next().await + { if check.observe(&msg, slot).is_some() { break; } @@ -341,7 +578,17 @@ mod tests { } fn anchor_for(block: &Block, slot: Slot) -> Anchor { - Anchor::new(slot, Some((block.header.block_id, block.header.hash))) + let test_checkpoint = SequencerCheckpoint { + last_msg_id: MsgId::from([0_u8; 32]), + pending_txs: vec![], + lib: [1_u8; 32].into(), + lib_slot: slot, + }; + + Anchor::new( + test_checkpoint, + Some((block.header.block_id, block.header.hash)), + ) } #[test] @@ -422,7 +669,14 @@ mod tests { fn probe_accepts_any_message_for_a_headerless_anchor() { // A deserialize park records no header: any message still present at // the anchor slot means the history is intact. - let anchor = Anchor::new(Slot::from(1_000), None); + let test_checkpoint = SequencerCheckpoint { + last_msg_id: MsgId::from([0_u8; 32]), + pending_txs: vec![], + lib: [1_u8; 32].into(), + lib_slot: Slot::from(1_000), + }; + + let anchor = Anchor::new(test_checkpoint, None); let garbage = ZoneMessage::Block(ZoneBlock { id: MsgId::from([0_u8; 32]), data: Inscription::try_from(&[1_u8, 2, 3][..]).expect("inscription"), diff --git a/lez/chain_state/src/stall_reason.rs b/lez/chain_state/src/stall_reason.rs index e1d9b3ace..2fd6a31ce 100644 --- a/lez/chain_state/src/stall_reason.rs +++ b/lez/chain_state/src/stall_reason.rs @@ -1,5 +1,5 @@ use common::{HashType, block::BlockHeader}; -use logos_blockchain_zone_sdk::Slot; +use logos_blockchain_zone_sdk::sequencer::SequencerCheckpoint; use serde::{Deserialize, Serialize}; use crate::ingest_error::BlockIngestError; @@ -14,7 +14,7 @@ pub struct StallReason { pub block_id: Option, pub block_hash: Option, pub prev_block_hash: Option, - pub l1_slot: Slot, + pub checkpoint: SequencerCheckpoint, pub error: BlockIngestError, pub first_seen: Option, /// Number of later non-chaining blocks (orphans, since the tip is frozen). @@ -28,13 +28,17 @@ impl StallReason { /// First stall for a break, built from the breaking block's header /// (`None` for a deserialize break). #[must_use] - pub fn new(header: Option<&BlockHeader>, l1_slot: Slot, error: BlockIngestError) -> Self { + pub fn new( + header: Option<&BlockHeader>, + checkpoint: SequencerCheckpoint, + error: BlockIngestError, + ) -> Self { Self { block_id: header.map(|header| header.block_id), block_hash: header.map(|header| header.hash), prev_block_hash: header.map(|header| header.prev_block_hash), first_seen: header.map(|header| header.timestamp), - l1_slot, + checkpoint, error, orphans_since: 0, } diff --git a/lez/indexer/core/src/block_store.rs b/lez/indexer/core/src/block_store.rs index 7e7798ca0..77e32783f 100644 --- a/lez/indexer/core/src/block_store.rs +++ b/lez/indexer/core/src/block_store.rs @@ -11,8 +11,7 @@ use common::{ use lee::{Account, AccountId, V03State}; use lee_core::BlockId; use log::warn; -use logos_blockchain_core::header::HeaderId; -use logos_blockchain_zone_sdk::Slot; +use logos_blockchain_zone_sdk::sequencer::SequencerCheckpoint; use storage::indexer::RocksDBIO; use tokio::sync::RwLock; @@ -49,13 +48,6 @@ impl IndexerStore { }) } - pub fn last_observed_l1_lib_header(&self) -> Result> { - Ok(self - .dbio - .get_meta_last_observed_l1_lib_header_in_db()? - .map(HeaderId::from)) - } - pub fn get_last_block_id(&self) -> Result> { self.dbio.get_meta_last_block_id_in_db().map_err(Into::into) } @@ -112,16 +104,16 @@ impl IndexerStore { Ok(self.dbio.calculate_state_for_id(block_id)?) } - pub fn get_zone_cursor(&self) -> Result> { + pub fn get_zone_cursor(&self) -> Result> { let Some(bytes) = self.dbio.get_zone_sdk_indexer_cursor_bytes()? else { return Ok(None); }; - let cursor: Slot = serde_json::from_slice(&bytes) + let cursor: SequencerCheckpoint = serde_json::from_slice(&bytes) .context("Failed to deserialize stored zone-sdk indexer cursor")?; Ok(Some(cursor)) } - pub fn set_zone_cursor(&self, cursor: &Slot) -> Result<()> { + pub fn set_zone_cursor(&self, cursor: &SequencerCheckpoint) -> Result<()> { let bytes = serde_json::to_vec(cursor).context("Failed to serialize zone-sdk indexer cursor")?; self.dbio.put_zone_sdk_indexer_cursor_bytes(&bytes)?; @@ -131,8 +123,13 @@ impl IndexerStore { /// The L1 inscription slot of the validated tip, written atomically with it /// by [`Self::accept_block`]. `None` on a cold store or one written before /// the slot was recorded. - pub fn get_tip_slot(&self) -> Result> { - Ok(self.dbio.get_meta_tip_slot_in_db()?.map(Slot::from)) + pub fn get_tip_checkpoint(&self) -> Result> { + let Some(bytes) = self.dbio.get_meta_tip_checkpoint_in_db()? else { + return Ok(None); + }; + let checkpoint: Option = serde_json::from_slice(&bytes) + .context("Failed to deserialize stored tip checkpoint")?; + Ok(checkpoint) } pub fn get_cross_zone_halt(&self) -> Result> { @@ -214,11 +211,11 @@ impl IndexerStore { pub fn record_stall( &self, header: Option<&BlockHeader>, - l1_slot: Slot, + checkpoint: SequencerCheckpoint, error: BlockIngestError, ) -> Result<()> { let stall = self.get_stall_reason()?.map_or_else( - || StallReason::new(header, l1_slot, error), + || StallReason::new(header, checkpoint, error), StallReason::escalate, ); self.set_stall_reason(&Some(stall)) @@ -228,7 +225,15 @@ impl IndexerStore { /// (scratch clone, commit only on full success) and advances the tip. /// Retryable apply failures return `RetryableFailure` without recording a stall /// or touching state; other failures record the stall and return `Parked`. - pub async fn accept_block(&self, block: &Block, l1_slot: Slot) -> Result { + pub async fn accept_block( + &self, + block: &Block, + checkpoint: SequencerCheckpoint, + ) -> Result { + // First of all, checkpoint must be serializable + let checkpoint_bytes = serde_json::to_vec(&checkpoint) + .context("Failed to serialize SequencerCheckpoint, check signature")?; + let tip = self.validated_tip()?; // Re-delivery of an already-applied block is idempotent, not a divergence @@ -243,7 +248,7 @@ impl IndexerStore { // Validate before paying for the scratch clone; validation failures // are never retryable, so parking immediately is exact. if let Err(err) = validate_against_tip(tip.as_ref(), block) { - self.record_stall(Some(&block.header), l1_slot, err.clone())?; + self.record_stall(Some(&block.header), checkpoint.clone(), err.clone())?; return Ok(AcceptOutcome::Parked(err)); } @@ -253,14 +258,14 @@ impl IndexerStore { if err.is_retryable() { return Ok(AcceptOutcome::RetryableFailure(err)); } - self.record_stall(Some(&block.header), l1_slot, err.clone())?; + self.record_stall(Some(&block.header), checkpoint.clone(), err.clone())?; return Ok(AcceptOutcome::Parked(err)); } let mut stored = block.clone(); stored.bedrock_status = BedrockStatus::Finalized; self.dbio - .put_block(&stored, [0_u8; 32], l1_slot.into_inner(), &scratch) + .put_block(&stored, &checkpoint_bytes, &scratch) .context("Failed to persist accepted block")?; // Commit in-memory state (infallible) only after the DB write succeeded. @@ -277,6 +282,7 @@ impl IndexerStore { #[cfg(test)] mod stall_reason_tests { use common::HashType; + use logos_blockchain_zone_sdk::{Slot, node_types::MsgId, sequencer::SequencerCheckpoint}; use super::*; @@ -291,7 +297,12 @@ mod stall_reason_tests { block_id: Some(7), block_hash: Some(HashType([1_u8; 32])), prev_block_hash: Some(HashType([2_u8; 32])), - l1_slot: Slot::from(42), + checkpoint: SequencerCheckpoint { + last_msg_id: MsgId::from([3_u8; 32]), + pending_txs: vec![], + lib: [4_u8; 32].into(), + lib_slot: Slot::from(42), + }, error: BlockIngestError::StateTransition { tx_index: 0, reason: "boom".to_owned(), @@ -310,7 +321,7 @@ mod stall_reason_tests { )); assert_eq!(got.block_hash, Some(HashType([1_u8; 32]))); assert_eq!(got.prev_block_hash, Some(HashType([2_u8; 32]))); - assert_eq!(got.l1_slot, Slot::from(42)); + assert_eq!(got.checkpoint.lib_slot, Slot::from(42)); assert_eq!(got.first_seen, Some(99)); store.set_stall_reason(&None).expect("clear"); @@ -345,11 +356,21 @@ mod stall_reason_tests { #[cfg(test)] mod tests { use common::test_utils::{create_transaction_native_token_transfer, produce_dummy_block}; + use logos_blockchain_zone_sdk::{Slot, node_types::MsgId}; use tempfile::tempdir; use testnet_initial_state::initial_pub_accounts_private_keys; use super::*; + fn checkpoint(slot: u64) -> SequencerCheckpoint { + SequencerCheckpoint { + last_msg_id: MsgId::from([0_u8; 32]), + pending_txs: vec![], + lib: [1_u8; 32].into(), + lib_slot: Slot::from(slot), + } + } + #[test] fn correct_startup() { let home = tempdir().unwrap(); @@ -375,7 +396,7 @@ mod tests { let genesis = produce_dummy_block(1, None, vec![]); let mut prev_hash = genesis.header.hash; assert!(matches!( - store.accept_block(&genesis, Slot::from(0)).await.unwrap(), + store.accept_block(&genesis, checkpoint(0)).await.unwrap(), AcceptOutcome::Applied )); @@ -385,7 +406,7 @@ mod tests { let block = produce_dummy_block(i + 2, Some(prev_hash), vec![tx]); prev_hash = block.header.hash; assert!(matches!( - store.accept_block(&block, Slot::from(0)).await.unwrap(), + store.accept_block(&block, checkpoint(0)).await.unwrap(), AcceptOutcome::Applied )); } @@ -415,13 +436,13 @@ mod tests { let genesis = produce_dummy_block(1, None, vec![]); let mut prev_hash = genesis.header.hash; - store.accept_block(&genesis, Slot::from(0)).await.unwrap(); + store.accept_block(&genesis, checkpoint(0)).await.unwrap(); for i in 0..10_u64 { let tx = create_transaction_native_token_transfer(from, i.into(), to, 10, &sign_key); let block = produce_dummy_block(i + 2, Some(prev_hash), vec![tx]); prev_hash = block.header.hash; - store.accept_block(&block, Slot::from(0)).await.unwrap(); + store.accept_block(&block, checkpoint(0)).await.unwrap(); } // State at block N is inclusive of block N. @@ -449,9 +470,19 @@ mod tests { #[cfg(test)] mod accept_tests { use common::{HashType, block::HashableBlockData, test_utils::produce_dummy_block}; + use logos_blockchain_zone_sdk::{Slot, node_types::MsgId}; use super::*; + fn checkpoint(slot: u64) -> SequencerCheckpoint { + SequencerCheckpoint { + last_msg_id: MsgId::from([0_u8; 32]), + pending_txs: vec![], + lib: [1_u8; 32].into(), + lib_slot: Slot::from(slot), + } + } + fn signing_key() -> lee::PrivateKey { lee::PrivateKey::try_new([7_u8; 32]).expect("valid key") } @@ -475,7 +506,7 @@ mod accept_tests { let block = valid_hash_block(2, HashType([0_u8; 32])); let outcome = store - .accept_block(&block, Slot::from(0)) + .accept_block(&block, checkpoint(0)) .await .expect("accept"); @@ -500,7 +531,7 @@ mod accept_tests { block.header.timestamp = 999; // invalidates the stored hash let outcome = store - .accept_block(&block, Slot::from(0)) + .accept_block(&block, checkpoint(0)) .await .expect("accept"); assert!(matches!( @@ -516,12 +547,12 @@ mod accept_tests { let first = valid_hash_block(2, HashType([0_u8; 32])); store - .accept_block(&first, Slot::from(0)) + .accept_block(&first, checkpoint(0)) .await .expect("accept"); let second = valid_hash_block(3, HashType([0_u8; 32])); store - .accept_block(&second, Slot::from(0)) + .accept_block(&second, checkpoint(0)) .await .expect("accept"); @@ -538,7 +569,7 @@ mod accept_tests { store .record_stall( None, - Slot::from(0), + checkpoint(0), BlockIngestError::Deserialize("bad bytes".to_owned()), ) .expect("record"); @@ -556,14 +587,14 @@ mod accept_tests { // Genesis (block 1, clock-only) applies and advances the tip. let genesis = produce_dummy_block(1, None, vec![]); assert!(matches!( - store.accept_block(&genesis, Slot::from(0)).await.unwrap(), + store.accept_block(&genesis, checkpoint(0)).await.unwrap(), AcceptOutcome::Applied )); // A block that skips ahead (id 3 while the tip is 1) parks the indexer. let bad = produce_dummy_block(3, Some(genesis.header.hash), vec![]); assert!(matches!( - store.accept_block(&bad, Slot::from(0)).await.unwrap(), + store.accept_block(&bad, checkpoint(0)).await.unwrap(), AcceptOutcome::Parked(BlockIngestError::UnexpectedBlockId { expected: 2, got: 3 @@ -582,7 +613,7 @@ mod accept_tests { // The valid continuation (block 2 chaining on genesis) recovers the chain. let next = produce_dummy_block(2, Some(genesis.header.hash), vec![]); assert!(matches!( - store.accept_block(&next, Slot::from(0)).await.unwrap(), + store.accept_block(&next, checkpoint(0)).await.unwrap(), AcceptOutcome::Applied )); assert!( @@ -597,43 +628,73 @@ mod accept_tests { } #[tokio::test] - async fn accept_block_records_tip_inscription_slot() { + async fn accept_block_records_tip_inscription_checkpoint() { let dir = tempfile::tempdir().expect("tempdir"); let store = IndexerStore::open_db(dir.path(), Vec::new()).expect("open store"); - assert_eq!(store.get_tip_slot().expect("get"), None); + assert_eq!( + store + .get_tip_checkpoint() + .expect("get") + .map(|ch| ch.lib_slot), + None + ); let genesis = produce_dummy_block(1, None, vec![]); store - .accept_block(&genesis, Slot::from(1_000)) + .accept_block(&genesis, checkpoint(1_000)) .await .expect("accept"); - assert_eq!(store.get_tip_slot().expect("get"), Some(Slot::from(1_000))); + assert_eq!( + store + .get_tip_checkpoint() + .expect("get") + .map(|ch| ch.lib_slot), + Some(Slot::from(1_000)) + ); let block2 = produce_dummy_block(2, Some(genesis.header.hash), vec![]); store - .accept_block(&block2, Slot::from(1_005)) + .accept_block(&block2, checkpoint(1_005)) .await .expect("accept"); - assert_eq!(store.get_tip_slot().expect("get"), Some(Slot::from(1_005))); + assert_eq!( + store + .get_tip_checkpoint() + .expect("get") + .map(|ch| ch.lib_slot), + Some(Slot::from(1_005)) + ); // A parked block freezes the tip, so its slot must not advance either. let bad = produce_dummy_block(4, Some(block2.header.hash), vec![]); assert!(matches!( - store.accept_block(&bad, Slot::from(1_010)).await.unwrap(), + store.accept_block(&bad, checkpoint(1_010)).await.unwrap(), AcceptOutcome::Parked(_) )); - assert_eq!(store.get_tip_slot().expect("get"), Some(Slot::from(1_005))); + assert_eq!( + store + .get_tip_checkpoint() + .expect("get") + .map(|ch| ch.lib_slot), + Some(Slot::from(1_005)) + ); // Neither must a re-delivered old block move it. assert!(matches!( store - .accept_block(&genesis, Slot::from(1_015)) + .accept_block(&genesis, checkpoint(1_015)) .await .unwrap(), AcceptOutcome::AlreadyApplied )); - assert_eq!(store.get_tip_slot().expect("get"), Some(Slot::from(1_005))); + assert_eq!( + store + .get_tip_checkpoint() + .expect("get") + .map(|ch| ch.lib_slot), + Some(Slot::from(1_005)) + ); } #[tokio::test] @@ -650,7 +711,7 @@ mod accept_tests { let genesis = produce_dummy_block(1, None, vec![]); store - .accept_block(&genesis, Slot::from(0)) + .accept_block(&genesis, checkpoint(0)) .await .expect("accept genesis"); @@ -660,14 +721,14 @@ mod accept_tests { ); let block = produce_dummy_block(2, Some(genesis.header.hash), vec![tx]); assert!(matches!( - store.accept_block(&block, Slot::from(0)).await.unwrap(), + store.accept_block(&block, checkpoint(0)).await.unwrap(), AcceptOutcome::Applied )); let balance_after = store.account_current_state(&from).await.unwrap().balance; // Re-deliver the exact same block: idempotent skip, no state change, no park. assert!(matches!( - store.accept_block(&block, Slot::from(0)).await.unwrap(), + store.accept_block(&block, checkpoint(0)).await.unwrap(), AcceptOutcome::AlreadyApplied )); assert_eq!( @@ -701,7 +762,7 @@ mod accept_tests { // Build a short chain: genesis (1) -> block 2 -> block 3, so the tip is 3. let genesis = produce_dummy_block(1, None, vec![]); store - .accept_block(&genesis, Slot::from(0)) + .accept_block(&genesis, checkpoint(0)) .await .expect("accept genesis"); @@ -710,7 +771,7 @@ mod accept_tests { ); let block2 = produce_dummy_block(2, Some(genesis.header.hash), vec![tx2]); assert!(matches!( - store.accept_block(&block2, Slot::from(0)).await.unwrap(), + store.accept_block(&block2, checkpoint(0)).await.unwrap(), AcceptOutcome::Applied )); @@ -719,7 +780,7 @@ mod accept_tests { ); let block3 = produce_dummy_block(3, Some(block2.header.hash), vec![tx3]); assert!(matches!( - store.accept_block(&block3, Slot::from(0)).await.unwrap(), + store.accept_block(&block3, checkpoint(0)).await.unwrap(), AcceptOutcome::Applied )); @@ -727,7 +788,7 @@ mod accept_tests { // Re-deliver block 2 (id below the tip): a re-delivery, not a divergence. assert!(matches!( - store.accept_block(&block2, Slot::from(0)).await.unwrap(), + store.accept_block(&block2, checkpoint(0)).await.unwrap(), AcceptOutcome::AlreadyApplied )); assert_eq!( @@ -760,7 +821,7 @@ mod accept_tests { let genesis = produce_dummy_block(1, None, vec![]); assert!(matches!( - store.accept_block(&genesis, Slot::from(0)).await.unwrap(), + store.accept_block(&genesis, checkpoint(0)).await.unwrap(), AcceptOutcome::Applied )); let mut prev_hash = genesis.header.hash; @@ -777,7 +838,7 @@ mod accept_tests { let block = produce_dummy_block(i + 2, Some(prev_hash), vec![tx]); prev_hash = block.header.hash; assert!(matches!( - store.accept_block(&block, Slot::from(0)).await.unwrap(), + store.accept_block(&block, checkpoint(0)).await.unwrap(), AcceptOutcome::Applied )); } @@ -806,7 +867,7 @@ mod accept_tests { let genesis = produce_dummy_block(1, None, vec![]); store - .accept_block(&genesis, Slot::from(0)) + .accept_block(&genesis, checkpoint(0)) .await .expect("accept genesis"); @@ -819,7 +880,7 @@ mod accept_tests { &sign_key, ); let block = produce_dummy_block(2, Some(genesis.header.hash), vec![tx]); - let outcome = store.accept_block(&block, Slot::from(0)).await.unwrap(); + let outcome = store.accept_block(&block, checkpoint(0)).await.unwrap(); assert!(matches!( outcome, diff --git a/lez/indexer/core/src/cross_zone_verifier.rs b/lez/indexer/core/src/cross_zone_verifier.rs index f22f45713..474140070 100644 --- a/lez/indexer/core/src/cross_zone_verifier.rs +++ b/lez/indexer/core/src/cross_zone_verifier.rs @@ -10,6 +10,7 @@ use std::{ }; use anyhow::anyhow; +use chain_state::consistency::IndexerContext; use common::{ HashType, block::{Block, PeerChainTip}, @@ -30,7 +31,7 @@ use logos_blockchain_core::mantle::ops::channel::ChannelId; use logos_blockchain_zone_sdk::{ CommonHttpClient, Slot, ZoneMessage, adapter::{Node as _, NodeHttpClient}, - indexer::ZoneIndexer, + sequencer::{SequencerCheckpoint, ZoneSequencer}, }; use tokio::{sync::RwLock, time::Instant}; @@ -120,17 +121,17 @@ pub type SeenKey = (MessageKey, [u8; 32]); /// One peer zone's cached blocks, plus how far this reader has read them as an /// unbroken hash-linked run from the peer's genesis. struct PeerChain { - /// Full bodies, each with the slot the reader took it from: every block + /// Full bodies, each with the checkpoint the reader took it from: every block /// ahead of the verified prefix (the displacement buffer), plus the /// `window` most recent ids behind its tip. - blocks: HashMap, + blocks: HashMap, /// Where each evicted body was read and what it hashed to. Append-only and /// itself never evicted: at 48 bytes per block plus map overhead it grows /// for the life of the process, deliberately, because an id inside the run /// that is in neither map is the forgery signal, and forgetting an entry /// would turn an evicted honest block into a forgery verdict. The bound /// this buys is on bodies, which is where the memory was. - evicted: HashMap, + evicted: HashMap, /// The id [`Self::evict_behind_window`] considers next. Ids below it are /// already evicted, so each id is visited exactly once. next_to_evict: u64, @@ -223,9 +224,12 @@ impl PeerChain { enum PeerLookup { /// Held, and inside the run verified from the peer's genesis. Cached(Box), - /// Inside the run, body evicted: the slot it was read at and the hash the + /// Inside the run, body evicted: the checkpoint it was read at and the hash the /// walk certified, which is everything a refetch needs. - Evicted { read_at: Slot, block_hash: HashType }, + Evicted { + read_at: SequencerCheckpoint, + block_hash: HashType, + }, /// Inside the verified run but in neither map, so it is not on the peer /// chain. InsideRun, @@ -286,7 +290,7 @@ impl PeerBlocks { /// /// `read_at` is the slot the reader took the block from, recorded so an /// evicted body can be refetched. - async fn insert(&self, zone: ZoneId, block: Block, read_at: Slot) -> bool { + async fn insert(&self, zone: ZoneId, block: Block, read_at: SequencerCheckpoint) -> bool { let mut chains = self.chains.write().await; let chain = chains .entry(zone) @@ -414,10 +418,10 @@ impl PeerBlocks { chain .evicted .get(&block_id) - .map_or(PeerLookup::InsideRun, |&(read_at, block_hash)| { + .map_or(PeerLookup::InsideRun, |(read_at, block_hash)| { PeerLookup::Evicted { - read_at, - block_hash, + read_at: read_at.clone(), + block_hash: *block_hash, } }) } @@ -553,6 +557,8 @@ impl PeerWatch { /// Folds in a pass that never produced a stream. It read nothing, so it /// says nothing about the channel tip and breaks the evidence run. + // ToDo: Fix this clippy insanity later + #[cfg(test)] fn report_failed_pass(&self, zone: ZoneId) { let mut peers = self.lock(); let entry = peers.entry(zone).or_default(); @@ -634,7 +640,7 @@ pub struct CrossZoneVerifier { peers: PeerBlocks, /// One channel client per peer, used only for the one-shot refetch of an /// evicted body. Built exactly like the reader's own client. - refetch_clients: HashMap>>, + refetch_clients: HashMap, /// One-shot refetches attempted, successful or not. The retry cadence /// line in [`Self::wait_for_peer_block`] reports the running total. refetch_attempts: Arc, @@ -663,16 +669,13 @@ impl CrossZoneVerifier { let tip_node = node.clone(); refetch_clients.insert( peer.channel_id, - Arc::new(ZoneIndexer::new( - ChannelId::from(peer.channel_id), - node.clone(), - )), + IndexerContext::new(ChannelId::from(peer.channel_id), node.clone()), ); let expected_pubkeys = pinned_keys(peer); peer_pubkeys.insert(peer.channel_id, expected_pubkeys.clone()); watch.register(peer.channel_id); tokio::spawn(read_peer( - ZoneIndexer::new(ChannelId::from(peer.channel_id), node), + chain_state::consistency::new_indexer(ChannelId::from(peer.channel_id), node, None), tip_node, peer.channel_id, expected_pubkeys, @@ -995,7 +998,7 @@ impl CrossZoneVerifier { &self, zone: ZoneId, block_id: u64, - read_at: Slot, + read_at: SequencerCheckpoint, block_hash: HashType, ) -> anyhow::Result { self.refetch_attempts.fetch_add(1, Ordering::Relaxed); @@ -1003,13 +1006,11 @@ impl CrossZoneVerifier { .refetch_clients .get(&zone) .ok_or_else(|| anyhow!("no channel client for peer zone {}", hex::encode(zone)))?; - // `next_messages` resumes after its cursor, so the cursor one below - // `read_at` serves the recorded slot first. - let cursor = read_at.into_inner().checked_sub(1).map(Slot::from); - let stream = indexer - .next_messages(cursor) - .await - .map_err(|err| anyhow!("channel read failed: {err}"))?; + let stream = chain_state::consistency::next_messages_own( + indexer.node.clone(), + indexer.channel_id, + Some(read_at.clone()), + ); refetched_block(stream, read_at, block_id, block_hash, self.pinned_for(zone)).await } @@ -1110,7 +1111,7 @@ fn accept_peer_block(block: &Block, peer_zone: ZoneId, expected_pubkeys: &[Publi reason = "the peer reader runs for the lifetime of the indexer process" )] async fn read_peer( - zone_indexer: ZoneIndexer, + mut zone_indexer: ZoneSequencer, tip_node: NodeHttpClient, peer_zone: ZoneId, expected_pubkeys: Vec, @@ -1122,58 +1123,47 @@ async fn read_peer( "Cross-zone peer reader started for {}", hex::encode(peer_zone) ); - let mut cursor = None; // In memory only: it says how loud to be about a slot this reader is stuck // on. let mut stall = StallState::default(); loop { - match zone_indexer.next_messages(cursor).await { - Ok(stream) => { - let pass = - consume_peer_stream(stream, peer_zone, &expected_pubkeys, &peers, cursor).await; - cursor = pass.cursor; - if let Some((slot, attempts)) = stall.after_pass(pass.stalled_at, pass.cursor) - && alerts_at(attempts) - { - error!( - "Peer reader for {} has been stuck at slot {slot:?} for {attempts} passes. The run verified from that peer's genesis stops below it, so every dispatch naming a later block stalls until this slot can be read.", - hex::encode(peer_zone) - ); - } - let drained = pass.stalled_at.is_none(); - let drained_at_tip = if drained { - channel_tip_reached(&tip_node, peer_zone, pass.cursor).await - } else { - None - }; - let lib_slot = if drained_at_tip.is_some() { - observed_lib_slot(&tip_node).await - } else { - None - }; - watch.report_pass( - peer_zone, - &PassReport { - cursor_slot: pass.cursor.map(Slot::into_inner), - verified_tip: peers.verified_prefix(peer_zone).await, - stuck: stall - .current() - .map(|(slot, attempts)| (slot.into_inner(), attempts)), - drained, - drained_at_tip, - lib_slot, - }, - ); - } - Err(err) => { - error!( - "Peer reader next_messages failed for {}: {err}", - hex::encode(peer_zone) - ); - watch.report_failed_pass(peer_zone); - } + let stream = chain_state::consistency::next_messages(&mut zone_indexer); + + let pass = consume_peer_stream(stream, peer_zone, &expected_pubkeys, &peers, cursor).await; + cursor = pass.cursor; + if let Some((slot, attempts)) = stall.after_pass(pass.stalled_at, pass.cursor) + && alerts_at(attempts) + { + error!( + "Peer reader for {} has been stuck at slot {slot:?} for {attempts} passes. The run verified from that peer's genesis stops below it, so every dispatch naming a later block stalls until this slot can be read.", + hex::encode(peer_zone) + ); } + let drained = pass.stalled_at.is_none(); + let drained_at_tip = if drained { + channel_tip_reached(&tip_node, peer_zone, pass.cursor).await + } else { + None + }; + let lib_slot = if drained_at_tip.is_some() { + observed_lib_slot(&tip_node).await + } else { + None + }; + watch.report_pass( + peer_zone, + &PassReport { + cursor_slot: pass.cursor.map(Slot::into_inner), + verified_tip: peers.verified_prefix(peer_zone).await, + stuck: stall + .current() + .map(|(slot, attempts)| (slot.into_inner(), attempts)), + drained, + drained_at_tip, + lib_slot, + }, + ); tokio::time::sleep(poll_interval).await; } @@ -1202,14 +1192,15 @@ async fn consume_peer_stream( resume_from: Option, ) -> PeerPass where - S: Stream, + S: Stream, { let mut stream = std::pin::pin!(stream); let mut cursor = resume_from; // The slot being consumed: cached so far, but there may be more to come. let mut in_progress: Option = None; - while let Some((msg, slot)) = stream.next().await { + while let Some((msg, checkpoint)) = stream.next().await { + let slot = checkpoint.lib_slot; if in_progress != Some(slot) { cursor = in_progress.or(cursor); in_progress = Some(slot); @@ -1223,7 +1214,7 @@ where // Before caching, not when a dispatch names it: an unchecked // block steers the prefix, and by then the damage is a halt. if accept_peer_block(&block, peer_zone, expected_pubkeys) { - peers.insert(peer_zone, block, slot).await; + peers.insert(peer_zone, block, checkpoint.clone()).await; } } Err(err) => { @@ -1265,21 +1256,23 @@ where /// [`rederive`]: CrossZoneVerifier::rederive async fn refetched_block( stream: S, - read_at: Slot, + read_at: SequencerCheckpoint, block_id: u64, block_hash: HashType, pinned: &[PublicKey], ) -> anyhow::Result where - S: Stream, + S: Stream, { let mut stream = std::pin::pin!(stream); let mut mismatch = None; - while let Some((msg, slot)) = stream.next().await { - if slot > read_at { + while let Some((msg, checkpoint)) = stream.next().await { + let slot = checkpoint.lib_slot; + + if slot > read_at.lib_slot { break; } - if slot != read_at { + if slot != read_at.lib_slot { continue; } let ZoneMessage::Block(zone_block) = msg else { @@ -1315,6 +1308,7 @@ where #[cfg(test)] mod tests { + use chain_state::consistency::checkpoint_eq; use common::{HashType, test_utils::produce_dummy_block}; use cross_zone::test_utils::{linked_chain_to, ping_emission}; use futures::stream; @@ -1338,6 +1332,15 @@ mod tests { verifier_with_pinned_keys(HashMap::new()) } + fn checkpoint(slot: u64) -> SequencerCheckpoint { + SequencerCheckpoint { + last_msg_id: [0; 32].into(), + pending_txs: vec![], + lib: [1; 32].into(), + lib_slot: Slot::from(slot), + } + } + fn verifier_with_pinned_keys( peer_pubkeys: HashMap>, ) -> CrossZoneVerifier { @@ -1369,7 +1372,7 @@ mod tests { /// shape a one-block-per-slot reader would produce. async fn cache_chain_with_slots(peers: &PeerBlocks, chain: Vec) { for block in chain { - let read_at = Slot::from(block.header.block_id); + let read_at = checkpoint(block.header.block_id); peers.insert(PEER_ZONE, block, read_at).await; } } @@ -1380,13 +1383,18 @@ mod tests { } /// A peer-stream item inscribing `data` at `slot`. - fn peer_msg(data: Vec, slot: u64) -> (ZoneMessage, Slot) { + fn peer_msg(data: Vec, slot: u64) -> (ZoneMessage, SequencerCheckpoint) { ( ZoneMessage::Block(ZoneBlock { id: MsgId::from([0; 32]), data: Inscription::try_from(data).expect("test inscription is within bounds"), }), - Slot::from(slot), + SequencerCheckpoint { + last_msg_id: MsgId::from([0_u8; 32]), + pending_txs: vec![], + lib: [1_u8; 32].into(), + lib_slot: Slot::new(slot), + }, ) } @@ -1400,7 +1408,7 @@ mod tests { } /// A peer-stream item carrying `block`. - fn peer_block_msg(block: &Block, slot: u64) -> (ZoneMessage, Slot) { + fn peer_block_msg(block: &Block, slot: u64) -> (ZoneMessage, SequencerCheckpoint) { peer_msg(borsh::to_vec(block).expect("block serializes"), slot) } @@ -1420,12 +1428,15 @@ mod tests { /// Caches a run so its last block sits inside the verified prefix. async fn cache_chain(verifier: &CrossZoneVerifier, chain: Vec) { for block in chain { - verifier.peers.insert(PEER_ZONE, block, READ_SLOT).await; + verifier + .peers + .insert(PEER_ZONE, block, checkpoint(READ_SLOT.into_inner())) + .await; } } /// A peer-stream item whose inscription is not a decodable block. - fn undecodable_msg(slot: u64) -> (ZoneMessage, Slot) { + fn undecodable_msg(slot: u64) -> (ZoneMessage, SequencerCheckpoint) { peer_msg(b"not a block".to_vec(), slot) } @@ -1704,13 +1715,19 @@ mod tests { async fn a_block_that_does_not_link_does_not_extend_the_verified_run() { let peers = PeerBlocks::default(); let genesis = linked_chain(1); - peers.insert(PEER_ZONE, genesis[0].clone(), READ_SLOT).await; + peers + .insert( + PEER_ZONE, + genesis[0].clone(), + checkpoint(READ_SLOT.into_inner()), + ) + .await; // Claims the next id, but not the predecessor it would have to follow. peers .insert( PEER_ZONE, produce_dummy_block(GENESIS_BLOCK_ID + 1, None, vec![emission(b"hi")]), - READ_SLOT, + checkpoint(READ_SLOT.into_inner()), ) .await; @@ -1727,7 +1744,9 @@ mod tests { // absent-and-inside-the-run, the forgery signal, for a cached block. let peers = PeerBlocks::default(); for block in linked_chain(2) { - peers.insert(PEER_ZONE, block, READ_SLOT).await; + peers + .insert(PEER_ZONE, block, checkpoint(READ_SLOT.into_inner())) + .await; } assert!(matches!( @@ -1749,7 +1768,9 @@ mod tests { let peers = PeerBlocks::default(); let chain = linked_chain(3); for block in chain.iter().take(2).cloned() { - peers.insert(PEER_ZONE, block, READ_SLOT).await; + peers + .insert(PEER_ZONE, block, checkpoint(READ_SLOT.into_inner())) + .await; } peers .chains @@ -1761,7 +1782,13 @@ mod tests { .remove(&2); assert!( - peers.insert(PEER_ZONE, chain[2].clone(), READ_SLOT).await, + peers + .insert( + PEER_ZONE, + chain[2].clone(), + checkpoint(READ_SLOT.into_inner()) + ) + .await, "the next block still extends the run off the pinned tip" ); assert_eq!(peers.verified_prefix(PEER_ZONE).await, Some(3)); @@ -1867,7 +1894,10 @@ mod tests { cache_chain(&verifier, linked_chain(2)).await; let claimed = produce_dummy_block(9, None, vec![emission(b"hi")]); assert!( - !verifier.peers.insert(PEER_ZONE, claimed, READ_SLOT).await, + !verifier + .peers + .insert(PEER_ZONE, claimed, checkpoint(READ_SLOT.into_inner())) + .await, "the reader takes the next block on the run, never one ahead of it" ); assert!(verifier.peers.get(PEER_ZONE, 9).await.is_none()); @@ -1892,18 +1922,26 @@ mod tests { let chain = linked_chain(2); verifier .peers - .insert(PEER_ZONE, chain[0].clone(), READ_SLOT) + .insert( + PEER_ZONE, + chain[0].clone(), + checkpoint(READ_SLOT.into_inner()), + ) .await; verifier .peers - .insert(PEER_ZONE, chain[1].clone(), READ_SLOT) + .insert( + PEER_ZONE, + chain[1].clone(), + checkpoint(READ_SLOT.into_inner()), + ) .await; verifier .peers .insert( PEER_ZONE, produce_dummy_block(u64::MAX, None, vec![emission(b"hi")]), - READ_SLOT, + checkpoint(READ_SLOT.into_inner()), ) .await; @@ -1976,11 +2014,14 @@ mod tests { assert!( verifier .peers - .insert(PEER_ZONE, real.clone(), READ_SLOT) + .insert(PEER_ZONE, real.clone(), checkpoint(READ_SLOT.into_inner())) .await ); assert!( - !verifier.peers.insert(PEER_ZONE, impostor, READ_SLOT).await, + !verifier + .peers + .insert(PEER_ZONE, impostor, checkpoint(READ_SLOT.into_inner())) + .await, "a differing block at a held id must be refused" ); assert_eq!( @@ -2011,10 +2052,16 @@ mod tests { let peers = PeerBlocks::default(); let chain = linked_chain(3); for block in chain.iter().take(2).cloned() { - peers.insert(PEER_ZONE, block, READ_SLOT).await; + peers + .insert(PEER_ZONE, block, checkpoint(READ_SLOT.into_inner())) + .await; } let claimed = produce_dummy_block(3, Some(HashType([9; 32])), vec![emission(b"claimed")]); - assert!(peers.insert(PEER_ZONE, claimed, READ_SLOT).await); + assert!( + peers + .insert(PEER_ZONE, claimed, checkpoint(READ_SLOT.into_inner())) + .await + ); assert_eq!( peers.verified_prefix(PEER_ZONE).await, Some(2), @@ -2023,7 +2070,13 @@ mod tests { let honest = chain[2].clone(); assert!( - peers.insert(PEER_ZONE, honest.clone(), READ_SLOT).await, + peers + .insert( + PEER_ZONE, + honest.clone(), + checkpoint(READ_SLOT.into_inner()) + ) + .await, "the block that continues the run displaces the one that never could" ); assert_eq!(peers.verified_prefix(PEER_ZONE).await, Some(3)); @@ -2049,13 +2102,31 @@ mod tests { let peers = PeerBlocks::default(); let chain = linked_chain(4); for block in chain.iter().take(2).cloned() { - peers.insert(PEER_ZONE, block, READ_SLOT).await; + peers + .insert(PEER_ZONE, block, checkpoint(READ_SLOT.into_inner())) + .await; } let ahead = produce_dummy_block(4, Some(chain[2].header.hash), vec![emission(b"ahead")]); - assert!(!peers.insert(PEER_ZONE, ahead, READ_SLOT).await); + assert!( + !peers + .insert(PEER_ZONE, ahead, checkpoint(READ_SLOT.into_inner())) + .await + ); - peers.insert(PEER_ZONE, chain[2].clone(), READ_SLOT).await; - peers.insert(PEER_ZONE, chain[3].clone(), READ_SLOT).await; + peers + .insert( + PEER_ZONE, + chain[2].clone(), + checkpoint(READ_SLOT.into_inner()), + ) + .await; + peers + .insert( + PEER_ZONE, + chain[3].clone(), + checkpoint(READ_SLOT.into_inner()), + ) + .await; assert_eq!(peers.verified_prefix(PEER_ZONE).await, Some(4)); assert_eq!( @@ -2072,10 +2143,16 @@ mod tests { // the peer had built it. let peers = PeerBlocks::default(); let below = produce_dummy_block(0, None, vec![emission(b"below")]); - assert!(!peers.insert(PEER_ZONE, below, READ_SLOT).await); + assert!( + !peers + .insert(PEER_ZONE, below, checkpoint(READ_SLOT.into_inner())) + .await + ); for block in linked_chain(3) { - peers.insert(PEER_ZONE, block, READ_SLOT).await; + peers + .insert(PEER_ZONE, block, checkpoint(READ_SLOT.into_inner())) + .await; } assert_eq!(peers.verified_prefix(PEER_ZONE).await, Some(3)); assert!(peers.get(PEER_ZONE, 0).await.is_none()); @@ -2114,14 +2191,18 @@ mod tests { let peers = PeerBlocks::default(); let chain = linked_chain(2); for block in chain.iter().cloned() { - peers.insert(PEER_ZONE, block, READ_SLOT).await; + peers + .insert(PEER_ZONE, block, checkpoint(READ_SLOT.into_inner())) + .await; } assert_eq!(peers.verified_prefix(PEER_ZONE).await, Some(2)); let impostor = produce_dummy_block(2, Some(chain[0].header.hash), vec![emission(b"forged")]); assert!( - !peers.insert(PEER_ZONE, impostor, READ_SLOT).await, + !peers + .insert(PEER_ZONE, impostor, checkpoint(READ_SLOT.into_inner())) + .await, "it links to block 1 just as the held block does, and the run has certified the held one" ); @@ -2131,7 +2212,9 @@ mod tests { let plausible = produce_dummy_block(2, Some(chain[1].header.hash), vec![emission(b"forged")]); assert!( - !peers.insert(PEER_ZONE, plausible, READ_SLOT).await, + !peers + .insert(PEER_ZONE, plausible, checkpoint(READ_SLOT.into_inner())) + .await, "displacement fires only at the id that would extend the run, never inside it" ); assert_eq!( @@ -2150,13 +2233,13 @@ mod tests { assert!( verifier .peers - .insert(PEER_ZONE, block.clone(), READ_SLOT) + .insert(PEER_ZONE, block.clone(), checkpoint(READ_SLOT.into_inner())) .await ); assert!( !verifier .peers - .insert(PEER_ZONE, block.clone(), READ_SLOT) + .insert(PEER_ZONE, block.clone(), checkpoint(READ_SLOT.into_inner())) .await, "an identical re-read is already held, not newly cached" ); @@ -2442,7 +2525,10 @@ mod tests { else { panic!("id 1 must resolve as evicted"); }; - assert_eq!(read_at, Slot::from(1), "the slot the reader recorded"); + assert!( + checkpoint_eq(&read_at, &checkpoint(1)), + "the slot the reader recorded" + ); assert_eq!(block_hash, chain[0].header.hash); assert!(matches!( peers.resolve(PEER_ZONE, 2).await, @@ -2531,12 +2617,24 @@ mod tests { )); // The run still extends past the eviction. - assert!(peers.insert(PEER_ZONE, chain[3].clone(), READ_SLOT).await); + assert!( + peers + .insert( + PEER_ZONE, + chain[3].clone(), + checkpoint(READ_SLOT.into_inner()) + ) + .await + ); assert_eq!(peers.verified_prefix(PEER_ZONE).await, Some(4)); // An equivocating block at an evicted id is refused off the index hash. let impostor = produce_dummy_block(1, None, vec![emission(b"forged")]); - assert!(!peers.insert(PEER_ZONE, impostor, READ_SLOT).await); + assert!( + !peers + .insert(PEER_ZONE, impostor, checkpoint(READ_SLOT.into_inner())) + .await + ); let PeerLookup::Evicted { block_hash, .. } = peers.resolve(PEER_ZONE, 1).await else { panic!("the evicted entry must survive the equivocation attempt"); }; @@ -2552,7 +2650,7 @@ mod tests { peer_block_msg(target, 4), ]); - let block = refetched_block(stream, Slot::from(4), 2, target.header.hash, &[]) + let block = refetched_block(stream, checkpoint(4), 2, target.header.hash, &[]) .await .expect("the recorded slot serves the block"); assert_eq!(block.header.hash, target.header.hash); @@ -2567,7 +2665,7 @@ mod tests { tampered.header.hash = HashType([0xAB; 32]); let stream = stream::iter(vec![peer_block_msg(&tampered, 4)]); - let block = refetched_block(stream, Slot::from(4), GENESIS_BLOCK_ID, certified, &[]) + let block = refetched_block(stream, checkpoint(4), GENESIS_BLOCK_ID, certified, &[]) .await .expect("the recomputed hash matches the index"); assert_eq!( @@ -2634,7 +2732,7 @@ mod tests { let served = produce_dummy_block(2, Some(chain[0].header.hash), vec![emission(b"other")]); let stream = stream::iter(vec![peer_block_msg(&served, 4)]); - let err = refetched_block(stream, Slot::from(4), 2, chain[1].header.hash, &[]) + let err = refetched_block(stream, checkpoint(4), 2, chain[1].header.hash, &[]) .await .expect_err("different bytes than the walk saw must be refused"); assert!( @@ -2655,7 +2753,7 @@ mod tests { let block = refetched_block( stream, - Slot::from(4), + checkpoint(4), GENESIS_BLOCK_ID, honest.header.hash, std::slice::from_ref(&signer), @@ -2679,7 +2777,7 @@ mod tests { let err = refetched_block( stream, - Slot::from(4), + checkpoint(4), GENESIS_BLOCK_ID, honest.header.hash, std::slice::from_ref(&signer), @@ -2696,7 +2794,7 @@ mod tests { async fn refetch_reports_a_missing_or_undecodable_block_as_retriable() { let err = refetched_block( stream::iter(vec![undecodable_msg(4)]), - Slot::from(4), + checkpoint(4), 2, HashType([1; 32]), &[], diff --git a/lez/indexer/core/src/lib.rs b/lez/indexer/core/src/lib.rs index c282159dd..f696fa87d 100644 --- a/lez/indexer/core/src/lib.rs +++ b/lez/indexer/core/src/lib.rs @@ -3,15 +3,18 @@ use std::{path::Path, sync::Arc}; use anyhow::Result; use arc_swap::ArcSwap; pub use chain_state::{AcceptOutcome, BlockIngestError, StallReason}; -use chain_state::{Anchor, ChainConsistency}; +use chain_state::{Anchor, ChainConsistency, consistency::checkpoint_eq_opt}; use common::block::Block; // TODO: Remove after testnet use futures::StreamExt as _; use log::{error, warn}; use logos_blockchain_zone_sdk::{ - CommonHttpClient, Slot, ZoneMessage, adapter::NodeHttpClient, indexer::ZoneIndexer, + CommonHttpClient, Slot, ZoneMessage, + adapter::NodeHttpClient, + sequencer::{SequencerCheckpoint, ZoneSequencer}, }; use retry::ApplyRetryGate; +use tokio::sync::Mutex; use crate::{ block_store::IndexerStore, @@ -37,12 +40,12 @@ const APPLY_RETRY_LIMIT: u32 = 3; /// therefore put a later block in the same slot beyond the cursor whenever a /// pass ends early, and nothing would ever read it again. #[derive(Default)] -struct SlotProgress(Option); +struct CheckpointProgress(Option); #[derive(Clone)] pub struct IndexerCore { - pub zone_indexer: Arc>, - /// Direct node handle for queries outside `ZoneIndexer`'s streaming API. + pub zone_indexer: Arc>>, + /// Direct node handle for queries outside `ZoneSequencer`'s streaming API. pub node: NodeHttpClient, pub config: IndexerConfig, pub store: IndexerStore, @@ -52,19 +55,20 @@ pub struct IndexerCore { pub verifier: Option, } -impl SlotProgress { - /// Records that a message from `slot` is being handled, returning the slot +impl CheckpointProgress { + /// Records that a message from `checkpoint` is being handled, returning the checkpoint /// that just completed, if this message begins a new one. - fn enter(&mut self, slot: Slot) -> Option { - if self.0 == Some(slot) { + fn enter(&mut self, checkpoint: SequencerCheckpoint) -> Option { + // Equality is not implemented for `SequencerCheckpoint` + if checkpoint_eq_opt(self.0.as_ref(), Some(&checkpoint)) { return None; } - self.0.replace(slot) + self.0.replace(checkpoint) } - /// The slot in progress when the stream drained cleanly, which is therefore - /// complete. Not called when a pass ends early: that slot must be re-read. - const fn drained(self) -> Option { + /// The checkpoint in progress when the stream drained cleanly, which is therefore + /// complete. Not called when a pass ends early: that checkpoint must be re-read. + fn drained(self) -> Option { self.0 } } @@ -115,7 +119,8 @@ impl IndexerCore { CommonHttpClient::new(basic_auth), config.bedrock_config.addr.clone(), ); - let zone_indexer = ZoneIndexer::new(config.channel_id, node.clone()); + let zone_indexer = + chain_state::consistency::new_indexer(config.channel_id, node.clone(), None); // Cross-zone programs are base builtins, and their config accounts are // reconstructed by replaying the genesis block's InitConfig transactions; @@ -145,7 +150,7 @@ impl IndexerCore { }; Ok(Self { - zone_indexer: Arc::new(zone_indexer), + zone_indexer: Arc::new(Mutex::new(zone_indexer)), store, node, config, @@ -178,16 +183,16 @@ impl IndexerCore { fn get_startup_anchor(&self) -> Result> { if let Some(stall) = self.store.get_stall_reason()? { return Ok(Some(Anchor::new( - stall.l1_slot, + stall.checkpoint, stall.block_id.zip(stall.block_hash), ))); } // not stalled, so anchor on the tip at its own inscription slot - let Some(slot) = self - .store - .get_tip_slot()? - .map_or_else(|| self.store.get_zone_cursor(), |slot| Ok(Some(slot)))? + let Some(checkpoint) = self.store.get_tip_checkpoint()?.map_or_else( + || self.store.get_zone_cursor(), + |checkpoint| Ok(Some(checkpoint)), + )? else { return Ok(None); }; @@ -197,7 +202,10 @@ impl IndexerCore { let Some(tip) = self.store.get_block_at_id(tip_id)? else { return Ok(None); }; - Ok(Some(Anchor::new(slot, Some((tip_id, tip.header.hash))))) + Ok(Some(Anchor::new( + checkpoint, + Some((tip_id, tip.header.hash)), + ))) } /// Snapshot of the current ingestion status (sync state + indexed tip). @@ -252,9 +260,9 @@ impl IndexerCore { /// Advances the in-memory L1 read cursor past `slot` and persists it. /// A persist failure is only logged: the worst case is re-reading a batch /// after a restart, which ingestion handles idempotently. - fn advance_cursor(&self, cursor: &mut Option, slot: Slot) { - *cursor = Some(slot); - if let Err(err) = self.store.set_zone_cursor(&slot) { + fn advance_cursor(&self, cursor: &mut Option, checkpoint: &SequencerCheckpoint) { + *cursor = Some(checkpoint.lib_slot); + if let Err(err) = self.store.set_zone_cursor(checkpoint) { warn!("Failed to persist indexer cursor: {err:#}"); } } @@ -338,16 +346,21 @@ impl IndexerCore { /// /// Returns `false` if the stall could not be recorded durably; the caller /// must then hold the cursor and retry instead of advancing past the slot. - fn park_undeserializable(&self, slot: Slot, error: std::io::Error) -> bool { + fn park_undeserializable( + &self, + checkpoint: SequencerCheckpoint, + error: std::io::Error, + ) -> bool { let error = anyhow::Error::new(error); // use `:#` to get the entire error chain let reason = format!("{error:#}"); error!("Failed to deserialize L2 block from zone-sdk: {reason}"); - if let Err(err) = - self.store - .record_stall(None, slot, BlockIngestError::Deserialize(reason.clone())) - { + if let Err(err) = self.store.record_stall( + None, + checkpoint, + BlockIngestError::Deserialize(reason.clone()), + ) { error!("Failed to record stall reason: {err:#}"); self.set_status(IndexerSyncStatus::error(format!("store error: {err:#}"))); return false; @@ -358,7 +371,10 @@ impl IndexerCore { true } - pub fn subscribe_parse_block_stream(&self) -> impl futures::Stream> + '_ { + /// Warning: locks indexer during operation. + pub fn subscribe_parse_block_stream( + &mut self, + ) -> impl futures::Stream> + '_ { let poll_interval = self.config.consensus_info_polling_interval; let initial_cursor = self .store @@ -366,7 +382,7 @@ impl IndexerCore { .expect("Failed to load zone-sdk indexer cursor"); async_stream::stream! { - let mut cursor = initial_cursor; + let mut cursor = initial_cursor.map(|ch| ch.lib_slot); let mut retry_gate = ApplyRetryGate::new(); // In-memory mirror of the persisted halt record, so clearing it // when the recorded block later applies needs no per-block read. @@ -385,17 +401,11 @@ impl IndexerCore { } loop { - let stream = match self.zone_indexer.next_messages(cursor).await { - Ok(s) => s, - Err(err) => { - error!("Failed to start zone-sdk next_messages stream: {err}"); - self.set_status(IndexerSyncStatus::error(format!( - "cannot reach L1 / read channel: {err}" - ))); - tokio::time::sleep(poll_interval).await; - continue; - } - }; + let mut write_lock = self.zone_indexer.lock().await; + let stream = + chain_state::consistency::next_messages(&mut write_lock); + + //let stream = chain_state::consistency::next_messages(&mut self.zone_indexer).await; let mut stream = std::pin::pin!(stream); let mut announced_syncing = false; @@ -406,12 +416,17 @@ impl IndexerCore { // stream resumes *after* the stored slot, so advancing inside a // slot would put a later message in it beyond the cursor // for ever if this pass ends early. - let mut in_progress = SlotProgress::default(); - - while let Some((msg, slot)) = stream.next().await { - // A message from a later slot means the previous one is complete. - if let Some(done) = in_progress.enter(slot) { - self.advance_cursor(&mut cursor, done); + let mut in_progress = CheckpointProgress::default(); + + while let Some(( + msg, + checkpoint, + )) = stream.next().await + { + let slot = checkpoint.lib_slot; + // A message from a later checkpoint means the previous one is complete. + if let Some(done) = in_progress.enter(checkpoint.clone()) { + self.advance_cursor(&mut cursor, &done); } if !announced_syncing { @@ -429,7 +444,7 @@ impl IndexerCore { Ok(b) => b, Err(error) => { // The stall must be durable before the cursor moves. - if !self.park_undeserializable(slot, error) { + if !self.park_undeserializable(checkpoint.clone(), error) { had_cycle_error = true; break; } @@ -474,7 +489,7 @@ impl IndexerCore { }, }; - match self.store.accept_block(&block, slot).await { + match self.store.accept_block(&block, checkpoint.clone()).await { Ok(AcceptOutcome::Applied) => { if let Some(verifier) = &self.verifier { verifier.record_seen(verified_keys).await; @@ -512,7 +527,7 @@ impl IndexerCore { // The stall must be durable before the cursor moves. if let Err(err) = self.store.record_stall( Some(&block.header), - slot, + checkpoint.clone(), ingest_err.clone(), ) { error!( @@ -564,7 +579,7 @@ impl IndexerCore { // The stream drained cleanly, so the slot in progress completed too. if let Some(done) = in_progress.drained() { - self.advance_cursor(&mut cursor, done); + self.advance_cursor(&mut cursor, &done); } // Stream drained. Stay Stalled if parked; otherwise we are caught up. @@ -587,55 +602,62 @@ impl IndexerCore { mod tests { use std::{num::NonZeroU32, time::Duration}; + use chain_state::consistency::checkpoint_eq; use common::{HashType, block::HashableBlockData}; - use logos_blockchain_zone_sdk::Slot; + use logos_blockchain_zone_sdk::{Slot, node_types::MsgId}; use super::*; use crate::config::{ChannelId, ClientConfig, IndexerConfig}; - /// The cursor must not move while more of the same slot may still arrive. + fn checkpoint(slot: u64) -> SequencerCheckpoint { + SequencerCheckpoint { + last_msg_id: MsgId::from([0_u8; 32]), + pending_txs: vec![], + lib: [1_u8; 32].into(), + lib_slot: Slot::from(slot), + } + } + + /// The cursor must not move while more of the same checkpoint may still arrive. /// - /// Two L2 blocks in one L1 slot: the first applies, the second stalls on an + /// Two L2 blocks in one L1 checkpoint: the first applies, the second stalls on an /// unavailable peer and the pass retries. If handling the first had advanced - /// the cursor onto the slot, the retry would resume past it and the second + /// the cursor onto the checkpoint, the retry would resume past it and the second /// block would never be read again, silently losing whatever it carried. #[test] - fn a_slot_is_only_left_behind_once_it_is_finished() { - let mut progress = SlotProgress::default(); - let slot = Slot::from(7); + fn a_checkpoint_is_only_left_behind_once_it_is_finished() { + let mut progress = CheckpointProgress::default(); + let checkpoint = checkpoint(7); - assert_eq!( - progress.enter(slot), - None, - "nothing precedes the first slot" + assert!( + progress.enter(checkpoint.clone()).is_none(), + "nothing precedes the first checkpoint" ); - assert_eq!( - progress.enter(slot), - None, - "a second message in the same slot must not release it" + assert!( + progress.enter(checkpoint).is_none(), + "a second message in the same checkpoint must not release it" ); // The pass ends early here, so `drained` is never called and the cursor - // is still below slot 7: the next pass re-reads it whole. + // is still below checkpoint 7: the next pass re-reads it whole. } #[test] - fn a_completed_slot_is_released_when_the_next_one_starts() { - let mut progress = SlotProgress::default(); + fn a_completed_checkpoint_is_released_when_the_next_one_starts() { + let mut progress = CheckpointProgress::default(); - assert_eq!(progress.enter(Slot::from(3)), None); - assert_eq!(progress.enter(Slot::from(3)), None); - assert_eq!( - progress.enter(Slot::from(4)), - Some(Slot::from(3)), + assert!(progress.enter(checkpoint(3)).is_none()); + assert!(progress.enter(checkpoint(3)).is_none()); + assert!( + checkpoint_eq(&progress.enter(checkpoint(4)).unwrap(), &checkpoint(3)), "slot 3 is complete once a message from slot 4 arrives" ); - assert_eq!(progress.drained(), Some(Slot::from(4))); + assert!(checkpoint_eq(&progress.drained().unwrap(), &checkpoint(4))); } #[test] fn draining_an_untouched_stream_releases_nothing() { - assert_eq!(SlotProgress::default().drained(), None); + assert!(CheckpointProgress::default().drained().is_none()); } fn unreachable_core(dir: &std::path::Path) -> IndexerCore { @@ -694,7 +716,7 @@ mod tests { core.store .record_stall( Some(&parked.header), - Slot::from(1_000), + checkpoint(1_000), BlockIngestError::EmptyBlock, ) .expect("record stall"); @@ -711,13 +733,13 @@ mod tests { let genesis = common::test_utils::produce_dummy_block(1, None, vec![]); assert!(matches!( core.store - .accept_block(&genesis, Slot::from(1_000)) + .accept_block(&genesis, checkpoint(1_000)) .await .expect("accept"), AcceptOutcome::Applied )); core.store - .set_zone_cursor(&Slot::from(1_000)) + .set_zone_cursor(&checkpoint(1_000)) .expect("set cursor"); assert!(matches!( core.verify_chain_consistency().await.expect("verify"), @@ -736,28 +758,28 @@ mod tests { let genesis = common::test_utils::produce_dummy_block(1, None, vec![]); core.store - .accept_block(&genesis, Slot::from(1_000)) + .accept_block(&genesis, checkpoint(1_000)) .await .expect("accept"); let block2 = common::test_utils::produce_dummy_block(2, Some(genesis.header.hash), vec![]); core.store - .accept_block(&block2, Slot::from(1_005)) + .accept_block(&block2, checkpoint(1_005)) .await .expect("accept"); let block3 = common::test_utils::produce_dummy_block(3, Some(block2.header.hash), vec![]); core.store - .accept_block(&block3, Slot::from(1_010)) + .accept_block(&block3, checkpoint(1_010)) .await .expect("accept"); // Cursor last persisted at the genesis slot: two blocks behind the tip. core.store - .set_zone_cursor(&Slot::from(1_000)) + .set_zone_cursor(&checkpoint(1_000)) .expect("set cursor"); let anchor = core.get_startup_anchor().expect("anchor").expect("present"); - let expected = Anchor::new(Slot::from(1_010), Some((3, block3.header.hash))); - assert_eq!(anchor, expected); + let expected = Anchor::new(checkpoint(1_010), Some((3, block3.header.hash))); + assert_eq!(anchor.slot(), expected.slot()); } /// An inbox dispatch transaction with fixed source coordinates, so blocks diff --git a/lez/indexer/core/src/status.rs b/lez/indexer/core/src/status.rs index b5c6e6c38..9e0ffe47d 100644 --- a/lez/indexer/core/src/status.rs +++ b/lez/indexer/core/src/status.rs @@ -163,6 +163,8 @@ pub struct IndexerStatus { #[cfg(test)] mod tests { + use logos_blockchain_zone_sdk::{node_types::MsgId, sequencer::SequencerCheckpoint}; + use super::*; #[test] @@ -256,7 +258,12 @@ mod tests { block_id: Some(42), block_hash: None, prev_block_hash: None, - l1_slot: Slot::from(0), + checkpoint: SequencerCheckpoint { + last_msg_id: MsgId::from([0_u8; 32]), + pending_txs: vec![], + lib: [1_u8; 32].into(), + lib_slot: Slot::from(0), + }, error: BlockIngestError::StateTransition { tx_index: 0, reason: String::default(), diff --git a/lez/indexer/ffi/src/api/lifecycle.rs b/lez/indexer/ffi/src/api/lifecycle.rs index 8a1eafaf9..cc21f7084 100644 --- a/lez/indexer/ffi/src/api/lifecycle.rs +++ b/lez/indexer/ffi/src/api/lifecycle.rs @@ -122,7 +122,7 @@ unsafe fn setup_indexer( // The block stream writes each parsed block into the store as a side effect // of being polled, so we spawn a task that simply drains it. There are no // subscribers — queries read the store directly via `core()`. - let ingest_core = core.clone(); + let mut ingest_core = core.clone(); let ingest_handle = runtime.spawn(async move { let mut block_stream = std::pin::pin!(ingest_core.subscribe_parse_block_stream()); while let Some(result) = block_stream.next().await { diff --git a/lez/indexer/service/protocol/src/convert.rs b/lez/indexer/service/protocol/src/convert.rs index c77c93d52..3cea82c7b 100644 --- a/lez/indexer/service/protocol/src/convert.rs +++ b/lez/indexer/service/protocol/src/convert.rs @@ -8,8 +8,8 @@ use crate::{ HashType, IndexerStatus, IndexerSyncState, Nullifier, PeerHealth, PeerStatus, PrivacyPreservingMessage, PrivacyPreservingTransaction, PrivateAction, ProgramDeploymentMessage, ProgramDeploymentTransaction, ProgramId, Proof, PublicActionWithID, - PublicKey, PublicMessage, PublicTransaction, Signature, StallReason, Transaction, - ValidityWindow, WitnessSet, + PublicKey, PublicMessage, PublicTransaction, SequencerCheckpoint, Signature, StallReason, + Transaction, ValidityWindow, WitnessSet, }; // ============================================================================ @@ -848,17 +848,27 @@ impl From for StallReason { block_id, block_hash, prev_block_hash, - l1_slot, + checkpoint, error, first_seen, orphans_since, } = value; + let checkpoint = SequencerCheckpoint { + last_msg_id: *checkpoint.last_msg_id.as_ref(), + // There is no getter + lib: hex::decode(checkpoint.lib.to_string()) + .expect("Must be a valid hex") + .try_into() + .expect("Must fit 32 bytes"), + lib_slot: checkpoint.lib_slot.into_inner(), + }; + Self { block_id, block_hash: block_hash.map(Into::into), prev_block_hash: prev_block_hash.map(Into::into), - l1_slot: l1_slot.into_inner(), + checkpoint, error: error.into(), first_seen, orphans_since, diff --git a/lez/indexer/service/protocol/src/lib.rs b/lez/indexer/service/protocol/src/lib.rs index 6f5df0461..976dbe1e2 100644 --- a/lez/indexer/service/protocol/src/lib.rs +++ b/lez/indexer/service/protocol/src/lib.rs @@ -469,6 +469,15 @@ pub enum BlockIngestError { }, } +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)] +pub struct SequencerCheckpoint { + pub last_msg_id: [u8; 32], + pub lib: [u8; 32], + pub lib_slot: u64, + // We are dropping pending transactions here + // ineexer can not send transactions, therefore field should be empty +} + /// Diagnostic record of the first block that broke the L2 chain. /// /// The block-derived fields are `None` for a deserialize break (no header was @@ -478,7 +487,7 @@ pub struct StallReason { pub block_id: Option, pub block_hash: Option, pub prev_block_hash: Option, - pub l1_slot: u64, + pub checkpoint: SequencerCheckpoint, pub error: BlockIngestError, /// The breaking block's L2 timestamp (`None` for a deserialize break). pub first_seen: Option, diff --git a/lez/indexer/service/src/service.rs b/lez/indexer/service/src/service.rs index 2bafb6ee2..0465b4a0d 100644 --- a/lez/indexer/service/src/service.rs +++ b/lez/indexer/service/src/service.rs @@ -288,7 +288,7 @@ impl SubscriptionService { } fn spawn_respond_subscribers_loop( - indexer: IndexerCore, + mut indexer: IndexerCore, shutdown: CancellationToken, ) -> SubscriptionLoopParts { let (new_subscription_sender, mut sub_receiver) = @@ -338,6 +338,7 @@ impl SubscriptionService { } } }; + #[expect(clippy::large_futures, reason = "ToDo: Fix in future refactor")] let res: anyhow::Result<()> = run_loop.await; if let Err(err) = &res { error!("Subscription service loop has unexpectedly finished with error: {err:#?}"); diff --git a/lez/programs/bridge/Cargo.toml b/lez/programs/bridge/Cargo.toml index 1241adde6..c87be3e9c 100644 --- a/lez/programs/bridge/Cargo.toml +++ b/lez/programs/bridge/Cargo.toml @@ -5,6 +5,7 @@ edition = "2024" license = { workspace = true } [dependencies] +authenticated_transfer_core.workspace = true bridge_core.workspace = true vault_core.workspace = true lee_core.workspace = true diff --git a/lez/programs/bridge/src/main.rs b/lez/programs/bridge/src/main.rs index 1fd3333a0..8fdcd4ef3 100644 --- a/lez/programs/bridge/src/main.rs +++ b/lez/programs/bridge/src/main.rs @@ -104,35 +104,33 @@ fn main() { } } Instruction::Withdraw { - amount: _, + amount, bedrock_account_pk: _, } => { - panic!("Withdraws are disabled in the current version of LEZ"); - - // let [sender, bridge] = pre_states - // .try_into() - // .expect("Withdraw requires exactly 2 accounts"); + let [sender, bridge] = pre_states + .try_into() + .expect("Withdraw requires exactly 2 accounts"); - // assert_eq!( - // bridge.account_id, - // bridge_core::compute_bridge_account_id(self_program_id), - // "Second account must be bridge PDA" - // ); + assert_eq!( + bridge.account_id, + bridge_core::compute_bridge_account_id(self_program_id), + "Second account must be bridge PDA" + ); - // let auth_transfer_program_id = bridge.account.program_owner; - // assert_eq!( - // sender.account.program_owner, auth_transfer_program_id, - // "Sender account must be owned by the authenticated transfer program" - // ); + let auth_transfer_program_id = bridge.account.program_owner; + assert_eq!( + sender.account.program_owner, auth_transfer_program_id, + "Sender account must be owned by the authenticated transfer program" + ); - // let chained_calls = vec![ChainedCall::new( - // auth_transfer_program_id, - // vec![sender, bridge], - // &authenticated_transfer_core::Instruction::Transfer { - // amount: u128::from(amount), - // }, - // )]; - // (unchanged_post_states(&pre_states_clone), chained_calls) + let chained_calls = vec![ChainedCall::new( + auth_transfer_program_id.into(), + vec![sender, bridge], + &authenticated_transfer_core::Instruction::Transfer { + amount: u128::from(amount), + }, + )]; + (unchanged_post_states(&pre_states_clone), chained_calls) } }; diff --git a/lez/sequencer/actors/storage/Cargo.toml b/lez/sequencer/actors/storage/Cargo.toml index 4877a8e8e..be03f8be9 100644 --- a/lez/sequencer/actors/storage/Cargo.toml +++ b/lez/sequencer/actors/storage/Cargo.toml @@ -15,12 +15,16 @@ lee_core.workspace = true lee.workspace = true common.workspace = true storage.workspace = true +chain_state.workspace = true kameo.workspace = true thiserror.workspace = true log.workspace = true mockall = { workspace = true, optional = true } itertools.workspace = true +serde_json.workspace = true +serde.workspace = true +logos-blockchain-zone-sdk.workspace = true [dev-dependencies] tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } diff --git a/lez/sequencer/actors/storage/src/actor.rs b/lez/sequencer/actors/storage/src/actor.rs index 2edc7b917..09499a424 100644 --- a/lez/sequencer/actors/storage/src/actor.rs +++ b/lez/sequencer/actors/storage/src/actor.rs @@ -330,10 +330,12 @@ impl Message for StorageActor { GetZoneAnchor: GetZoneAnchor, _ctx: &mut Context, ) -> Self::Reply { - self.dbio() - .get_zone_anchor() - .map(|anchor| anchor.map(Into::into)) - .map_err(Into::into) + let anchor_bytes = self.dbio().get_zone_anchor_bytes()?; + if let Some(bytes) = anchor_bytes { + Ok(Some(serde_json::from_slice(&bytes)?)) + } else { + Ok(None) + } } } @@ -345,8 +347,10 @@ impl Message for StorageActor { SetZoneAnchor { anchor }: SetZoneAnchor, _ctx: &mut Context, ) -> Self::Reply { + let anchor_bytes = serde_json::to_vec(&anchor)?; + self.dbio() - .put_zone_anchor(&anchor.into()) + .put_zone_anchor_bytes(&anchor_bytes) .map_err(Into::into) } } @@ -431,7 +435,12 @@ impl Message for StorageActor { .iter() .map(|(block, finalized)| (block, *finalized)) .collect::>(); - let zone_anchor = zone_anchor.map(Into::into); + let zone_anchor_bytes = if let Some(zone_anchor) = zone_anchor { + let anchor_bytes = serde_json::to_vec(&zone_anchor)?; + Some(anchor_bytes) + } else { + None + }; let new_deposit_events = new_deposit_events .into_iter() .map(Into::into) @@ -459,7 +468,7 @@ impl Message for StorageActor { remove_dispatch_records: &remove_dispatch_records, consumed_withdrawals: &consumed_withdrawals, new_withdraw_intents: &new_withdraw_intents, - zone_anchor: zone_anchor.as_ref(), + zone_anchor: zone_anchor_bytes.as_deref(), }; let outcome = self.dbio().store_update(&update)?; diff --git a/lez/sequencer/actors/storage/src/error.rs b/lez/sequencer/actors/storage/src/error.rs index 904806ff0..5f287b41f 100644 --- a/lez/sequencer/actors/storage/src/error.rs +++ b/lez/sequencer/actors/storage/src/error.rs @@ -2,4 +2,6 @@ pub enum Error { #[error("Database error")] DatabaseError(#[from] storage::error::DbError), + #[error("Serializaton error")] + SerializationError(#[from] serde_json::Error), } diff --git a/lez/sequencer/actors/storage/src/protocol.rs b/lez/sequencer/actors/storage/src/protocol.rs index e74819de4..cb4a30921 100644 --- a/lez/sequencer/actors/storage/src/protocol.rs +++ b/lez/sequencer/actors/storage/src/protocol.rs @@ -10,6 +10,8 @@ use common::{ }; use lee::V03State; use lee_core::BlockId; +use logos_blockchain_zone_sdk::sequencer::SequencerCheckpoint; +use serde::{Deserialize, Serialize}; use storage::sequencer::{self as db, sequencer_cells as db_cells}; use crate::Result; @@ -203,44 +205,22 @@ impl From for WithdrawalReconciliationKey /// /// `slot` is the raw L1 inscription slot; the caller converts to and from the /// zone-sdk `Slot`, which does not derive borsh and so cannot be stored. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ZoneAnchorRecord { - pub slot: u64, + pub checkpoint: SequencerCheckpoint, pub block_id: u64, pub hash: HashType, } -impl From for db_cells::ZoneAnchorRecord { - fn from( - ZoneAnchorRecord { - slot, - block_id, - hash, - }: ZoneAnchorRecord, - ) -> Self { - Self { - slot, - block_id, - hash, - } +impl PartialEq for ZoneAnchorRecord { + fn eq(&self, other: &Self) -> bool { + chain_state::consistency::checkpoint_eq(&self.checkpoint, &other.checkpoint) + && self.block_id == other.block_id + && self.hash == other.hash } } -impl From for ZoneAnchorRecord { - fn from( - db_cells::ZoneAnchorRecord { - slot, - block_id, - hash, - }: db_cells::ZoneAnchorRecord, - ) -> Self { - Self { - slot, - block_id, - hash, - } - } -} +impl Eq for ZoneAnchorRecord {} /// An L1 deposit event observed but not yet seen finalized. /// diff --git a/lez/sequencer/core/src/block_publisher.rs b/lez/sequencer/core/src/block_publisher.rs index d2909e09f..905e9c278 100644 --- a/lez/sequencer/core/src/block_publisher.rs +++ b/lez/sequencer/core/src/block_publisher.rs @@ -34,7 +34,6 @@ pub use logos_blockchain_zone_sdk::sequencer::SequencerCheckpoint; use logos_blockchain_zone_sdk::{ CommonHttpClient, Slot, ZoneMessage, adapter::{Node as _, NodeHttpClient}, - indexer::ZoneIndexer, sequencer::{ ChannelUpdateTx, DepositInfo, Event, FinalizedOp, FundingConfig, InscriptionInfo, PendingTx, SequencerConfig as ZoneSdkSequencerConfig, TurnNotification, WithdrawArg, @@ -191,8 +190,8 @@ pub trait LocalBlockPublisherTrait: Sized + Sync { /// from the channel's genesis. async fn read_channel_after( &self, - after_slot: Option, - ) -> Result + Send + '_>; + checkpoint: Option, + ) -> impl Stream + Send + '_; } /// Real block publisher backed by zone-sdk's `ZoneSequencer`. @@ -208,7 +207,6 @@ pub struct ZoneSdkPublisher { // Stops the drive task when the last clone is dropped, and lets a shutdown // path wait until it has actually stopped. drive_task: TaskGroup, - indexer: ZoneIndexer, bedrock_signing_key: Ed25519Key, funding_key: ZkPublicKey, priority_fee: u64, @@ -251,7 +249,7 @@ impl BlockPublisherTrait for ZoneSdkPublisher { ..ZoneSdkSequencerConfig::new(FundingConfig { funding_pk: config.funding_key, max_tx_fee: GasCost::new(logos_blockchain_core::mantle::Value::MAX), - priority_fee: config.priority_fee, + priority_fee_percent: config.priority_fee, }) }; @@ -373,6 +371,8 @@ impl BlockPublisherTrait for ZoneSdkPublisher { } }, event = sequencer.next_event() => { + log::info!("========================== Received event {event:#?}"); + match event { Event::BlocksProcessed { checkpoint, @@ -445,7 +445,6 @@ impl BlockPublisherTrait for ZoneSdkPublisher { Ok(Self { channel_id: config.channel_id, - indexer: ZoneIndexer::new(config.channel_id, node.clone()), node, command_tx, turn_rx, @@ -598,16 +597,12 @@ impl BlockPublisherTrait for ZoneSdkPublisher { .map(|state| state.tip_slot)) } + /// Creates indexer in-place, then reads channel after checkpoint. async fn read_channel_after( &self, - after_slot: Option, - ) -> Result + Send + '_> { - let stream = self - .indexer - .next_messages(after_slot) - .await - .context("Failed to start channel read stream")?; - Ok(stream) + checkpoint: Option, + ) -> impl Stream + Send + '_ { + chain_state::consistency::next_messages_own(self.node.clone(), self.channel_id, checkpoint) } } @@ -661,7 +656,7 @@ async fn fund_ops( change_public_key: funding_key, funding_public_keys: vec![funding_key], max_tx_fee: GasCost::new(logos_blockchain_core::mantle::Value::MAX), - priority_fee, + priority_fee_percent: priority_fee, }) .await .context("Failed to fund channel transaction") diff --git a/lez/sequencer/core/src/cross_zone_watcher.rs b/lez/sequencer/core/src/cross_zone_watcher.rs index c03cbf789..c4878c2e2 100644 --- a/lez/sequencer/core/src/cross_zone_watcher.rs +++ b/lez/sequencer/core/src/cross_zone_watcher.rs @@ -1,13 +1,14 @@ use std::time::Duration; use anyhow::{Context as _, Result}; +use chain_state::consistency::{IndexerContext, checkpoint_eq_opt}; use common::{ HashType, block::{Block, PeerChainTip}, transaction::LeeTransaction, }; use cross_zone::{ - EmissionSource, Link, StallState, alerts_at, build_dispatch_from_emission, equivocation_report, + EmissionSource, Link, StallState, build_dispatch_from_emission, equivocation_report, extract_emission, is_sequencer_only_program, link_to_tip, pinned_keys, screen_peer_block, }; use cross_zone_inbox_core::message_key; @@ -17,7 +18,7 @@ use lee::PublicKey; use log::{debug, error, warn}; use logos_blockchain_core::mantle::ops::channel::ChannelId; use logos_blockchain_zone_sdk::{ - CommonHttpClient, Slot, ZoneMessage, adapter::NodeHttpClient, indexer::ZoneIndexer, + CommonHttpClient, Slot, ZoneMessage, adapter::NodeHttpClient, sequencer::SequencerCheckpoint, }; use sequencer_storage_actor::{ StorageActorTrait, @@ -33,6 +34,15 @@ use crate::{ task_group::TaskGroup, }; +/// Consecutive passes a watcher spends stuck on one slot before it says so as +/// something more than the per-pass failure. +/// +/// One pass per poll interval, which is the block time, so this is minutes of +/// retrying rather than seconds. A transient failure (a truncated read, a peer +/// mid-upgrade) heals well inside that; anything still stuck after it wants +/// someone to look. +const STUCK_SLOT_ALERT_PASSES: u32 = 20; + /// The per-peer settings one watcher pass needs. struct PeerContext { peer_zone: [u8; 32], @@ -95,14 +105,32 @@ impl WatcherState { } /// What a starting watcher does with its stored floor and chain tip. -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug)] struct Resume { /// Where to read from. `None` is the peer's genesis. - cursor: Option, + cursor: Option, /// Whether the stored floor has to be dropped before anything is read. clear_floor: bool, } +impl core::cmp::PartialEq for Resume { + fn eq(&self, other: &Self) -> bool { + (self.clear_floor == other.clear_floor) + && checkpoint_eq_opt(self.cursor.as_ref(), other.cursor.as_ref()) + } +} + +impl core::cmp::Eq for Resume {} + +/// Whether a watcher stuck for `attempts` passes should say so on this one. +/// +/// Every [`STUCK_SLOT_ALERT_PASSES`], not on the crossing alone: a stall that +/// never clears would otherwise be reported once and then look resolved for as +/// long as it lasts. Not every pass, since that is one line per block time. +const fn alerts_at(attempts: u32) -> bool { + attempts > 0 && attempts.is_multiple_of(STUCK_SLOT_ALERT_PASSES) +} + /// Where a starting watcher resumes reading a peer's channel. /// /// A store holding a floor but no tip predates chain pinning, and its next block @@ -113,7 +141,7 @@ struct Resume { /// /// The floor is dropped rather than ignored, or a crash partway through the /// rebuild resumes above the tip it had just started building. -const fn resume_from(tip: Option, floor: Option) -> Resume { +fn resume_from(tip: Option, floor: Option) -> Resume { match tip { Some(_) => Resume { cursor: floor, @@ -134,31 +162,27 @@ const fn resume_from(tip: Option, floor: Option) -> Resume { async fn get_cross_zone_peer_floor( storage_ref: &ActorRef, peer_zone: PeerZoneKey, -) -> Result> { +) -> Result> { let Some(bytes) = storage_ref .ask(GetCrossZonePeerFloorBytes { peer_zone }) .await? else { return Ok(None); }; - let bytes: [u8; 8] = bytes.as_slice().try_into().with_context(|| { - format!( - "Stored cross-zone peer floor is {} bytes, expected 8", - bytes.len() - ) - })?; - Ok(Some(Slot::new(u64::from_le_bytes(bytes)))) + Ok(Some( + serde_json::from_slice(&bytes).context("Checkpoint must deserialize")?, + )) } async fn set_cross_zone_peer_floor( storage_ref: &ActorRef, peer_zone: PeerZoneKey, - floor: Slot, + floor: SequencerCheckpoint, ) -> Result<()> { storage_ref .ask(SetCrossZonePeerFloorBytes { peer_zone, - bytes: floor.to_le_bytes().to_vec(), + bytes: serde_json::to_vec(&floor).context("Checkpoint must serialize")?, }) .await?; Ok(()) @@ -204,7 +228,7 @@ pub fn spawn_watchers( ); let expected_pubkeys = pinned_keys(&peer); tasks.push(tokio::spawn(watch_peer( - ZoneIndexer::new(ChannelId::from(peer.channel_id), node), + IndexerContext::new(ChannelId::from(peer.channel_id), node), PeerContext { peer_zone: peer.channel_id, self_zone, @@ -223,7 +247,7 @@ pub fn spawn_watchers( reason = "the peer watcher runs for the lifetime of the sequencer process" )] async fn watch_peer( - zone_indexer: ZoneIndexer, + zone_indexer_context: IndexerContext, peer: PeerContext, poll_interval: Duration, storage_ref: ActorRef, @@ -282,9 +306,9 @@ async fn watch_peer( } } let mut cursor = resume.cursor; - if let Some(slot) = cursor { + if let Some(checkpoint) = &cursor { log::info!( - "Resuming watcher for peer {} from slot {slot:?}", + "Resuming watcher for peer {} from checkpoint {checkpoint:?}", hex::encode(peer_zone) ); } @@ -293,20 +317,15 @@ async fn watch_peer( // loud to be about a slot this watcher is stuck on. let mut state = WatcherState::default(); loop { - let stream = match zone_indexer.next_messages(cursor).await { - Ok(stream) => stream, - Err(err) => { - error!( - "Watcher next_messages failed for peer {}: {err}", - hex::encode(peer_zone) - ); - tokio::time::sleep(poll_interval).await; - continue; - } - }; + let stream = chain_state::consistency::next_messages_own( + zone_indexer_context.node.clone(), + zone_indexer_context.channel_id, + cursor.clone(), + ); let outcome = consume_peer_stream(stream, &peer, &storage_ref, &mut cursor, &mut tip).await; - if let Some((slot, attempts)) = state.after_pass(outcome, cursor) + if let Some((slot, attempts)) = + state.after_pass(outcome, cursor.as_ref().map(|c| c.lib_slot)) && alerts_at(attempts) { error!( @@ -346,29 +365,31 @@ async fn consume_peer_stream( stream: Str, peer: &PeerContext, storage_ref: &ActorRef, - cursor: &mut Option, + cursor: &mut Option, tip: &mut Option, ) -> PassOutcome where - Str: Stream, + Str: Stream, { let mut stream = std::pin::pin!(stream); // The slot being consumed: every message of it seen so far is handled, but // there may be more to come, so the cursor may not advance onto it yet. - let mut in_progress: Option = None; + let mut in_progress: Option = None; // What the pass did with the blocks it read, so a peer going quiet behind a // tip that no longer tracks it is distinguishable from one with nothing to // say. let mut placed = 0_usize; let mut skipped = 0_usize; - while let Some((msg, slot)) = stream.next().await { - if in_progress != Some(slot) { + while let Some((msg, checkpoint)) = stream.next().await { + let slot = checkpoint.lib_slot; + + if !checkpoint_eq_opt(in_progress.as_ref(), Some(&checkpoint)) { // A message from a later slot means the previous one completed. if let Some(done) = in_progress { advance_cursor(storage_ref, peer.peer_zone, cursor, done).await; } - in_progress = Some(slot); + in_progress = Some(checkpoint); } let zone_block = match msg { @@ -498,11 +519,11 @@ where async fn advance_cursor( storage_ref: &ActorRef, peer_zone: [u8; 32], - cursor: &mut Option, - slot: Slot, + cursor: &mut Option, + checkpoint: SequencerCheckpoint, ) { - *cursor = Some(slot); - if let Err(err) = set_cross_zone_peer_floor(storage_ref, peer_zone, slot).await { + *cursor = Some(checkpoint.clone()); + if let Err(err) = set_cross_zone_peer_floor(storage_ref, peer_zone, checkpoint).await { warn!( "Failed to persist watcher delivery floor for peer {}: {err:#}", hex::encode(peer_zone) @@ -690,13 +711,13 @@ mod tests { ping_emission(SELF_ZONE, target_program_id, b"hi") } - fn peer_msg(data: Vec, slot: u64) -> (ZoneMessage, Slot) { + fn peer_msg(data: Vec, slot: u64) -> (ZoneMessage, SequencerCheckpoint) { ( ZoneMessage::Block(ZoneBlock { id: MsgId::from([0; 32]), data: Inscription::try_from(data).expect("test inscription is within bounds"), }), - Slot::from(slot), + checkpoint(slot), ) } @@ -728,12 +749,12 @@ mod tests { ) } - fn block_msg(block: &Block, slot: u64) -> (ZoneMessage, Slot) { + fn block_msg(block: &Block, slot: u64) -> (ZoneMessage, SequencerCheckpoint) { peer_msg(borsh::to_vec(block).expect("block serializes"), slot) } /// A stream item carrying the peer's block `block_id`. - fn peer_block_msg(block_id: u64, slot: u64) -> (ZoneMessage, Slot) { + fn peer_block_msg(block_id: u64, slot: u64) -> (ZoneMessage, SequencerCheckpoint) { block_msg(&chain_block(block_id), slot) } @@ -743,7 +764,7 @@ mod tests { block_id: u64, slot: u64, target_program_id: lee_core::program::ProgramId, - ) -> (ZoneMessage, Slot) { + ) -> (ZoneMessage, SequencerCheckpoint) { block_msg(&chain_block_to(block_id, target_program_id), slot) } @@ -755,10 +776,19 @@ mod tests { } } - fn undecodable_msg(slot: u64) -> (ZoneMessage, Slot) { + fn undecodable_msg(slot: u64) -> (ZoneMessage, SequencerCheckpoint) { peer_msg(b"not a block".to_vec(), slot) } + fn checkpoint(slot: u64) -> SequencerCheckpoint { + SequencerCheckpoint { + last_msg_id: MsgId::from([0; 32]), + pending_txs: vec![], + lib: [42; 32].into(), + lib_slot: Slot::from(slot), + } + } + /// The message keys recorded so far, sorted: the store keys each record by /// its message key, so no insertion order survives. async fn recorded_keys(storage_ref: &ActorRef) -> Vec<[u8; 32]> { @@ -870,16 +900,16 @@ mod tests { // A store written before chain pinning. The floor is cleared rather // than ignored so a crash mid-rebuild does not resume from it either. assert_eq!( - resume_from(None, Some(Slot::from(7))), + resume_from(None, Some(checkpoint(7))), Resume { cursor: None, clear_floor: true } ); assert_eq!( - resume_from(Some(tip_at(2)), Some(Slot::from(7))), + resume_from(Some(tip_at(2)), Some(checkpoint(7))), Resume { - cursor: Some(Slot::from(7)), + cursor: Some(checkpoint(7)), clear_floor: false }, "an ordinary restart resumes where it left off and keeps its floor" @@ -910,12 +940,15 @@ mod tests { .await; assert_eq!(outcome, PassOutcome::Drained); - assert_eq!(cursor, Some(Slot::from(1))); - assert_eq!( - get_cross_zone_peer_floor(&storage_ref, PEER_ZONE) - .await - .unwrap(), - Some(Slot::from(1)), + assert!(checkpoint_eq_opt(cursor.as_ref(), Some(&checkpoint(1)))); + assert!( + checkpoint_eq_opt( + get_cross_zone_peer_floor(&storage_ref, PEER_ZONE) + .await + .unwrap() + .as_ref(), + Some(&checkpoint(1)) + ), "the cursor must be durable, not just in memory" ); let mut expected = vec![message_key(&PEER_ZONE, 1, 0), message_key(&PEER_ZONE, 2, 0)]; @@ -956,11 +989,15 @@ mod tests { recorded_keys(&storage_ref).await.is_empty(), "a message aimed at a sequencer-only program must not be recorded" ); - assert_eq!( - get_cross_zone_peer_floor(&storage_ref, PEER_ZONE) - .await - .unwrap(), - Some(Slot::from(0)), + + assert!( + checkpoint_eq_opt( + get_cross_zone_peer_floor(&storage_ref, PEER_ZONE) + .await + .unwrap() + .as_ref(), + Some(&checkpoint(0)) + ), "the slot was fully read, so the floor still advances" ); } @@ -1091,11 +1128,14 @@ mod tests { // that failed to record must not let it move, or the delivery is lost // rather than retried. assert_eq!(outcome, PassOutcome::Undelivered(Slot::from(0))); - assert_eq!( - get_cross_zone_peer_floor(&storage_ref, PEER_ZONE) - .await - .unwrap(), - None, + assert!( + checkpoint_eq_opt( + get_cross_zone_peer_floor(&storage_ref, PEER_ZONE) + .await + .unwrap() + .as_ref(), + None + ), "the slot must stay re-readable" ); // The tip is written after the deliveries, never before. Ahead of them a @@ -1135,7 +1175,7 @@ mod tests { let resumed = get_cross_zone_peer_floor(&storage_ref, PEER_ZONE) .await .unwrap(); - assert_eq!(resumed, Some(Slot::from(1))); + assert!(checkpoint_eq_opt(resumed.as_ref(), Some(&checkpoint(1)))); let mut resumed_tip = storage_ref .ask(GetCrossZonePeerTip { peer_zone: PEER_ZONE, @@ -1170,12 +1210,13 @@ mod tests { expected, "only the unread block is recorded on the second pass" ); - assert_eq!( + assert!(checkpoint_eq_opt( get_cross_zone_peer_floor(&storage_ref, PEER_ZONE) .await - .unwrap(), - Some(Slot::from(2)) - ); + .unwrap() + .as_ref(), + Some(&checkpoint(2)) + ),); } #[tokio::test] @@ -1200,12 +1241,13 @@ mod tests { // A durable cursor makes this load-bearing: advancing past the bad block // would drop its messages permanently rather than until the next restart. assert_eq!(outcome, PassOutcome::Undecodable(Slot::from(1))); - assert_eq!( + assert!(checkpoint_eq_opt( get_cross_zone_peer_floor(&storage_ref, PEER_ZONE) .await - .unwrap(), - Some(Slot::from(0)) - ); + .unwrap() + .as_ref(), + Some(&checkpoint(0)) + ),); assert_eq!( recorded_keys(&storage_ref).await, vec![message_key(&PEER_ZONE, 1, 0)], @@ -1232,13 +1274,17 @@ mod tests { .await; assert_eq!(outcome, PassOutcome::Undecodable(Slot::from(4))); - assert_eq!(cursor, None, "slot 4 is re-read whole on the next pass"); - assert_eq!( + assert!( + checkpoint_eq_opt(cursor.as_ref(), None), + "slot 4 is re-read whole on the next pass" + ); + assert!(checkpoint_eq_opt( get_cross_zone_peer_floor(&storage_ref, PEER_ZONE) .await - .unwrap(), + .unwrap() + .as_ref(), None - ); + )); assert_eq!( recorded_keys(&storage_ref).await, vec![message_key(&PEER_ZONE, 1, 0)] @@ -1275,11 +1321,14 @@ mod tests { vec![message_key(&PEER_ZONE, 1, 0)], "no pass reads past the slot it cannot decode" ); - assert_eq!( - get_cross_zone_peer_floor(&storage_ref, PEER_ZONE) - .await - .unwrap(), - Some(Slot::from(0)), + assert!( + checkpoint_eq_opt( + get_cross_zone_peer_floor(&storage_ref, PEER_ZONE) + .await + .unwrap() + .as_ref(), + Some(&checkpoint(0)) + ), "the floor stays below it, so a fixed decoder recovers the messages" ); assert_eq!(tip, Some(tip_at(1))); @@ -1526,7 +1575,7 @@ mod tests { // partway through the rebuild would otherwise leave a floor far above a // tip of 1, and nothing read after that restart could link. let (_dir, storage_ref) = store().await; - set_cross_zone_peer_floor(&storage_ref, PEER_ZONE, Slot::from(5000)) + set_cross_zone_peer_floor(&storage_ref, PEER_ZONE, checkpoint(5000)) .await .unwrap(); @@ -1540,17 +1589,20 @@ mod tests { .await .unwrap(); let resume = resume_from(tip, floor); - assert_eq!(resume.cursor, None, "the rebuild reads from genesis"); + assert!( + checkpoint_eq_opt(resume.cursor.as_ref(), None), + "the rebuild reads from genesis" + ); assert!(resume.clear_floor); clear_cross_zone_peer_floor(&storage_ref, PEER_ZONE) .await .unwrap(); - assert_eq!( + assert!( get_cross_zone_peer_floor(&storage_ref, PEER_ZONE) .await - .unwrap(), - None, + .unwrap() + .is_none(), "and a crash mid-rebuild resumes from genesis too, not from slot 5000" ); } diff --git a/lez/sequencer/core/src/lib.rs b/lez/sequencer/core/src/lib.rs index 49e619973..887a36c68 100644 --- a/lez/sequencer/core/src/lib.rs +++ b/lez/sequencer/core/src/lib.rs @@ -26,7 +26,7 @@ use logos_blockchain_core::mantle::ops::channel::Ed25519PublicKey; use logos_blockchain_key_management_system_service::keys::{ED25519_SECRET_KEY_SIZE, Ed25519Key}; use logos_blockchain_zone_sdk::{ Slot, ZoneMessage, - sequencer::{DepositInfo, WithdrawArg}, + sequencer::{DepositInfo, SequencerCheckpoint, WithdrawArg}, }; use mempool::{MemPool, MemPoolHandle}; #[cfg(feature = "mock")] @@ -444,9 +444,6 @@ impl SequencerCore { .await .context("Failed to read zone anchor")?; - let after_slot = anchor_record - .and_then(|record| record.slot.checked_sub(1)) - .map(Slot::from); let channel_tip_slot = publisher .channel_tip_slot() .await @@ -472,6 +469,7 @@ impl SequencerCore { .context("Failed to read latest block meta")? .map(|meta| meta.id); let had_checkpoint_before_start = !is_fresh_start; + if let Some(local_tip) = local_tip && had_checkpoint_before_start && channel_tip_slot.is_none() @@ -493,15 +491,13 @@ impl SequencerCore { // With a recorded anchor, probe the channel for positive evidence of a // different chain: the frontier upfront (a missing/behind channel serves // no messages to scan), then the anchor block as messages stream in. - let mut consistency_check = anchor_record.map(|record| { - let anchor = Anchor::new( - Slot::from(record.slot), - Some((record.block_id, record.hash)), - ); + let mut consistency_check = anchor_record.clone().map(|record| { + let anchor = Anchor::new(record.checkpoint, Some((record.block_id, record.hash))); let mut check = AnchorConsistencyCheck::new(anchor); check.check_frontier(channel_tip_slot); check }); + if let Some(ChainConsistency::Inconsistent(mismatch)) = consistency_check .as_ref() .and_then(AnchorConsistencyCheck::verdict) @@ -512,11 +508,11 @@ impl SequencerCore { // Verify each message against the anchor and replay the // blocks (applying the ones we miss, checking the ones we hold). let messages = publisher - .read_channel_after(after_slot) - .await - .context("Failed to read channel history for reconstruction")?; + .read_channel_after(anchor_record.map(|an| an.checkpoint)) + .await; let mut messages = std::pin::pin!(messages); - while let Some((message, slot)) = messages.next().await { + while let Some((message, checkpoint)) = messages.next().await { + let slot = checkpoint.lib_slot; if let Some(check) = &mut consistency_check && let Some(ChainConsistency::Inconsistent(mismatch)) = check.observe(&message, slot) @@ -537,7 +533,8 @@ impl SequencerCore { // follow events interleave safely — both paths apply idempotently // and persist under this same lock. let mut chain = chain.lock().await; - Self::apply_reconstructed_block(store.storage_ref(), &mut chain, &block, slot).await?; + Self::apply_reconstructed_block(store.storage_ref(), &mut chain, &block, checkpoint) + .await?; } // The channel exists once it has a tip; only when it has none is this @@ -556,7 +553,7 @@ impl SequencerCore { storage_ref: &ActorRef, chain: &mut ChainState, block: &Block, - slot: Slot, + checkpoint: SequencerCheckpoint, ) -> Result<()> { let tip = storage_ref .ask(GetLatestBlockMeta) @@ -566,7 +563,7 @@ impl SequencerCore { let block_hash = block.header.hash; let record = ZoneAnchorRecord { - slot: slot.into_inner(), + checkpoint: checkpoint.clone(), block_id, hash: block_hash, }; @@ -611,7 +608,7 @@ impl SequencerCore { // Above the final tier the head is reorg-able, so finalized history // wins: `apply_finalized` finalizes the matching prefix and rebases the // head onto what the channel settled. Validation happens inside it. - match chain.apply_finalized(MsgId::from(block.header.hash.0), block, slot) { + match chain.apply_finalized(MsgId::from(block.header.hash.0), block, checkpoint) { AcceptOutcome::Applied | AcceptOutcome::AlreadyApplied => {} AcceptOutcome::Parked(err) | AcceptOutcome::RetryableFailure(err) => { return Err(anyhow!( @@ -639,6 +636,7 @@ impl SequencerCore { // itself landed. let head_tip = chain.head_tip().map(|head| BlockMeta::from(&head)); let final_meta = chain.final_tip().map(|meta| BlockMeta::from(&meta)); + storage_ref .ask(ApplyStoreUpdate { blocks: vec![(block.clone(), true)], @@ -1595,7 +1593,16 @@ async fn apply_follow_update( // logos-blockchain PR #3147 surfaces it as `FinalizedTx.l1_slot` — // wire it through `FollowUpdate::finalized` once the zone-sdk pin is // bumped past that (a separate PR). - match chain.apply_finalized(*this_msg, block, Slot::from(0)) { + match chain.apply_finalized( + *this_msg, + block, + SequencerCheckpoint { + last_msg_id: [0; 32].into(), + pending_txs: vec![], + lib: [0; 32].into(), + lib_slot: Slot::from(0), + }, + ) { AcceptOutcome::Applied => { to_persist.push((block, true)); irreversible.push(block); @@ -2432,3 +2439,5 @@ pub fn load_or_create_stake_signing_key(path: &Path) -> Result #[cfg(test)] #[cfg(feature = "mock")] mod tests; + +// tests::reconstruction::fails_when_channel_serves_a_divergent_block diff --git a/lez/sequencer/core/src/mock.rs b/lez/sequencer/core/src/mock.rs index 4cfe6775d..8e6a8b1bf 100644 --- a/lez/sequencer/core/src/mock.rs +++ b/lez/sequencer/core/src/mock.rs @@ -29,7 +29,7 @@ pub struct MockBlockPublisher { /// Canned channel frontier returned by [`Self::channel_tip_slot`]. tip_slot: Option, /// Canned finalized channel history returned by [`Self::read_channel_after`]. - messages: Vec<(ZoneMessage, Slot)>, + messages: Vec<(ZoneMessage, SequencerCheckpoint)>, } impl MockBlockPublisher { @@ -40,7 +40,7 @@ impl MockBlockPublisher { pub fn with_canned_channel( channel_id: ChannelId, tip_slot: Option, - messages: Vec<(ZoneMessage, Slot)>, + messages: Vec<(ZoneMessage, SequencerCheckpoint)>, ) -> Self { Self { channel_id, @@ -124,15 +124,19 @@ impl BlockPublisherTrait for MockBlockPublisher { async fn read_channel_after( &self, - after_slot: Option, - ) -> Result + Send + '_> { + checkpoint: Option, + ) -> impl Stream { // Mirror `next_messages`: `after_slot` is exclusive. let messages = self .messages .iter() - .filter(move |(_, slot)| after_slot.is_none_or(|after| *slot > after)) + .filter(move |(_, checkp)| { + checkpoint + .clone() + .is_none_or(|after| checkp.lib_slot >= after.lib_slot) + }) .cloned(); - Ok(futures::stream::iter(messages)) + futures::stream::iter(messages) } } diff --git a/lez/sequencer/core/src/tests.rs b/lez/sequencer/core/src/tests.rs index b479ce6ec..e8b825326 100644 --- a/lez/sequencer/core/src/tests.rs +++ b/lez/sequencer/core/src/tests.rs @@ -9,10 +9,20 @@ use common::{ transaction::{LeeTransaction, clock_invocation}, }; use kameo::actor::Spawn as _; +use key_protocol::key_management::KeyChain; use lee::{ - Account, AccountId, Data, PrivateKey, PublicKey, PublicTransaction, V03State, program::Program, + Account, AccountId, Data, PrivacyPreservingTransaction, PrivateKey, PublicKey, + PublicTransaction, V03State, + error::LeeError, + execute_and_prove, + privacy_preserving_transaction::{Message, circuit::ProgramWithDependencies}, + program::Program, +}; +use lee_core::{ + Commitment, InputAccountIdentity, Nullifier, NullifierWitness, PrivateWitness, WitnessKind, + account::{AccountWithMetadata, Nonce}, + program::PdaSeed, }; -use lee_core::{account::Nonce, program::PdaSeed}; use logos_blockchain_core::{ events::DepositRecreatedNotes, mantle::{ @@ -1708,94 +1718,98 @@ async fn block_production_aborts_when_clock_account_data_is_corrupted() { ); } -// #[test] -// fn private_bridge_withdraw_invocation_is_dropped() { -// let sender_keys = KeyChain::new_os_random(); -// let sender_account_id = AccountId::for_regular_private_account( -// &sender_keys.nullifier_public_key, -// &sender_keys.viewing_public_key, -// 0, -// ); -// let sender_private_account = Account { -// program_owner: programs::authenticated_transfer().id().into(), -// balance: 100, -// nonce: Nonce(0xdead_beef), -// data: Data::default(), -// }; -// let bridge_account_id = system_accounts::bridge_account_id(); - -// let mut state = V03State::new() -// .with_public_accounts([(bridge_account_id, system_accounts::bridge_account())]) -// .with_private_accounts([( -// Commitment::new(&sender_account_id, &sender_private_account), -// Nullifier::for_account_initialization(&sender_account_id), -// )]); - -// let sender_commitment = Commitment::new(&sender_account_id, &sender_private_account); - -// let sender_pre = AccountWithMetadata::new( -// sender_private_account, -// true, -// ( -// &sender_keys.nullifier_public_key, -// &sender_keys.viewing_public_key, -// 0, -// ), -// ); -// let bridge_pre = AccountWithMetadata::new( -// state.get_account_by_id(bridge_account_id), -// false, -// bridge_account_id, -// ); - -// let instruction = Program::serialize_instruction(bridge_core::Instruction::Withdraw { -// amount: 1, -// bedrock_account_pk: [0; 32], -// }) -// .unwrap(); - -// let program_with_deps = ProgramWithDependencies::new( -// programs::bridge(), -// [( -// programs::authenticated_transfer().id(), -// programs::authenticated_transfer(), -// )] -// .into(), -// ); - -// let (output, proof) = execute_and_prove( -// vec![sender_pre, bridge_pre], -// instruction, -// vec![ -// InputAccountIdentity::PrivateAuthorizedUpdate { -// vpk: sender_keys.viewing_public_key.clone(), -// random_seed: [0; 32], -// view_tag: 0, -// nsk: sender_keys.private_key_holder.nullifier_secret_key, -// membership_proof: state -// .get_proof_for_commitment(&sender_commitment) -// .expect("sender commitment must be in state"), -// identifier: 0, -// }, -// InputAccountIdentity::Public, -// ], -// &program_with_deps, -// ) -// .expect("Execution should succeed"); - -// let message = Message::try_from_circuit_output(vec![bridge_account_id], vec![], output) -// .expect("Message construction should succeed"); -// let witness_set = -// lee::privacy_preserving_transaction::WitnessSet::for_message(&message, proof, &[]); -// let tx = -// LeeTransaction::PrivacyPreserving(PrivacyPreservingTransaction::new(message, -// witness_set)); let res = tx.execute_check_on_state(&mut state, 1, 0); - -// assert!( -// matches!(res, Err(LeeError::InvalidInput(_))), -// "Bridge withdraw invocation should be rejected in private execution" -// ); -// } +#[test] +fn private_bridge_withdraw_invocation_is_dropped() { + let sender_keys = KeyChain::new_os_random(); + let sender_account_id = AccountId::for_regular_private_account( + &sender_keys.nullifier_public_key, + &sender_keys.viewing_public_key, + 0, + ); + let sender_private_account = Account { + program_owner: programs::authenticated_transfer().id().into(), + balance: 100, + nonce: Nonce(0xdead_beef), + data: Data::default(), + }; + let bridge_account_id = system_accounts::bridge_account_id(); + + let mut state = V03State::new() + .with_public_accounts([(bridge_account_id, system_accounts::bridge_account())]) + .with_private_accounts([( + Commitment::new(&sender_account_id, &sender_private_account), + Nullifier::for_account_initialization(&sender_account_id), + )]); + + let sender_commitment = Commitment::new(&sender_account_id, &sender_private_account); + + let sender_pre = AccountWithMetadata::new( + sender_private_account, + true, + ( + &sender_keys.nullifier_public_key, + &sender_keys.viewing_public_key, + 0, + ), + ); + let bridge_pre = AccountWithMetadata::new( + state.get_account_by_id(bridge_account_id), + false, + bridge_account_id, + ); + + let instruction = Program::serialize_instruction(bridge_core::Instruction::Withdraw { + amount: 1, + bedrock_account_pk: [0; 32], + }) + .unwrap(); + + let program_with_deps = ProgramWithDependencies::new( + programs::bridge(), + [( + programs::authenticated_transfer().id(), + programs::authenticated_transfer(), + )] + .into(), + ); + + let (output, proof) = execute_and_prove( + vec![sender_pre, bridge_pre], + instruction, + vec![ + InputAccountIdentity::Private(PrivateWitness { + vpk: sender_keys.viewing_public_key.clone(), + random_seed: [0; 32], + kind: WitnessKind::Regular { + ask: Some(sender_keys.private_key_holder.authorization_secret_key), + }, + nullifier: NullifierWitness::Update { + view_tag: 0, + nsk: sender_keys.private_key_holder.nullifier_secret_key(), + membership_proof: state + .get_proof_for_commitment(&sender_commitment) + .expect("sender commitment must be in state"), + }, + identifier: 0, + }), + InputAccountIdentity::Public, + ], + &program_with_deps, + ) + .expect("Execution should succeed"); + + let message = Message::from_circuit_output(vec![], output); + let witness_set = + lee::privacy_preserving_transaction::WitnessSet::for_message(&message, proof, &[]); + let tx = + LeeTransaction::PrivacyPreserving(PrivacyPreservingTransaction::new(message, witness_set)); + let res = tx.execute_check_on_state(&mut state, 1, 0); + + assert!( + matches!(res, Err(LeeError::InvalidInput(_))), + "Bridge withdraw invocation should be rejected in private execution" + ); +} /// Builds a [`V03State`] with the clock program and `program` registered, the three clock /// accounts initialized, and the clock advanced to `clock_timestamp` so that reads of the diff --git a/lez/sequencer/core/src/tests/reconstruction.rs b/lez/sequencer/core/src/tests/reconstruction.rs index d61d12480..b6c90958e 100644 --- a/lez/sequencer/core/src/tests/reconstruction.rs +++ b/lez/sequencer/core/src/tests/reconstruction.rs @@ -7,10 +7,13 @@ use chain_state::ChainState; use common::block::Block; use logos_blockchain_core::mantle::ops::channel::{MsgId, inscribe::Inscription}; -use logos_blockchain_zone_sdk::{Slot, ZoneBlock, ZoneMessage}; +use logos_blockchain_zone_sdk::{Slot, ZoneBlock, ZoneMessage, sequencer::SequencerCheckpoint}; use sequencer_storage_actor::{ StorageActorTrait, - protocol::{AddPendingCrossZoneDispatches, AddPendingDepositEvent, ZoneAnchorRecord}, + protocol::{ + AddPendingCrossZoneDispatches, AddPendingDepositEvent, ConsumeUnseenWithdrawCount, + GetPendingDepositEvents, WithdrawalReconciliationKey, ZoneAnchorRecord, + }, }; use tokio::sync::Mutex; @@ -19,6 +22,15 @@ use crate::{ SequencerCore, block_store::SequencerStore, config::GenesisAction, mock::MockBlockPublisher, }; +fn checkpoint(slot: u64) -> SequencerCheckpoint { + SequencerCheckpoint { + last_msg_id: [0; 32].into(), + pending_txs: vec![], + lib: [42; 32].into(), + lib_slot: Slot::from(slot), + } +} + /// Fresh `(store, chain)` pair for a reconstruction target, as /// `start_from_config` would build them before the publisher starts. // TODO: Revisit this function, it relies to heavily on internal implementation details. @@ -53,13 +65,13 @@ async fn fresh_store_and_chain( (store, chain) } -fn block_to_channel_message(block: &Block, slot: u64) -> (ZoneMessage, Slot) { +fn block_to_channel_message(block: &Block, slot: u64) -> (ZoneMessage, SequencerCheckpoint) { let bytes = borsh::to_vec(block).expect("serialize block"); let message = ZoneMessage::Block(ZoneBlock { id: MsgId::from([0_u8; 32]), data: Inscription::try_from(bytes.as_slice()).expect("inscription"), }); - (message, Slot::from(slot)) + (message, checkpoint(slot)) } /// Collects a sequencer's whole chain (genesis..=tip) into a canned channel, @@ -67,7 +79,7 @@ fn block_to_channel_message(block: &Block, slot: u64) -> (ZoneMessage, Slot) { async fn channel_from_store( store: &SequencerStore, slot_step: u64, -) -> Vec<(ZoneMessage, Slot)> { +) -> Vec<(ZoneMessage, SequencerCheckpoint)> { let genesis_id = store.genesis_id(); let tip_id = store .latest_block_meta() @@ -101,7 +113,7 @@ async fn reconstructs_missing_channel_blocks_into_fresh_store() { .unwrap(); let messages = channel_from_store(seq_a.block_store(), 10).await; - let tip_slot = messages.last().unwrap().1; + let tip_slot = messages.last().unwrap().1.lib_slot; let channel_id = config_a.bedrock_config.channel_id; // Sequencer B starts from a fresh store and reconstructs A's chain. @@ -136,7 +148,7 @@ async fn reconstructs_missing_channel_blocks_into_fresh_store() { .unwrap() .expect("anchor recorded"); assert_eq!(anchor.block_id, tip_a.id); - assert_eq!(anchor.slot, tip_slot.into_inner()); + assert_eq!(anchor.checkpoint.lib_slot, tip_slot); // Re-running is idempotent: everything is already applied, no error. let channel_was_empty = SequencerCore::::verify_and_reconstruct( @@ -160,9 +172,10 @@ async fn fails_when_channel_serves_a_divergent_block() { let genesis_id = store.genesis_id(); let genesis = store.block_at_id(genesis_id).await.unwrap().unwrap(); let anchor_slot = 100_u64; + let anchor_checkpoint = checkpoint(anchor_slot); store .set_zone_anchor(ZoneAnchorRecord { - slot: anchor_slot, + checkpoint: anchor_checkpoint, block_id: genesis_id, hash: genesis.header.hash, }) @@ -193,7 +206,7 @@ async fn fails_when_channel_is_missing() { let genesis = store.block_at_id(genesis_id).await.unwrap().unwrap(); store .set_zone_anchor(ZoneAnchorRecord { - slot: 100, + checkpoint: checkpoint(100), block_id: genesis_id, hash: genesis.header.hash, }) @@ -358,7 +371,7 @@ async fn reconstruction_ignores_a_duplicate_height_the_final_tier_settled() { .unwrap() .unwrap(); let mut messages = channel_from_store(seq_a.block_store(), 10).await; - let settled_slot = messages.last().unwrap().1; + let settled_slot = messages.last().unwrap().1.lib_slot; // Sequencer B: the cold-start backfill finalizes A's chain into its store. let (seq_b, mempool_b) = start_sequencer(setup_sequencer_config()).await; @@ -432,7 +445,7 @@ async fn reconstruction_ignores_a_duplicate_height_the_final_tier_settled() { .await .unwrap() .expect("anchor"); - assert_eq!(anchor.slot, settled_slot.into_inner()); + assert_eq!(anchor.checkpoint.lib_slot, settled_slot); assert_eq!(anchor.hash, tip_a.hash); } @@ -451,7 +464,7 @@ async fn reconstruction_replaces_a_conflicting_head_block_with_finalized_history .unwrap() .unwrap(); let messages = channel_from_store(seq_a.block_store(), 10).await; - let tip_slot = messages.last().unwrap().1; + let tip_slot = messages.last().unwrap().1.lib_slot; // Sequencer B adopted a competitor at that height and never saw it finalize. let (seq_b, mempool_b) = start_sequencer(setup_sequencer_config()).await; @@ -539,230 +552,263 @@ fn deposit_event_record( } } -// /// Builds a signed public bridge `Withdraw` transaction (the normal user path). -// fn build_public_withdraw_tx( -// sender: lee::AccountId, -// nonce: u128, -// amount: u64, -// bedrock_account_pk: [u8; 32], -// signing_key: &lee::PrivateKey, -// ) -> LeeTransaction { -// let message = lee::public_transaction::Message::try_new( -// programs::bridge().id(), -// vec![sender, system_accounts::bridge_account_id()], -// vec![nonce.into()], -// bridge_core::Instruction::Withdraw { -// amount, -// bedrock_account_pk, -// }, -// ) -// .unwrap(); -// let witness_set = lee::public_transaction::WitnessSet::for_message(&message, &[signing_key]); -// LeeTransaction::Public(lee::PublicTransaction::new(message, witness_set)) -// } - -// /// The reconciliation key a produced block carries for `withdraw_tx`, keyed on -// /// the note [`MockBlockPublisher`] reports as released for it. -// fn produced_withdraw_key(withdraw_tx: &LeeTransaction) -> WithdrawalReconciliationKey { -// let withdraw_arg = crate::extract_bridge_withdraw_data(withdraw_tx).expect("withdraw data"); -// let [note_id] = crate::mock::mock_released_notes(std::slice::from_ref(&withdraw_arg))[..] -// else { -// panic!("A bridge withdraw releases exactly one note"); -// }; - -// crate::withdrawal_reconciliation_key(¬e_id) -// } - -// /// Cold-start backfill re-records an already-finalized deposit event as a -// /// pending record before reconstruction replays the same deposit block. -// /// Reconstruction must drop that record — its mint is permanently reflected in -// /// the reconstructed state (the receipt PDA) — so the next production neither -// /// re-mints the vault nor emits a stray deposit tx. -// #[tokio::test] -// async fn reconstructed_deposit_is_not_reminted_after_backfill_redelivery() { -// let recipient = initial_public_user_accounts()[0].account_id; -// let deposit_amount = 500_u64; -// let withdraw_amount = 100_u64; -// let bedrock_account_pk = [0x22_u8; 32]; -// let deposit_op_id = [0x0d_u8; 32]; - -// // Sequencer A produces a deposit block then a withdraw block. -// let config_a = bridge_funded_config(); -// let (mut seq_a, mempool_a) = -// start_sequencer(config_a.clone()).await; - -// let deposit_record = deposit_event_record(deposit_op_id, deposit_amount, recipient); -// let deposit_tx = -// crate::build_bridge_deposit_tx_from_event(&deposit_record).expect("build deposit tx"); -// mempool_a -// .push((TransactionOrigin::Sequencer, deposit_tx)) -// .await -// .unwrap(); -// seq_a.run_production_turn().await.unwrap(); - -// let withdraw_tx = build_public_withdraw_tx( -// recipient, -// 0, -// withdraw_amount, -// bedrock_account_pk, -// &create_signing_key_for_account1(), -// ); -// mempool_a -// .push((TransactionOrigin::User, withdraw_tx.clone())) -// .await -// .unwrap(); -// seq_a.run_production_turn().await.unwrap(); - -// let tip_a = seq_a.block_store().latest_block_meta().await.unwrap().unwrap(); -// let messages = channel_from_store(seq_a.block_store(), 10).await; -// let tip_slot = messages.last().unwrap().1; -// let channel_id = config_a.bedrock_config.channel_id; - -// let config_b = bridge_funded_config(); -// let (mut seq_b, _mempool_b) = -// start_sequencer(config_b).await; - -// // Backfill re-delivery: the deposit event is re-recorded as a pending record -// // before reconstruction runs. The mint no longer flows through the mempool -// // (that sink was removed); the store drain is the only source. -// assert!( -// seq_b -// .block_store() -// .dbio() -// .add_pending_deposit_event(deposit_record.clone()) -// .unwrap() -// ); - -// let mock_b = MockBlockPublisher::with_canned_channel(channel_id, Some(tip_slot), messages); -// SequencerCore::::verify_and_reconstruct( -// &mock_b, -// &seq_b.store, -// &seq_b.chain, -// true, -// ) -// .await -// .expect("reconstruct"); - -// let tip_b = seq_b.block_store().latest_block_meta().await.unwrap().unwrap(); -// assert_eq!(tip_b.id, tip_a.id); -// assert_eq!(tip_b.hash, tip_a.hash); - -// // Reconstruction replays the finalized deposit block, minting the receipt -// // into state and dropping the re-recorded pending event — so the drain has -// // nothing left to re-mint. This is the mechanism that protects against the -// // re-delivery, in place of the removed mempool sink. -// assert!( -// seq_b -// .block_store() -// .dbio() -// .get_pending_deposit_events() -// .unwrap() -// .is_empty(), -// "reconstruction must drop the re-delivered pending deposit record" -// ); - -// seq_b.run_production_turn().await.unwrap(); - -// let vault_id = vault_core::compute_vault_account_id(programs::vault().id(), recipient); -// let bridge_id = system_accounts::bridge_account_id(); -// let state_b = seq_b.chain().lock().await.head_state().clone(); -// let state_a = seq_a.chain().lock().await.head_state().clone(); -// for account in [vault_id, bridge_id, recipient] { -// assert_eq!( -// state_b.get_account_by_id(account).balance, -// state_a.get_account_by_id(account).balance, -// "reconstructed balance mismatch for {account:?}", -// ); -// } -// assert_eq!( -// state_b.get_account_by_id(vault_id).balance, -// u128::from(deposit_amount), -// "deposit must mint into the recipient vault exactly once, not twice" -// ); - -// let produced = seq_b -// .block_store() -// .block_at_id(tip_b.id + 1) -// .unwrap() -// .expect("produced block present"); -// assert!( -// !produced -// .body -// .transactions -// .iter() -// .any(|tx| crate::extract_bridge_deposit_id(tx) == Some(HashType(deposit_op_id))), -// "the re-delivered mint must be skipped, not re-included in a block" -// ); - -// // A reconstructed withdraw's finalized L1 event was already re-delivered (and -// // dropped) by cold-start backfill, so it will never be consumed again. -// // Reconstruction must not count it, or the count stays phantom-inflated forever. -// let key = produced_withdraw_key(&withdraw_tx); -// assert!( -// !seq_b -// .block_store() -// .dbio() -// .consume_unseen_withdraw_count(key) -// .unwrap(), -// "reconstruction must not leave a phantom unseen-withdraw count" -// ); -// } - -// /// A reconstructed withdraw block must not touch the unseen-withdraw counter. -// /// Its finalized L1 Withdraw event was already re-delivered (and dropped as a -// /// no-op) by cold-start backfill, so counting it during reconstruction would -// /// leave a permanent phantom that nothing ever consumes. -// #[tokio::test] -// async fn reconstructed_withdraw_leaves_no_phantom_unseen_count() { -// let recipient = initial_public_user_accounts()[0].account_id; -// let withdraw_amount = 100_u64; -// let bedrock_account_pk = [0x33_u8; 32]; - -// // Sequencer A produces a single withdraw block; treat its chain as the channel. -// let config_a = bridge_funded_config(); -// let (mut seq_a, mempool_a) = -// start_sequencer(config_a.clone()).await; -// let withdraw_tx = build_public_withdraw_tx( -// recipient, -// 0, -// withdraw_amount, -// bedrock_account_pk, -// &create_signing_key_for_account1(), -// ); -// mempool_a -// .push((TransactionOrigin::User, withdraw_tx.clone())) -// .await -// .unwrap(); -// seq_a.run_production_turn().await.unwrap(); - -// let key = produced_withdraw_key(&withdraw_tx); -// // Producing the withdraw counts it as unseen, awaiting its L1 event. -// assert!( -// seq_a -// .block_store() -// .dbio() -// .consume_unseen_withdraw_count(key) -// .unwrap(), -// "producing a withdraw must count it as unseen" -// ); - -// let messages = channel_from_store(seq_a.block_store(), 10).await; -// let tip_slot = messages.last().unwrap().1; -// let channel_id = config_a.bedrock_config.channel_id; - -// // Sequencer B reconstructs A's chain from a fresh store. -// let config_b = bridge_funded_config(); -// let (store_b, chain_b) = fresh_store_and_chain(&config_b).await; -// let mock_b = MockBlockPublisher::with_canned_channel(channel_id, Some(tip_slot), messages); -// SequencerCore::::verify_and_reconstruct(&mock_b, &store_b, &chain_b, -// true) .await -// .expect("reconstruct"); - -// assert!( -// !dbio_b.consume_unseen_withdraw_count(key).unwrap(), -// "reconstruction must not leave a phantom unseen-withdraw count" -// ); -// } +/// Builds a signed public bridge `Withdraw` transaction (the normal user path). +fn build_public_withdraw_tx( + sender: lee::AccountId, + nonce: u128, + amount: u64, + bedrock_account_pk: [u8; 32], + signing_key: &lee::PrivateKey, +) -> LeeTransaction { + let message = lee::public_transaction::Message::try_new( + programs::bridge().id(), + vec![sender, system_accounts::bridge_account_id()], + vec![nonce.into()], + bridge_core::Instruction::Withdraw { + amount, + bedrock_account_pk, + }, + ) + .unwrap(); + let witness_set = lee::public_transaction::WitnessSet::for_message(&message, &[signing_key]); + LeeTransaction::Public(lee::PublicTransaction::new(message, witness_set)) +} + +/// The reconciliation key a produced block carries for `withdraw_tx`, keyed on +/// the note [`MockBlockPublisher`] reports as released for it. +fn produced_withdraw_key(withdraw_tx: &LeeTransaction) -> WithdrawalReconciliationKey { + let withdraw_arg = crate::extract_bridge_withdraw_data(withdraw_tx).expect("withdraw data"); + let [note_id] = crate::mock::mock_released_notes(std::slice::from_ref(&withdraw_arg))[..] + else { + panic!("A bridge withdraw releases exactly one note"); + }; + + crate::withdrawal_reconciliation_key(¬e_id) +} + +/// Cold-start backfill re-records an already-finalized deposit event as a +/// pending record before reconstruction replays the same deposit block. +/// Reconstruction must drop that record — its mint is permanently reflected in +/// the reconstructed state (the receipt PDA) — so the next production neither +/// re-mints the vault nor emits a stray deposit tx. +#[tokio::test] +async fn reconstructed_deposit_is_not_reminted_after_backfill_redelivery() { + let recipient = initial_public_user_accounts()[0].account_id; + let deposit_amount = 500_u64; + let withdraw_amount = 100_u64; + let bedrock_account_pk = [0x22_u8; 32]; + let deposit_op_id = [0x0d_u8; 32]; + + // Sequencer A produces a deposit block then a withdraw block. + let config_a = bridge_funded_config(); + + let storage = StorageActor::new(&config_a.db_path()).expect("Failed to open database"); + let storage_ref = StorageActor::spawn(storage); + + let (mut seq_a, mempool_a) = + SequencerCoreWithMockClients::start_from_config(config_a.clone(), storage_ref).await; + + let deposit_record = deposit_event_record(deposit_op_id, deposit_amount, recipient); + let deposit_tx = + crate::build_bridge_deposit_tx_from_event(&deposit_record).expect("build deposit tx"); + mempool_a + .push((TransactionOrigin::Sequencer, deposit_tx)) + .await + .unwrap(); + seq_a.run_production_turn().await.unwrap(); + + let withdraw_tx = build_public_withdraw_tx( + recipient, + 0, + withdraw_amount, + bedrock_account_pk, + &create_signing_key_for_account1(), + ); + mempool_a + .push((TransactionOrigin::User, withdraw_tx.clone())) + .await + .unwrap(); + seq_a.run_production_turn().await.unwrap(); + + let tip_a = seq_a + .block_store() + .latest_block_meta() + .await + .unwrap() + .unwrap(); + let messages = channel_from_store(seq_a.block_store(), 10).await; + let tip_slot = messages.last().unwrap().1.lib_slot; + let channel_id = config_a.bedrock_config.channel_id; + + let config_b = bridge_funded_config(); + + let storage = StorageActor::new(&config_b.db_path()).expect("Failed to open database"); + let storage_ref = StorageActor::spawn(storage); + + let (mut seq_b, _mempool_b) = + SequencerCoreWithMockClients::start_from_config(config_b, storage_ref).await; + + // Backfill re-delivery: the deposit event is re-recorded as a pending record + // before reconstruction runs. The mint no longer flows through the mempool + // (that sink was removed); the store drain is the only source. + assert!( + seq_b + .block_store() + .storage_ref() + .ask(AddPendingDepositEvent { + event: deposit_record.clone() + }) + .await + .unwrap() + ); + + let mock_b = MockBlockPublisher::with_canned_channel(channel_id, Some(tip_slot), messages); + SequencerCore::::verify_and_reconstruct( + &mock_b, + &seq_b.store, + &seq_b.chain, + true, + ) + .await + .expect("reconstruct"); + + let tip_b = seq_b + .block_store() + .latest_block_meta() + .await + .unwrap() + .unwrap(); + assert_eq!(tip_b.id, tip_a.id); + assert_eq!(tip_b.hash, tip_a.hash); + + // Reconstruction replays the finalized deposit block, minting the receipt + // into state and dropping the re-recorded pending event — so the drain has + // nothing left to re-mint. This is the mechanism that protects against the + // re-delivery, in place of the removed mempool sink. + assert!( + seq_b + .block_store() + .storage_ref() + .ask(GetPendingDepositEvents {}) + .await + .unwrap() + .is_empty(), + "reconstruction must drop the re-delivered pending deposit record" + ); + + seq_b.run_production_turn().await.unwrap(); + + let vault_id = vault_core::compute_vault_account_id(programs::vault().id(), recipient); + let bridge_id = system_accounts::bridge_account_id(); + let state_b = seq_b.chain().lock().await.head_state().clone(); + let state_a = seq_a.chain().lock().await.head_state().clone(); + for account in [vault_id, bridge_id, recipient] { + assert_eq!( + state_b.get_account_by_id(account).balance, + state_a.get_account_by_id(account).balance, + "reconstructed balance mismatch for {account:?}", + ); + } + assert_eq!( + state_b.get_account_by_id(vault_id).balance, + u128::from(deposit_amount), + "deposit must mint into the recipient vault exactly once, not twice" + ); + + let produced = seq_b + .block_store() + .block_at_id(tip_b.id + 1) + .await + .unwrap() + .expect("produced block present"); + assert!( + !produced + .body + .transactions + .iter() + .any(|tx| crate::extract_bridge_deposit_id(tx) == Some(HashType(deposit_op_id))), + "the re-delivered mint must be skipped, not re-included in a block" + ); + + // A reconstructed withdraw's finalized L1 event was already re-delivered (and + // dropped) by cold-start backfill, so it will never be consumed again. + // Reconstruction must not count it, or the count stays phantom-inflated forever. + let key = produced_withdraw_key(&withdraw_tx); + assert!( + !seq_b + .block_store() + .storage_ref() + .ask(ConsumeUnseenWithdrawCount { withdrawal: key }) + .await + .unwrap(), + "reconstruction must not leave a phantom unseen-withdraw count" + ); +} + +/// A reconstructed withdraw block must not touch the unseen-withdraw counter. +/// Its finalized L1 Withdraw event was already re-delivered (and dropped as a +/// no-op) by cold-start backfill, so counting it during reconstruction would +/// leave a permanent phantom that nothing ever consumes. +#[tokio::test] +async fn reconstructed_withdraw_leaves_no_phantom_unseen_count() { + let recipient = initial_public_user_accounts()[0].account_id; + let withdraw_amount = 100_u64; + let bedrock_account_pk = [0x33_u8; 32]; + + // Sequencer A produces a single withdraw block; treat its chain as the channel. + let config_a = bridge_funded_config(); + + let storage = StorageActor::new(&config_a.db_path()).expect("Failed to open database"); + let storage_ref = StorageActor::spawn(storage); + + let (mut seq_a, mempool_a) = + SequencerCoreWithMockClients::start_from_config(config_a.clone(), storage_ref).await; + let withdraw_tx = build_public_withdraw_tx( + recipient, + 0, + withdraw_amount, + bedrock_account_pk, + &create_signing_key_for_account1(), + ); + mempool_a + .push((TransactionOrigin::User, withdraw_tx.clone())) + .await + .unwrap(); + seq_a.run_production_turn().await.unwrap(); + + let key = produced_withdraw_key(&withdraw_tx); + // Producing the withdraw counts it as unseen, awaiting its L1 event. + assert!( + seq_a + .block_store() + .storage_ref() + .ask(ConsumeUnseenWithdrawCount { withdrawal: key }) + .await + .unwrap(), + "producing a withdraw must count it as unseen" + ); + + let messages = channel_from_store(seq_a.block_store(), 10).await; + let tip_slot = messages.last().unwrap().1.lib_slot; + let channel_id = config_a.bedrock_config.channel_id; + + // Sequencer B reconstructs A's chain from a fresh store. + let config_b = bridge_funded_config(); + let (store_b, chain_b) = fresh_store_and_chain(&config_b).await; + let mock_b = MockBlockPublisher::with_canned_channel(channel_id, Some(tip_slot), messages); + SequencerCore::::verify_and_reconstruct(&mock_b, &store_b, &chain_b, true) + .await + .expect("reconstruct"); + + assert!( + !store_b + .storage_ref() + .ask(ConsumeUnseenWithdrawCount { withdrawal: key }) + .await + .unwrap(), + "reconstruction must not leave a phantom unseen-withdraw count" + ); +} /// A deposit whose L1 event was observed (an unfulfilled pending record /// exists) and whose L2 mint is already contained in a finalized channel block. @@ -788,7 +834,7 @@ async fn reconstruction_reconciles_already_finished_deposit() { seq_a.run_production_turn().await.unwrap(); let messages = channel_from_store(seq_a.block_store(), 10).await; - let tip_slot = messages.last().unwrap().1; + let tip_slot = messages.last().unwrap().1.lib_slot; let channel_id = config_a.bedrock_config.channel_id; // Sequencer B: fresh store, but with the *unfulfilled* pending deposit event @@ -872,7 +918,7 @@ async fn reconstructed_delivery_settles_its_pending_record() { .unwrap() .unwrap(); let messages = channel_from_store(seq_a.block_store(), 10).await; - let tip_slot = messages.last().unwrap().1; + let tip_slot = messages.last().unwrap().1.lib_slot; let channel_id = config_a.bedrock_config.channel_id; // Sequencer B holds the same record, as its own watcher would after reading @@ -979,7 +1025,7 @@ async fn a_verified_own_block_settles_its_delivery_records() { // The channel serves our own chain back, tip included. let messages = channel_from_store(seq.block_store(), 10).await; - let tip_slot = messages.last().unwrap().1; + let tip_slot = messages.last().unwrap().1.lib_slot; let mock = MockBlockPublisher::with_canned_channel( seq.sequencer_config.bedrock_config.channel_id, Some(tip_slot), diff --git a/lez/storage/src/indexer/indexer_cells.rs b/lez/storage/src/indexer/indexer_cells.rs index 416734a03..45dba0c5e 100644 --- a/lez/storage/src/indexer/indexer_cells.rs +++ b/lez/storage/src/indexer/indexer_cells.rs @@ -8,34 +8,11 @@ use crate::{ indexer::{ ACC_NUM_CELL_NAME, BLOCK_HASH_CELL_NAME, BREAKPOINT_CELL_NAME, CF_ACC_META, CF_BREAKPOINT_NAME, CF_HASH_TO_ID, CF_TX_TO_ID, DB_META_CROSS_ZONE_HALT_KEY, - DB_META_LAST_OBSERVED_L1_LIB_HEADER_ID_IN_DB_KEY, DB_META_STALL_REASON_KEY, - DB_META_TIP_SLOT_KEY, DB_META_ZONE_SDK_INDEXER_CURSOR_KEY, TX_HASH_CELL_NAME, + DB_META_STALL_REASON_KEY, DB_META_TIP_CHECKPOINT_KEY, DB_META_ZONE_SDK_INDEXER_CURSOR_KEY, + TX_HASH_CELL_NAME, }, }; -#[derive(Debug, BorshSerialize, BorshDeserialize)] -pub struct LastObservedL1LibHeaderCell(pub [u8; 32]); - -impl SimpleStorableCell for LastObservedL1LibHeaderCell { - type KeyParams = (); - - const CELL_NAME: &'static str = DB_META_LAST_OBSERVED_L1_LIB_HEADER_ID_IN_DB_KEY; - const CF_NAME: &'static str = CF_META_NAME; -} - -impl SimpleReadableCell for LastObservedL1LibHeaderCell {} - -impl SimpleWritableCell for LastObservedL1LibHeaderCell { - fn value_constructor(&self) -> DbResult> { - borsh::to_vec(&self).map_err(|err| { - DbError::borsh_cast_message( - err, - Some("Failed to serialize last observed l1 header".to_owned()), - ) - }) - } -} - #[derive(BorshDeserialize)] pub struct BreakpointCellOwned(pub V03State); @@ -189,29 +166,42 @@ impl SimpleWritableCell for AccNumTxCell { } } -/// The L1 inscription slot of the tip block, written atomically with the tip. -#[derive(Debug, BorshSerialize, BorshDeserialize)] -pub struct TipSlotCell(pub u64); +/// The L1 inscription checkpoint of the tip block, written atomically with the tip. +#[derive(BorshDeserialize)] +pub struct TipCheckpointCellOwned(pub Vec); -impl SimpleStorableCell for TipSlotCell { +impl SimpleStorableCell for TipCheckpointCellOwned { type KeyParams = (); - const CELL_NAME: &'static str = DB_META_TIP_SLOT_KEY; + const CELL_NAME: &'static str = DB_META_TIP_CHECKPOINT_KEY; const CF_NAME: &'static str = CF_META_NAME; } -impl SimpleReadableCell for TipSlotCell {} +impl SimpleReadableCell for TipCheckpointCellOwned {} + +#[derive(BorshSerialize)] +pub struct TipCheckpointCellRef<'bytes>(pub &'bytes [u8]); + +impl SimpleStorableCell for TipCheckpointCellRef<'_> { + type KeyParams = (); -impl SimpleWritableCell for TipSlotCell { + const CELL_NAME: &'static str = DB_META_TIP_CHECKPOINT_KEY; + const CF_NAME: &'static str = CF_META_NAME; +} + +impl SimpleWritableCell for TipCheckpointCellRef<'_> { fn value_constructor(&self) -> DbResult> { borsh::to_vec(&self).map_err(|err| { - DbError::borsh_cast_message(err, Some("Failed to serialize tip slot".to_owned())) + DbError::borsh_cast_message( + err, + Some("Failed to serialize zone-sdk indexer cursor cell".to_owned()), + ) }) } } -/// Opaque bytes for the zone-sdk indexer cursor `Option<(MsgId, Slot)>`. -/// The caller serializes via `serde_json` (neither type derives borsh). +/// Opaque bytes for the zone-sdk indexer cursor `Option`. +/// The caller serializes via `serde_json` (type does not devive borsh). #[derive(BorshDeserialize)] pub struct ZoneSdkIndexerCursorCellOwned(pub Vec); diff --git a/lez/storage/src/indexer/mod.rs b/lez/storage/src/indexer/mod.rs index a859b5f23..64c2cea92 100644 --- a/lez/storage/src/indexer/mod.rs +++ b/lez/storage/src/indexer/mod.rs @@ -18,17 +18,14 @@ pub mod read_once; pub mod write_atomic; pub mod write_non_atomic; -/// Key base for storing metainformation about id of last observed L1 lib header in db. -pub const DB_META_LAST_OBSERVED_L1_LIB_HEADER_ID_IN_DB_KEY: &str = - "last_observed_l1_lib_header_in_db"; /// Key base for storing the zone-sdk indexer cursor (opaque bytes). pub const DB_META_ZONE_SDK_INDEXER_CURSOR_KEY: &str = "zone_sdk_indexer_cursor"; /// Key base for storing the persisted `Option` diagnostic record (opaque JSON bytes). pub const DB_META_STALL_REASON_KEY: &str = "stall_reason"; +/// Key base for storing the L1 inscription checkpoint of the tip block. +pub const DB_META_TIP_CHECKPOINT_KEY: &str = "tip_checkpoint"; /// Key base for storing the persisted cross-zone halt record (opaque JSON bytes). pub const DB_META_CROSS_ZONE_HALT_KEY: &str = "cross_zone_halt"; -/// Key base for storing the L1 inscription slot of the tip block. -pub const DB_META_TIP_SLOT_KEY: &str = "tip_slot"; /// Cell name for a breakpoint. pub const BREAKPOINT_CELL_NAME: &str = "breakpoint"; diff --git a/lez/storage/src/indexer/read_once.rs b/lez/storage/src/indexer/read_once.rs index 805aa7725..a8dca3df8 100644 --- a/lez/storage/src/indexer/read_once.rs +++ b/lez/storage/src/indexer/read_once.rs @@ -4,7 +4,7 @@ use crate::{ cells::shared_cells::{BlockCell, FirstBlockCell, FirstBlockSetCell, LastBlockCell}, indexer::indexer_cells::{ AccNumTxCell, BlockHashToBlockIdMapCell, BreakpointCellOwned, CrossZoneHaltCellOwned, - LastObservedL1LibHeaderCell, StallReasonCellOwned, TipSlotCell, TxHashToBlockIdMapCell, + StallReasonCellOwned, TipCheckpointCellOwned, TxHashToBlockIdMapCell, ZoneSdkIndexerCursorCellOwned, }, }; @@ -23,17 +23,12 @@ impl RocksDBIO { .map(|opt| opt.map(|cell| cell.0)) } - pub fn get_meta_last_observed_l1_lib_header_in_db(&self) -> DbResult> { - self.get_opt::(()) - .map(|opt| opt.map(|val| val.0)) - } - pub fn get_meta_is_first_block_set(&self) -> DbResult { Ok(self.get_opt::(())?.is_some()) } - pub fn get_meta_tip_slot_in_db(&self) -> DbResult> { - self.get_opt::(()) + pub fn get_meta_tip_checkpoint_in_db(&self) -> DbResult>> { + self.get_opt::(()) .map(|opt| opt.map(|cell| cell.0)) } diff --git a/lez/storage/src/indexer/tests.rs b/lez/storage/src/indexer/tests.rs index 148454efe..3fb0fc50f 100644 --- a/lez/storage/src/indexer/tests.rs +++ b/lez/storage/src/indexer/tests.rs @@ -1,9 +1,19 @@ +use borsh::{BorshDeserialize, BorshSerialize}; use common::test_utils::produce_dummy_block; use lee::{Account, AccountId, PublicKey}; use tempfile::tempdir; use super::*; +/// All the checkpoint data we care in DB. +/// +/// Not exactly the checkpoint, but we put bytes anyway, so will do. +#[derive(Debug, Clone, Copy, BorshSerialize, BorshDeserialize, PartialEq, Eq)] +struct TestCheckpoint { + l1_header: [u8; 32], + slot: u64, +} + fn genesis_block() -> Block { produce_dummy_block(1, None, vec![]) } @@ -47,6 +57,10 @@ fn initial_state() -> lee::V03State { .with_programs([programs::authenticated_transfer(), programs::clock()]) } +fn checkpoint_bytes(l1_header: [u8; 32], slot: u64) -> Vec { + borsh::to_vec(&TestCheckpoint { l1_header, slot }).unwrap() +} + #[test] fn start_db() { let initial_state = initial_state(); @@ -58,14 +72,14 @@ fn start_db() { let last_id = dbio.get_meta_last_block_id_in_db().unwrap(); let first_id = dbio.get_meta_first_block_id_in_db().unwrap(); let is_first_set = dbio.get_meta_is_first_block_set().unwrap(); - let last_observed_l1_header = dbio.get_meta_last_observed_l1_lib_header_in_db().unwrap(); + let last_tip_checkpoint = dbio.get_meta_tip_checkpoint_in_db().unwrap(); let last_block = dbio.get_block(1).unwrap(); let breakpoint = dbio.get_breakpoint(0).unwrap(); let final_state = dbio.final_state().unwrap(); assert_eq!(last_id, None); assert_eq!(first_id, None); - assert_eq!(last_observed_l1_header, None); + assert_eq!(last_tip_checkpoint, None); assert!(!is_first_set); assert!(last_block.is_none()); assert_eq!( @@ -87,8 +101,12 @@ fn one_block_insertion() { let dbio = RocksDBIO::open_or_create(temdir_path, &initial_state).unwrap(); let genesis_block = genesis_block(); - dbio.put_block(&genesis_block, [0; 32], 0, &initial_state) - .unwrap(); + dbio.put_block( + &genesis_block, + &checkpoint_bytes([0; 32], 0), + &initial_state, + ) + .unwrap(); let prev_hash = genesis_block.header.hash; let from = acc1(); @@ -99,14 +117,13 @@ fn one_block_insertion() { common::test_utils::create_transaction_native_token_transfer(from, 0, to, 1, &sign_key); let block = produce_dummy_block(2, Some(prev_hash), vec![transfer_tx]); - dbio.put_block(&block, [1; 32], 0, &initial_state).unwrap(); + dbio.put_block(&block, &checkpoint_bytes([1; 32], 0), &initial_state) + .unwrap(); let last_id = dbio.get_meta_last_block_id_in_db().unwrap().unwrap(); let first_id = dbio.get_meta_first_block_id_in_db().unwrap(); - let last_observed_l1_header = dbio - .get_meta_last_observed_l1_lib_header_in_db() - .unwrap() - .unwrap(); + let last_tip_checkpoint: TestCheckpoint = + borsh::from_slice(&dbio.get_meta_tip_checkpoint_in_db().unwrap().unwrap()).unwrap(); let is_first_set = dbio.get_meta_is_first_block_set().unwrap(); let last_block = dbio.get_block(last_id).unwrap().unwrap(); let breakpoint = dbio.get_breakpoint(0).unwrap(); @@ -114,7 +131,13 @@ fn one_block_insertion() { assert_eq!(last_id, 2); assert_eq!(first_id, Some(1)); - assert_eq!(last_observed_l1_header, [1; 32]); + assert_eq!( + last_tip_checkpoint, + TestCheckpoint { + l1_header: [1; 32], + slot: 0 + } + ); assert!(is_first_set); assert_eq!(last_block.header.hash, block.header.hash); assert_eq!( @@ -130,27 +153,44 @@ fn one_block_insertion() { } #[test] -fn put_block_records_tip_inscription_slot() { +fn put_block_records_tip_inscription_checkpoint() { let initial_state = initial_state(); let temp_dir = tempdir().unwrap(); let dbio = RocksDBIO::open_or_create(temp_dir.path(), &initial_state).unwrap(); - assert_eq!(dbio.get_meta_tip_slot_in_db().unwrap(), None); + assert_eq!(dbio.get_meta_tip_checkpoint_in_db().unwrap(), None); let genesis_block = genesis_block(); - dbio.put_block(&genesis_block, [0; 32], 1_000, &initial_state) - .unwrap(); - assert_eq!(dbio.get_meta_tip_slot_in_db().unwrap(), Some(1_000)); + dbio.put_block( + &genesis_block, + &checkpoint_bytes([0; 32], 1_000), + &initial_state, + ) + .unwrap(); + assert_eq!( + dbio.get_meta_tip_checkpoint_in_db().unwrap(), + Some(checkpoint_bytes([0; 32], 1_000)) + ); let block = produce_dummy_block(2, Some(genesis_block.header.hash), vec![]); - dbio.put_block(&block, [1; 32], 1_005, &initial_state) + dbio.put_block(&block, &checkpoint_bytes([1; 32], 1_005), &initial_state) .unwrap(); - assert_eq!(dbio.get_meta_tip_slot_in_db().unwrap(), Some(1_005)); + assert_eq!( + dbio.get_meta_tip_checkpoint_in_db().unwrap(), + Some(checkpoint_bytes([1; 32], 1_005)) + ); - // Re-inserting a block at/below the tip must not move the tip slot. - dbio.put_block(&genesis_block, [0; 32], 1_010, &initial_state) - .unwrap(); - assert_eq!(dbio.get_meta_tip_slot_in_db().unwrap(), Some(1_005)); + // Re-inserting a block at/below the tip must not move the tip checkpoint. + dbio.put_block( + &genesis_block, + &checkpoint_bytes([0; 32], 1_010), + &initial_state, + ) + .unwrap(); + assert_eq!( + dbio.get_meta_tip_checkpoint_in_db().unwrap(), + Some(checkpoint_bytes([1; 32], 1_005)) + ); } #[test] @@ -182,7 +222,8 @@ fn put_block_stores_breakpoint_in_same_batch() { ); let block = produce_dummy_block(i.into(), prev_hash, vec![transfer_tx]); - dbio.put_block(&block, [i; 32], 0, &initial_state).unwrap(); + dbio.put_block(&block, &checkpoint_bytes([i; 32], 0), &initial_state) + .unwrap(); } let bp1 = dbio.get_breakpoint(1).unwrap(); @@ -221,7 +262,8 @@ fn state_replay_falls_back_over_missing_breakpoints() { &sign_key, ); let block = produce_dummy_block(i, prev_hash, vec![transfer_tx]); - dbio.put_block(&block, [0; 32], 0, &initial_state).unwrap(); + dbio.put_block(&block, &checkpoint_bytes([0; 32], 0), &initial_state) + .unwrap(); } // Simulate a store whose boundary snapshot was lost (#605). @@ -256,7 +298,8 @@ fn simple_maps() { let control_hash1 = block.header.hash; - dbio.put_block(&block, [1; 32], 0, &initial_state).unwrap(); + dbio.put_block(&block, &checkpoint_bytes([1; 32], 0), &initial_state) + .unwrap(); let last_id = dbio.get_meta_last_block_id_in_db().unwrap().unwrap(); let last_block = dbio.get_block(last_id).unwrap().unwrap(); @@ -268,7 +311,8 @@ fn simple_maps() { let control_hash2 = block.header.hash; - dbio.put_block(&block, [2; 32], 0, &initial_state).unwrap(); + dbio.put_block(&block, &checkpoint_bytes([2; 32], 0), &initial_state) + .unwrap(); let last_id = dbio.get_meta_last_block_id_in_db().unwrap().unwrap(); let last_block = dbio.get_block(last_id).unwrap().unwrap(); @@ -280,7 +324,8 @@ fn simple_maps() { let control_tx_hash1 = transfer_tx.hash(); let block = produce_dummy_block(3, Some(prev_hash), vec![transfer_tx]); - dbio.put_block(&block, [3; 32], 0, &initial_state).unwrap(); + dbio.put_block(&block, &checkpoint_bytes([3; 32], 0), &initial_state) + .unwrap(); let last_id = dbio.get_meta_last_block_id_in_db().unwrap().unwrap(); let last_block = dbio.get_block(last_id).unwrap().unwrap(); @@ -292,7 +337,8 @@ fn simple_maps() { let control_tx_hash2 = transfer_tx.hash(); let block = produce_dummy_block(4, Some(prev_hash), vec![transfer_tx]); - dbio.put_block(&block, [4; 32], 0, &initial_state).unwrap(); + dbio.put_block(&block, &checkpoint_bytes([4; 32], 0), &initial_state) + .unwrap(); let control_block_id1 = dbio.get_block_id_by_hash(control_hash1.0).unwrap().unwrap(); let control_block_id2 = dbio.get_block_id_by_hash(control_hash2.0).unwrap().unwrap(); @@ -330,7 +376,8 @@ fn block_batch() { let block = produce_dummy_block(1, None, vec![transfer_tx]); block_res.push(block.clone()); - dbio.put_block(&block, [1; 32], 0, &initial_state).unwrap(); + dbio.put_block(&block, &checkpoint_bytes([1; 32], 0), &initial_state) + .unwrap(); let last_id = dbio.get_meta_last_block_id_in_db().unwrap().unwrap(); let last_block = dbio.get_block(last_id).unwrap().unwrap(); @@ -341,7 +388,8 @@ fn block_batch() { let block = produce_dummy_block(2, Some(prev_hash), vec![transfer_tx]); block_res.push(block.clone()); - dbio.put_block(&block, [2; 32], 0, &initial_state).unwrap(); + dbio.put_block(&block, &checkpoint_bytes([2; 32], 0), &initial_state) + .unwrap(); let last_id = dbio.get_meta_last_block_id_in_db().unwrap().unwrap(); let last_block = dbio.get_block(last_id).unwrap().unwrap(); @@ -352,7 +400,8 @@ fn block_batch() { let block = produce_dummy_block(3, Some(prev_hash), vec![transfer_tx]); block_res.push(block.clone()); - dbio.put_block(&block, [3; 32], 0, &initial_state).unwrap(); + dbio.put_block(&block, &checkpoint_bytes([3; 32], 0), &initial_state) + .unwrap(); let last_id = dbio.get_meta_last_block_id_in_db().unwrap().unwrap(); let last_block = dbio.get_block(last_id).unwrap().unwrap(); @@ -363,7 +412,8 @@ fn block_batch() { let block = produce_dummy_block(4, Some(prev_hash), vec![transfer_tx]); block_res.push(block.clone()); - dbio.put_block(&block, [4; 32], 0, &initial_state).unwrap(); + dbio.put_block(&block, &checkpoint_bytes([4; 32], 0), &initial_state) + .unwrap(); let block_hashes_mem: Vec<[u8; 32]> = block_res.into_iter().map(|bl| bl.header.hash.0).collect(); @@ -423,7 +473,8 @@ fn account_map() { let block = produce_dummy_block(1, None, vec![transfer_tx1, transfer_tx2]); - dbio.put_block(&block, [1; 32], 0, &initial_state).unwrap(); + dbio.put_block(&block, &checkpoint_bytes([1; 32], 0), &initial_state) + .unwrap(); let last_id = dbio.get_meta_last_block_id_in_db().unwrap().unwrap(); let last_block = dbio.get_block(last_id).unwrap().unwrap(); @@ -438,7 +489,8 @@ fn account_map() { let block = produce_dummy_block(2, Some(prev_hash), vec![transfer_tx1, transfer_tx2]); - dbio.put_block(&block, [2; 32], 0, &initial_state).unwrap(); + dbio.put_block(&block, &checkpoint_bytes([2; 32], 0), &initial_state) + .unwrap(); let last_id = dbio.get_meta_last_block_id_in_db().unwrap().unwrap(); let last_block = dbio.get_block(last_id).unwrap().unwrap(); @@ -453,7 +505,8 @@ fn account_map() { let block = produce_dummy_block(3, Some(prev_hash), vec![transfer_tx1, transfer_tx2]); - dbio.put_block(&block, [3; 32], 0, &initial_state).unwrap(); + dbio.put_block(&block, &checkpoint_bytes([3; 32], 0), &initial_state) + .unwrap(); let last_id = dbio.get_meta_last_block_id_in_db().unwrap().unwrap(); let last_block = dbio.get_block(last_id).unwrap().unwrap(); @@ -465,7 +518,8 @@ fn account_map() { let block = produce_dummy_block(4, Some(prev_hash), vec![transfer_tx]); - dbio.put_block(&block, [4; 32], 0, &initial_state).unwrap(); + dbio.put_block(&block, &checkpoint_bytes([4; 32], 0), &initial_state) + .unwrap(); let acc1_tx = dbio.get_acc_transactions(*acc1().value(), 0, 7).unwrap(); let acc1_tx_hashes: Vec<[u8; 32]> = acc1_tx.into_iter().map(|tx| tx.hash().0).collect(); diff --git a/lez/storage/src/indexer/write_atomic.rs b/lez/storage/src/indexer/write_atomic.rs index 729bcc025..5f8d5240f 100644 --- a/lez/storage/src/indexer/write_atomic.rs +++ b/lez/storage/src/indexer/write_atomic.rs @@ -7,8 +7,8 @@ use crate::{ DBIO as _, cells::shared_cells::{FirstBlockCell, FirstBlockSetCell, LastBlockCell}, indexer::indexer_cells::{ - AccNumTxCell, BlockHashToBlockIdMapCell, BreakpointCellRef, LastObservedL1LibHeaderCell, - TipSlotCell, TxHashToBlockIdMapCell, + AccNumTxCell, BlockHashToBlockIdMapCell, BreakpointCellRef, TipCheckpointCellRef, + TxHashToBlockIdMapCell, }, }; @@ -123,20 +123,12 @@ impl RocksDBIO { self.put_batch(&LastBlockCell(block_id), (), write_batch) } - pub fn put_meta_last_observed_l1_lib_header_in_db_batch( + pub fn put_meta_tip_checkpoint_in_db_batch( &self, - l1_lib_header: [u8; 32], + checkpoint_bytes: &[u8], write_batch: &mut WriteBatch, ) -> DbResult<()> { - self.put_batch(&LastObservedL1LibHeaderCell(l1_lib_header), (), write_batch) - } - - pub fn put_meta_tip_slot_in_db_batch( - &self, - l1_slot: u64, - write_batch: &mut WriteBatch, - ) -> DbResult<()> { - self.put_batch(&TipSlotCell(l1_slot), (), write_batch) + self.put_batch(&TipCheckpointCellRef(checkpoint_bytes), (), write_batch) } pub fn put_meta_is_first_block_set_batch(&self, write_batch: &mut WriteBatch) -> DbResult<()> { @@ -149,8 +141,7 @@ impl RocksDBIO { pub fn put_block( &self, block: &Block, - l1_lib_header: [u8; 32], - l1_slot: u64, + checkpoint_bytes: &[u8], post_state: &V03State, ) -> DbResult<()> { let cf_block = self.block_column(); @@ -169,8 +160,7 @@ impl RocksDBIO { if block.header.block_id > last_curr_block { self.put_meta_last_block_in_db_batch(block.header.block_id, &mut write_batch)?; - self.put_meta_last_observed_l1_lib_header_in_db_batch(l1_lib_header, &mut write_batch)?; - self.put_meta_tip_slot_in_db_batch(l1_slot, &mut write_batch)?; + self.put_meta_tip_checkpoint_in_db_batch(checkpoint_bytes, &mut write_batch)?; } if last_curr_block == 0 { self.put_meta_first_block_in_db_batch(block, &mut write_batch)?; diff --git a/lez/storage/src/indexer/write_non_atomic.rs b/lez/storage/src/indexer/write_non_atomic.rs index 519dd3287..54aaa3013 100644 --- a/lez/storage/src/indexer/write_non_atomic.rs +++ b/lez/storage/src/indexer/write_non_atomic.rs @@ -5,8 +5,7 @@ use crate::{ DBIO as _, cells::shared_cells::{FirstBlockSetCell, LastBlockCell}, indexer::indexer_cells::{ - BreakpointCellRef, CrossZoneHaltCellRef, LastObservedL1LibHeaderCell, StallReasonCellRef, - ZoneSdkIndexerCursorCellRef, + BreakpointCellRef, CrossZoneHaltCellRef, StallReasonCellRef, ZoneSdkIndexerCursorCellRef, }, }; @@ -18,13 +17,6 @@ impl RocksDBIO { self.put(&LastBlockCell(block_id), ()) } - pub fn put_meta_last_observed_l1_lib_header_in_db( - &self, - l1_lib_header: [u8; 32], - ) -> DbResult<()> { - self.put(&LastObservedL1LibHeaderCell(l1_lib_header), ()) - } - pub fn put_meta_is_first_block_set(&self) -> DbResult<()> { self.put(&FirstBlockSetCell(true), ()) } diff --git a/lez/storage/src/sequencer/mod.rs b/lez/storage/src/sequencer/mod.rs index 58c338c42..66b2b9eb1 100644 --- a/lez/storage/src/sequencer/mod.rs +++ b/lez/storage/src/sequencer/mod.rs @@ -31,7 +31,8 @@ use crate::{ PendingCrossZoneDispatchCountCell, PendingCrossZoneDispatchRecord, PendingDepositEventRecord, PendingDepositEventsCellOwned, PendingDepositEventsCellRef, PublishedHighWaterCell, UnseenWithdrawCountCell, WithdrawalReconciliationKey, - ZoneAnchorCell, ZoneAnchorRecord, ZoneSdkCheckpointCellOwned, ZoneSdkCheckpointCellRef, + ZoneAnchorCellOwned, ZoneAnchorCellRef, ZoneSdkCheckpointCellOwned, + ZoneSdkCheckpointCellRef, }, }; @@ -200,7 +201,7 @@ pub struct StoreUpdate<'update> { pub new_withdraw_intents: &'update [WithdrawalReconciliationKey], /// Advance the channel-read anchor. - pub zone_anchor: Option<&'update ZoneAnchorRecord>, + pub zone_anchor: Option<&'update [u8]>, } impl<'update> StoreUpdate<'update> { @@ -566,12 +567,12 @@ impl RocksDBIO { self.put(&PublishedHighWaterCell(block_id), ()) } - pub fn get_zone_anchor(&self) -> DbResult> { - Ok(self.get_opt::(())?.map(|cell| cell.0)) + pub fn get_zone_anchor_bytes(&self) -> DbResult>> { + Ok(self.get_opt::(())?.map(|cell| cell.0)) } - pub fn put_zone_anchor(&self, anchor: &ZoneAnchorRecord) -> DbResult<()> { - self.put(&ZoneAnchorCell(*anchor), ()) + pub fn put_zone_anchor_bytes(&self, bytes: &[u8]) -> DbResult<()> { + self.put(&ZoneAnchorCellRef(bytes), ()) } pub fn get_pending_deposit_events(&self) -> DbResult> { @@ -1406,7 +1407,7 @@ impl RocksDBIO { self.put_batch(&ZoneSdkCheckpointCellRef(bytes), (), &mut batch)?; } if let Some(anchor) = zone_anchor { - self.put_batch(&ZoneAnchorCell(*anchor), (), &mut batch)?; + self.put_batch(&ZoneAnchorCellRef(anchor), (), &mut batch)?; } // Every block payload this update writes, keyed by id so a block that diff --git a/lez/storage/src/sequencer/sequencer_cells.rs b/lez/storage/src/sequencer/sequencer_cells.rs index 927bdde3f..5cc52375a 100644 --- a/lez/storage/src/sequencer/sequencer_cells.rs +++ b/lez/storage/src/sequencer/sequencer_cells.rs @@ -229,35 +229,35 @@ impl SimpleWritableCell for ZoneSdkCheckpointCellRef<'_> { } } -/// The last channel block read back and verified from Bedrock. -/// -/// Holds its L1 inscription `slot` plus the block's `id`/`hash`, and serves as -/// both the anchor for the startup consistency check and the resume point for -/// reconstruction. `slot` is stored as a raw `u64` because the zone-sdk `Slot` -/// does not derive borsh; the caller converts to/from `Slot`. -#[derive(Debug, Clone, Copy, BorshSerialize, BorshDeserialize)] -pub struct ZoneAnchorRecord { - pub slot: u64, - pub block_id: u64, - pub hash: HashType, +#[derive(BorshDeserialize)] +pub struct ZoneAnchorCellOwned(pub Vec); + +impl SimpleStorableCell for ZoneAnchorCellOwned { + type KeyParams = (); + + const CELL_NAME: &'static str = DB_META_ZONE_CURSOR_KEY; + const CF_NAME: &'static str = CF_META_NAME; } -#[derive(Debug, BorshSerialize, BorshDeserialize)] -pub struct ZoneAnchorCell(pub ZoneAnchorRecord); +impl SimpleReadableCell for ZoneAnchorCellOwned {} + +#[derive(BorshSerialize)] +pub struct ZoneAnchorCellRef<'bytes>(pub &'bytes [u8]); -impl SimpleStorableCell for ZoneAnchorCell { +impl SimpleStorableCell for ZoneAnchorCellRef<'_> { type KeyParams = (); const CELL_NAME: &'static str = DB_META_ZONE_CURSOR_KEY; const CF_NAME: &'static str = CF_META_NAME; } -impl SimpleReadableCell for ZoneAnchorCell {} - -impl SimpleWritableCell for ZoneAnchorCell { +impl SimpleWritableCell for ZoneAnchorCellRef<'_> { fn value_constructor(&self) -> DbResult> { borsh::to_vec(&self).map_err(|err| { - DbError::borsh_cast_message(err, Some("Failed to serialize zone cursor".to_owned())) + DbError::borsh_cast_message( + err, + Some("Failed to serialize zone anchor cell".to_owned()), + ) }) } } diff --git a/lez/wallet-ffi/wallet_ffi.h b/lez/wallet-ffi/wallet_ffi.h index 0245b4144..dc6d37b98 100644 --- a/lez/wallet-ffi/wallet_ffi.h +++ b/lez/wallet-ffi/wallet_ffi.h @@ -24,7 +24,7 @@ #ifndef WALLET_FFI_H #define WALLET_FFI_H -/* Generated with cbindgen:0.29.3 */ +/* Generated with cbindgen:0.29.4 */ #include #include diff --git a/test_fixtures/fixtures/prebuilt_sequencer_db.dump b/test_fixtures/fixtures/prebuilt_sequencer_db.dump index 95f509e20..a30512f7d 100644 Binary files a/test_fixtures/fixtures/prebuilt_sequencer_db.dump and b/test_fixtures/fixtures/prebuilt_sequencer_db.dump differ diff --git a/test_fixtures/src/setup.rs b/test_fixtures/src/setup.rs index a128fd3ce..e55a8cd23 100644 --- a/test_fixtures/src/setup.rs +++ b/test_fixtures/src/setup.rs @@ -122,6 +122,8 @@ impl SequencerSetup { } async fn setup_owned(self, home: PathBuf) -> Result { + log::info!("======================================== Sequencer setup have config {self:#?}"); + let Self { partial, bedrock_addr,