From 2ea223055d5093a24c21d2f006b3bce3f14c8f18 Mon Sep 17 00:00:00 2001 From: Michael Taylor Date: Wed, 26 Aug 2026 07:42:42 -0700 Subject: [PATCH 1/6] chore(deps): begin chia-sdk-* 0.34 -> 0.36.0 ceiling adoption Refs https://github.com/DIG-Network/dig_ecosystem/issues/3161 Co-Authored-By: Claude From b0cd8fe8ca60eface457307514e9cf6d15f3f94d Mon Sep 17 00:00:00 2001 From: Michael Taylor Date: Wed, 26 Aug 2026 07:51:51 -0700 Subject: [PATCH 2/6] chore(deps)!: adopt the chia-wallet-sdk 0.36.0 ceiling across chia-sdk-* Published 0.3.1 shipped INTERNALLY SPLIT: chia-protocol/chia-puzzle-types/ clvm-traits/clvm-utils at ^0.36.1 beside chia-sdk-driver/chia-sdk-test/ chia-sdk-types at ^0.34. The split lives inside the published version, so no consumer could escape it by bumping -- an ecosystem blocker. Move the chia-sdk-* family to its ceiling (0.36.0) and pin chia-puzzles and clvmr to theirs (0.20.3, 0.16.2). The ceiling is chia-wallet-sdk 0.36.0's own dependency set, NOT the newest on crates.io: the primitives publish at 0.48 but the SDK cannot reach them, so 0.36.1 primitives beside 0.36.0 chia-sdk-* is the coherent maximum. The primitives were already at their ceiling and are left alone -- raising them would re-split the crate, not modernise it. Dependency-only: no source file changes. Cargo.lock collapses the chia-sdk-* family to a single 0.36.0 line and drops the chia-sha2 0.34.0 line the split had kept alive. BREAKING CHANGE: chia-sdk-driver/chia-sdk-types are semver-incompatible across 0.34 -> 0.36, so a consumer of the lineage-walk feature must move in step. Closes https://github.com/DIG-Network/dig-chainsource-interface/issues/5 Refs https://github.com/DIG-Network/dig_ecosystem/issues/3161 Co-Authored-By: Claude --- Cargo.lock | 701 ++++++++++++++++++++++++++++++++++++++++++++++++++--- Cargo.toml | 23 +- 2 files changed, 685 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 424e661..d4b41de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,6 +29,12 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.5.1" @@ -41,6 +47,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64ct" version = "1.8.3" @@ -140,6 +152,12 @@ version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" + [[package]] name = "cc" version = "1.3.0" @@ -179,11 +197,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f02cbfd038d9050d45edbe8f38e09391c73479c0cca5b37925daf48c4d4fcd4" dependencies = [ "blst", + "chia-serde", "chia-sha2 0.36.1", "chia-traits 0.36.1", "hex", "hkdf", "linked-hash-map", + "serde", "sha2 0.10.9", "thiserror 1.0.69", ] @@ -232,6 +252,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "150d1f8a5978fe58bce49af89ef2abfd292dad324fcbbced5972de78772f6e9c" dependencies = [ "chia-bls 0.36.1", + "chia-serde", "chia-sha2 0.36.1", "chia-traits 0.36.1", "chia_streamable_macro 0.36.1", @@ -239,6 +260,8 @@ dependencies = [ "clvm-utils", "clvmr", "hex", + "serde", + "serde_arrays", ] [[package]] @@ -268,11 +291,25 @@ dependencies = [ "hex-literal", ] +[[package]] +name = "chia-sdk-coinset" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f506b96f9fda1038315a3aa6a27ee57fc652aa118e21977ac35b24f6fe8d0a3" +dependencies = [ + "chia-protocol", + "hex", + "hex-literal", + "reqwest", + "serde", + "serde_json", +] + [[package]] name = "chia-sdk-derive" -version = "0.34.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e9e366cbc576221da519a08544b546cbf0441a4d3e8bbd8e69f3a06480a6af4" +checksum = "6582e68e7a3577a2d68f49ce996381c25b1c3e7ed8987f892640ae1b2f97a512" dependencies = [ "convert_case 0.8.0", "quote", @@ -281,9 +318,9 @@ dependencies = [ [[package]] name = "chia-sdk-driver" -version = "0.34.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2677cf560410db034c8bb5de1e07dec2021b12fd986981390654e260a2b856" +checksum = "33d22cc417877a290eff196fe851cfc1175a5432166f8d9bedeb9f55e010bc76" dependencies = [ "bigdecimal", "bip39", @@ -308,14 +345,15 @@ dependencies = [ "num-bigint", "rand 0.9.5", "rand_chacha 0.9.0", + "serde", "thiserror 2.0.19", ] [[package]] name = "chia-sdk-signer" -version = "0.34.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83f8553345d14f9eb89f07df0d3854162d818d21acf27140997ae77256dc7883" +checksum = "512d32dc79e27a7bd1cbd7f9fc899dcd9cbac0fbabe5ad956842097ab440ef33" dependencies = [ "chia-bls 0.36.1", "chia-consensus", @@ -333,9 +371,9 @@ dependencies = [ [[package]] name = "chia-sdk-test" -version = "0.34.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de32a1cc7124f151401d553413d45b88b607dbfa69cf1721c7daab75b717d1a2" +checksum = "117394d011b2424785f2a3405241302637ef57946e48541ebd03dc81f2360e89" dependencies = [ "anyhow", "bip39", @@ -343,6 +381,7 @@ dependencies = [ "chia-consensus", "chia-protocol", "chia-puzzle-types", + "chia-sdk-coinset", "chia-sdk-signer", "chia-sdk-types", "chia-secp", @@ -352,6 +391,7 @@ dependencies = [ "clvm-utils", "clvmr", "hex", + "hex-literal", "indexmap", "prettytable-rs", "rand 0.9.5", @@ -361,9 +401,9 @@ dependencies = [ [[package]] name = "chia-sdk-types" -version = "0.34.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0891df37e7b053682b7bec452321d0b2205c20de8792e96470d571390cfd5b48" +checksum = "3a4c4fb7e3ee75601e583efae625cd65e3bbcacda5be5d341b89c6f05a4b1702" dependencies = [ "chia-bls 0.36.1", "chia-consensus", @@ -381,6 +421,7 @@ dependencies = [ "rue-compiler", "rue-lir", "rue-options", + "serde", "thiserror 2.0.19", ] @@ -396,6 +437,16 @@ dependencies = [ "p256", ] +[[package]] +name = "chia-serde" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f776d8555d463e6915e02598bb2be2123c57f6eaeb5c8078565957f062b92d1d" +dependencies = [ + "hex", + "serde", +] + [[package]] name = "chia-sha2" version = "0.28.2" @@ -755,7 +806,7 @@ dependencies = [ [[package]] name = "dig-chainsource-interface" -version = "0.3.1" +version = "0.4.0" dependencies = [ "anyhow", "chia-bls 0.36.1", @@ -817,6 +868,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "displaydoc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.0", +] + [[package]] name = "do-notation" version = "0.1.3" @@ -922,12 +984,30 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + [[package]] name = "funty" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "futures-channel" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae" +dependencies = [ + "futures-core", +] + [[package]] name = "futures-core" version = "0.3.33" @@ -1109,6 +1189,45 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "http" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + [[package]] name = "hybrid-array" version = "0.4.14" @@ -1118,12 +1237,178 @@ dependencies = [ "typenum", ] +[[package]] +name = "hyper" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "icu_collections" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" + +[[package]] +name = "icu_properties" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" + +[[package]] +name = "icu_provider" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + [[package]] name = "id-arena" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "include_dir" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "indexmap" version = "2.14.0" @@ -1143,6 +1428,12 @@ dependencies = [ "rustversion", ] +[[package]] +name = "ipnet" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a756c3fac73139e83f14c2d742155dd2b78d3ee56597b419a0579b7bdd6dd78" + [[package]] name = "is-terminal" version = "0.4.17" @@ -1242,6 +1533,12 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" +[[package]] +name = "litemap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" + [[package]] name = "log" version = "0.4.33" @@ -1254,6 +1551,17 @@ version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" +[[package]] +name = "mio" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + [[package]] name = "num" version = "0.4.3" @@ -1381,6 +1689,12 @@ dependencies = [ "base64ct", ] +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + [[package]] name = "pin-project-lite" version = "0.2.17" @@ -1397,6 +1711,15 @@ dependencies = [ "spki", ] +[[package]] +name = "potential_utf" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" +dependencies = [ + "zerovec", +] + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -1599,6 +1922,38 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64", + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -1652,9 +2007,9 @@ dependencies = [ [[package]] name = "rue-ast" -version = "0.6.0" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8feffcdd1f81db8d83980714cdd15d53608f7cc49e4d4a1c52d0fe1d523c4b" +checksum = "82e99e24bfbaa8fe116b23d3fa1df09e2f59982e654e04430f8fad0d348271fa" dependencies = [ "paste", "rue-parser", @@ -1662,13 +2017,14 @@ dependencies = [ [[package]] name = "rue-compiler" -version = "0.6.0" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b58c388afe6e7fb78e63f43b455c57b6f788f1e2b65ae895e9ff38039ab2fdc" +checksum = "59f127828ed5bdd04dee995b5028f3ae291394850e66856bb6998198c51c4514" dependencies = [ "clvmr", "hex", "id-arena", + "include_dir", "indexmap", "log", "num-bigint", @@ -1687,19 +2043,18 @@ dependencies = [ [[package]] name = "rue-diagnostic" -version = "0.6.0" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cccb3041f21c77e80ea8fdb03e7214b91195d939f3146f054e27020ea1a9" +checksum = "d25461b6850121106735e1abe334ecf2bf56e27244284d46ef5dfbc0e4bc2894" dependencies = [ - "derive_more", "thiserror 2.0.19", ] [[package]] name = "rue-hir" -version = "0.6.0" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2d73674bfcd164e453dbeabfa99cb952827abf7bc0540ed5bf6d2ccea97d06a" +checksum = "cd0cc66defc213a291efd185f0ff18f703abec2850c931a459ce187ee667e1fd" dependencies = [ "derive_more", "hex", @@ -1715,15 +2070,15 @@ dependencies = [ [[package]] name = "rue-lexer" -version = "0.6.0" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68345f23ba80d548d4a671de14e455de74ae58fccfa436db105b35308a1780ed" +checksum = "579df9994fcc6485832d6a19f77309f38d12cf48bb73b7a2b99eb4ae094aaadf" [[package]] name = "rue-lir" -version = "0.6.0" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099f3c3d6b432bb94cf8876b7f71b650d6887ae9193e8063c529feca37276b6f" +checksum = "c3ba00e6908f8baf1de08b41f11213a1bc0ef4dfd75f47ebca341665b1d1f5b7" dependencies = [ "chialisp", "clvm-traits 0.28.1", @@ -1739,9 +2094,9 @@ dependencies = [ [[package]] name = "rue-options" -version = "0.6.0" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f94c541b1397b7fbc4aaba36440c0bc11ddb703b024a424dd2fe193ec413b7" +checksum = "a6c9855c49ee3f3f248004bfb2daf166ca0648a46820f95255fedb4e815b269d" dependencies = [ "serde", "thiserror 2.0.19", @@ -1750,9 +2105,9 @@ dependencies = [ [[package]] name = "rue-parser" -version = "0.6.0" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d23577d98f535c02d2898e0a0e9cdf04b82d1ea91b15cd31e66141bce73c4c5" +checksum = "2eeffa2e32037202a8fb8a4361f06bf01dd0a7d7ace092dfab3ff1aa5f2cd42f" dependencies = [ "derive_more", "indexmap", @@ -1766,9 +2121,9 @@ dependencies = [ [[package]] name = "rue-types" -version = "0.6.0" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a6dc5f584d1ff7cf562737aa990d746def396ca4211c8f56c2d28d6dc00718b" +checksum = "0766e7089d3b5e41cebb17bee53055479adee1925207e4c1a5dea36a2bf29d06" dependencies = [ "clvmr", "derive_more", @@ -1851,6 +2206,15 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde_arrays" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94a16b99c5ea4fe3daccd14853ad260ec00ea043b2708d1fd1da3106dcd8d9df" +dependencies = [ + "serde", +] + [[package]] name = "serde_core" version = "1.0.229" @@ -1893,6 +2257,18 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sha1" version = "0.10.7" @@ -1958,6 +2334,22 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "socket2" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "spki" version = "0.7.3" @@ -1968,6 +2360,12 @@ dependencies = [ "der", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + [[package]] name = "subtle" version = "2.6.1" @@ -1996,6 +2394,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "tap" version = "1.0.1" @@ -2087,6 +2505,16 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "tinystr" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.12.0" @@ -2102,6 +2530,19 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" +dependencies = [ + "libc", + "mio", + "pin-project-lite", + "socket2", + "windows-sys", +] + [[package]] name = "toml" version = "0.9.12+spec-1.1.0" @@ -2179,6 +2620,76 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "url", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "typenum" version = "1.20.1" @@ -2218,12 +2729,39 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -2254,6 +2792,16 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b7777d5cc23d0e91404e53ce2d5e8ec7acae3026b16233dba62cd3246457950" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.127" @@ -2286,6 +2834,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "web-sys" +version = "0.3.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c435338968042f4f59a557f690a253676d47ce13ceb55d70100e7facf6620a30" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2353,6 +2911,12 @@ version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" +[[package]] +name = "writeable" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" + [[package]] name = "wyz" version = "0.5.1" @@ -2373,6 +2937,29 @@ dependencies = [ "hashlink", ] +[[package]] +name = "yoke" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.8.54" @@ -2393,6 +2980,27 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure", +] + [[package]] name = "zeroize" version = "1.9.0" @@ -2413,6 +3021,39 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "zerotrie" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.0", +] + [[package]] name = "zmij" version = "1.0.23" diff --git a/Cargo.toml b/Cargo.toml index b3d2ceb..b96b9e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ # aggregating canonical source). See SPEC.md for the normative contract. [package] name = "dig-chainsource-interface" -version = "0.3.1" +version = "0.4.0" edition = "2021" rust-version = "1.75.0" license = "Apache-2.0 OR MIT" @@ -25,16 +25,21 @@ thiserror = "2" # --- `lineage-walk` only (see [features]) ------------------------------------------------------ # The canonical launcher -> tip singleton walk DERIVES each successor by running the parent's inner # puzzle, so it needs a CLVM evaluator and the vetted singleton layer/puzzle types. Every version is -# pinned to the same coherent chia-* set the rest of the DIG on-chain line rides (chia-protocol -# 0.36 / chia-wallet-sdk 0.34); the SDK's own SingletonLayer is reused rather than re-implemented so -# the walk cannot byte-drift from the puzzle it authenticates against. +# pinned to the same coherent chia-* set the rest of the DIG on-chain line rides; the SDK's own +# SingletonLayer is reused rather than re-implemented so the walk cannot byte-drift from the puzzle +# it authenticates against. +# +# The ceiling is chia-wallet-sdk 0.36.0 and the versions below are ITS dependency set, NOT the +# newest on crates.io: the primitives publish at 0.48 but the SDK cannot reach them, so 0.36.1 +# primitives beside 0.36.0 `chia-sdk-*` is the coherent maximum. Raising either family past its +# own ceiling re-splits this crate rather than modernising it. chia-puzzle-types = { version = "0.36.1", optional = true } -chia-puzzles = { version = "0.20", optional = true } -chia-sdk-driver = { version = "0.34", optional = true } -chia-sdk-types = { version = "0.34", optional = true } +chia-puzzles = { version = "0.20.3", optional = true } +chia-sdk-driver = { version = "0.36.0", optional = true } +chia-sdk-types = { version = "0.36.0", optional = true } clvm-traits = { version = "0.36.1", optional = true } clvm-utils = { version = "0.36.1", optional = true } -clvmr = { version = "0.16", optional = true } +clvmr = { version = "0.16.2", optional = true } [features] default = [] @@ -58,6 +63,6 @@ hex = "0.4" # The in-process Chia Simulator: the lineage-walk tests authenticate against REAL singleton spends # (launcher, eve, recreation, melt) rather than hand-built fixtures, so the adversarial cases are # genuine chain data. -chia-sdk-test = "0.34" +chia-sdk-test = "0.36.0" chia-bls = "0.36.1" anyhow = "1" From abd6ad1fea8d4a6b215f50504bf5701d7212a7fa Mon Sep 17 00:00:00 2001 From: Michael Taylor Date: Wed, 26 Aug 2026 07:55:08 -0700 Subject: [PATCH 3/6] docs(spec): state the lineage-walk dependency set and its 0.36.0 ceiling SPEC.md claimed the crate 'does not depend on chia-puzzle-types, chia-puzzles', which stopped being true when the non-default lineage-walk feature was added. Record the real shape: the default set is still chia-protocol + thiserror only, and lineage-walk adds the CLVM evaluator and singleton puzzle types pinned to the chia-wallet-sdk 0.36.0 ceiling. Refs https://github.com/DIG-Network/dig_ecosystem/issues/3161 Co-Authored-By: Claude --- SPEC.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/SPEC.md b/SPEC.md index 9deaa08..bc3d92e 100644 --- a/SPEC.md +++ b/SPEC.md @@ -13,9 +13,15 @@ typed query/result/error shapes that cross it. It is a pure **leaf**: - **No I/O, no network, no keys, no filesystem.** The crate performs zero side effects. - **Reads only.** There is NO broadcast/push/submit/spend method anywhere in the crate, by design. Value-moving paths live entirely outside it. -- **No DIG-crate dependencies.** Runtime dependencies are `chia-protocol` and `thiserror` ONLY. - It does not depend on `chia-wallet-sdk`, `chia-puzzle-types`, `chia-puzzles`, `async-trait`, or any - DIG crate. This keeps it the bottom of the crate hierarchy (level 00) and cleanly wasm-buildable. +- **No DIG-crate dependencies.** In the DEFAULT feature set, runtime dependencies are `chia-protocol` + and `thiserror` ONLY. It depends on no DIG crate and no `async-trait` in any configuration. This + keeps it the bottom of the crate hierarchy (level 00) and cleanly wasm-buildable. + The non-default `lineage-walk` feature (§7) additionally pulls a CLVM evaluator and the vetted + singleton puzzle types — `chia-puzzle-types`, `chia-puzzles`, `chia-sdk-driver`, `chia-sdk-types`, + `clvm-traits`, `clvm-utils`, `clvmr`. A consumer that only needs the trait does not pay for them. + Every `chia-*` version is the **chia-wallet-sdk 0.36.0 ceiling**, never the newest on crates.io: + the primitives publish at 0.48 but the SDK cannot reach them, so `0.36.1` primitives beside + `0.36.0` `chia-sdk-*` is the coherent maximum. Mixing the two lines re-splits the crate. - **Object-safe and synchronous.** `Box>` MUST compile. ## 2. The `ChainSource` trait — per-method contract From 6d6bf425f11933e2855e8c2a0d255d8705b4cae7 Mon Sep 17 00:00:00 2001 From: Michael Taylor Date: Wed, 26 Aug 2026 07:55:37 -0700 Subject: [PATCH 4/6] docs(spec): correct the lineage-walk section cross-reference to 4a Co-Authored-By: Claude --- SPEC.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SPEC.md b/SPEC.md index bc3d92e..b5d91e8 100644 --- a/SPEC.md +++ b/SPEC.md @@ -16,7 +16,7 @@ typed query/result/error shapes that cross it. It is a pure **leaf**: - **No DIG-crate dependencies.** In the DEFAULT feature set, runtime dependencies are `chia-protocol` and `thiserror` ONLY. It depends on no DIG crate and no `async-trait` in any configuration. This keeps it the bottom of the crate hierarchy (level 00) and cleanly wasm-buildable. - The non-default `lineage-walk` feature (§7) additionally pulls a CLVM evaluator and the vetted + The non-default `lineage-walk` feature (§4a) additionally pulls a CLVM evaluator and the vetted singleton puzzle types — `chia-puzzle-types`, `chia-puzzles`, `chia-sdk-driver`, `chia-sdk-types`, `clvm-traits`, `clvm-utils`, `clvmr`. A consumer that only needs the trait does not pay for them. Every `chia-*` version is the **chia-wallet-sdk 0.36.0 ceiling**, never the newest on crates.io: From ec28f69b1b8ef018aef5f901b4c3ecb9be87af1e Mon Sep 17 00:00:00 2001 From: Michael Taylor Date: Wed, 26 Aug 2026 09:14:16 -0700 Subject: [PATCH 5/6] fix(deps): drop to 0.3.2 and guard chia family coherence mechanically The chia-sdk-* uplift is not semver-breaking. Every `chia-sdk-*`, `clvm*` and `chia-puzzle*` import is confined to src/walk.rs and no type from any of them crosses a public signature: `LineageWalkError` carries only `E`/`String`/`Bytes32`/`usize`/`Duration`, and the walk functions take and return `Bytes32`/`SingletonLineage`/`WalkBounds`. The one chia crate that IS public, `chia-protocol`, is unchanged at 0.36.1 from origin/main. So no consumer can observe the bump, and nine consumers pinning "0.3" must not be forced to edit manifests for a change that cannot reach them. Add tests/manifest_chia_coherence.rs, the regression guard #5 lacked. The defect was manifest coherence, which no behavioural test can see: both halves of a split run correctly in isolation. The guard asserts per-FAMILY MAJOR.MINOR agreement rather than global equality, because the ecosystem ceiling is deliberately non-uniform (chia-sdk-* 0.36.0, primitives 0.36.1, chia-puzzles 0.20.3, clvmr 0.16.2). It also pins the exact declared set, so a dependency added on a foreign line or silently dropped fails the suite. Co-Authored-By: Claude --- Cargo.lock | 2 +- Cargo.toml | 9 +- SPEC.md | 2 +- tests/manifest_chia_coherence.rs | 205 +++++++++++++++++++++++++++++++ 4 files changed, 215 insertions(+), 3 deletions(-) create mode 100644 tests/manifest_chia_coherence.rs diff --git a/Cargo.lock b/Cargo.lock index d4b41de..42baab2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -806,7 +806,7 @@ dependencies = [ [[package]] name = "dig-chainsource-interface" -version = "0.4.0" +version = "0.3.2" dependencies = [ "anyhow", "chia-bls 0.36.1", diff --git a/Cargo.toml b/Cargo.toml index b96b9e5..fe1d176 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,14 @@ # aggregating canonical source). See SPEC.md for the normative contract. [package] name = "dig-chainsource-interface" -version = "0.4.0" +# PATCH, not major. The chia-sdk-* uplift below is INTERNAL: every `chia-sdk-*`, `clvm*` and +# `chia-puzzle*` import is confined to `src/walk.rs`, and no type from any of them crosses a public +# signature — `LineageWalkError` carries only `E`/`String`/`Bytes32`/`usize`/`Duration`, and the +# walk functions take and return `Bytes32`/`SingletonLineage`/`WalkBounds`. The one chia crate that +# IS on the public surface, `chia-protocol`, is unchanged at 0.36.1. So no consumer — including the +# `lineage-walk` ones — can observe this bump, and nine consumers pinning "0.3" must not be forced +# to edit a manifest for a change that cannot reach them. +version = "0.3.2" edition = "2021" rust-version = "1.75.0" license = "Apache-2.0 OR MIT" diff --git a/SPEC.md b/SPEC.md index b5d91e8..e9d9223 100644 --- a/SPEC.md +++ b/SPEC.md @@ -1,4 +1,4 @@ -# dig-chainsource-interface — normative specification (v0.4.0) +# dig-chainsource-interface — normative specification (v0.3.2) This is the authoritative contract for the DIG Network canonical `ChainSource` interface. An independent reimplementation of this crate, of a provider, or of a consumer MUST conform to this diff --git a/tests/manifest_chia_coherence.rs b/tests/manifest_chia_coherence.rs new file mode 100644 index 0000000..cfe03ad --- /dev/null +++ b/tests/manifest_chia_coherence.rs @@ -0,0 +1,205 @@ +//! The regression guard for #5: this crate MUST NEVER again declare two different minor lines of +//! the same `chia-*` family. +//! +//! ## The defect this exists to catch +//! +//! Published 0.3.1 shipped INTERNALLY SPLIT: `chia-bls`/`chia-protocol`/`chia-puzzle-types`/ +//! `chia-traits` declared at `^0.36.1` beside `chia-sdk-driver`/`chia-sdk-test`/`chia-sdk-types` at +//! `^0.34`. Two lines of the same family in one crate compile only while every consumer happens to +//! be stale in the matching way; the moment one is not, the crate exposes two incompatible copies +//! of the same types. Nothing mechanically prevented it, and no *behavioural* test can: both halves +//! run correctly in isolation, so the split is invisible to every test of what the code DOES. +//! +//! The defect was **manifest coherence**, and manifest coherence is mechanically assertable. That +//! is what these tests assert. +//! +//! ## Why the manifest, and not `Cargo.lock` +//! +//! #5 is about the versions this crate DECLARES. The resolved lock legitimately contains older +//! chia lines we neither choose nor control — `clvmr` vendors `chia-sha2 0.34.0` and `chia-bls +//! 0.28.2` internally, and `chialisp` (via `rue-lir`) pulls `chia-bls 0.42.1`. A lock-based +//! assertion would therefore have to carve those out by name and would go red every time an +//! upstream evaluator re-vendored something, which is noise rather than signal. The manifest is the +//! surface this crate owns, so it is the surface the guard pins. +//! +//! ## Why per-FAMILY, and not "all chia crates are equal" +//! +//! The ecosystem ceiling is deliberately NOT uniform, so a test asserting one global version would +//! be wrong on green code: `chia-sdk-*` tops out at 0.36.0 while the primitives publish 0.36.1, and +//! `chia-puzzles` (0.20.x) and `clvmr` (0.16.x) have never shared a version line with either. What +//! must agree is the `MAJOR.MINOR` **line** within a family — which is exactly the granularity the +//! 0.34-vs-0.36 defect violated, and exactly the granularity the legitimate 0.36.0-vs-0.36.1 patch +//! spread does not. + +use std::collections::BTreeSet; +use std::fs; + +/// A declared dependency: its crate name and the version requirement in the manifest. +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] +struct Declared { + name: String, + version: String, +} + +impl Declared { + /// The `MAJOR.MINOR` line this requirement sits on — the granularity a family must agree at. + fn line(&self) -> String { + self.version + .split('.') + .take(2) + .collect::>() + .join(".") + } +} + +/// The families that MUST each be internally coherent, with the line each is pinned to. +/// +/// `chia-sdk-*` and the chia/clvm primitives share the 0.36 line: they are listed as ONE family +/// precisely because the shipped defect split them apart. `chia-puzzles` and `clvmr` version +/// independently of both and of each other, so each is its own family. +const FAMILIES: &[(&str, &str, &[&str])] = &[ + ( + "the chia 0.36 line (chia-sdk-* + the chia/clvm primitives)", + "0.36", + &[ + "chia-bls", + "chia-protocol", + "chia-puzzle-types", + "chia-sdk-driver", + "chia-sdk-test", + "chia-sdk-types", + "chia-traits", + "clvm-traits", + "clvm-utils", + ], + ), + ("the chia-puzzles line", "0.20", &["chia-puzzles"]), + ("the clvmr line", "0.16", &["clvmr"]), +]; + +/// Reads every `chia-*`/`clvm*` requirement declared in `[dependencies]` and `[dev-dependencies]`. +/// +/// Read at RUNTIME rather than `include_str!`d so that reverting a version in the manifest and +/// re-running the suite is a genuine end-to-end proof of the guard, with no recompilation subtlety +/// standing between the edit and the verdict. +fn declared_chia_deps() -> Vec { + let manifest = fs::read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/Cargo.toml")) + .expect("the crate's own Cargo.toml is readable"); + + let mut section = String::new(); + let mut found = Vec::new(); + + for raw in manifest.lines() { + let line = raw.trim(); + // Comments carry example version numbers (including this guard's own rationale), so they + // must never be parsed as declarations. + if line.starts_with('#') || line.is_empty() { + continue; + } + if line.starts_with('[') { + section = line.to_string(); + continue; + } + if section != "[dependencies]" && section != "[dev-dependencies]" { + continue; + } + let Some((name, rest)) = line.split_once('=') else { + continue; + }; + let name = name.trim(); + if !(name.starts_with("chia") || name.starts_with("clvm")) { + continue; + } + let version = extract_version(rest.trim()).unwrap_or_else(|| { + panic!("dependency `{name}` declares no literal version this guard can read: {line}") + }); + found.push(Declared { + name: name.to_string(), + version, + }); + } + + found +} + +/// Pulls the version literal out of either `"0.36.1"` or `{ version = "0.36.1", optional = true }`. +fn extract_version(rest: &str) -> Option { + let quoted = if rest.starts_with('{') { + let at = rest.find("version")?; + &rest[at..] + } else { + rest + }; + let mut parts = quoted.split('"'); + parts.next()?; + parts.next().map(str::to_string) +} + +#[test] +fn every_chia_family_declares_a_single_minor_line() { + let declared = declared_chia_deps(); + + for (family, expected_line, members) in FAMILIES { + for member in *members { + let Some(dep) = declared.iter().find(|d| d.name == *member) else { + continue; // absence is the cardinality test's job, below. + }; + assert_eq!( + dep.line(), + *expected_line, + "#5 REGRESSION: `{}` is declared at {} but {family} is pinned to {expected_line}.x. \ + Two minor lines of one chia family in one manifest is the internal split that \ + shipped as 0.3.1. Move the whole family together, or re-state the family's line here.", + dep.name, + dep.version, + ); + } + } +} + +#[test] +fn every_declared_chia_dep_belongs_to_a_classified_family() { + let classified: BTreeSet<&str> = FAMILIES + .iter() + .flat_map(|(_, _, members)| members.iter().copied()) + .collect(); + + for dep in declared_chia_deps() { + assert!( + classified.contains(dep.name.as_str()), + "`{}` is a chia/clvm dependency this coherence guard does not classify. A new chia \ + dependency can silently arrive on a foreign version line, which is exactly how the \ + 0.3.1 split went unnoticed. Add it to the family it belongs to in FAMILIES.", + dep.name, + ); + } +} + +#[test] +fn the_declared_chia_dependency_set_is_exactly_the_expected_one() { + // Pinned by exact membership, not by count: a guard that only counts cannot tell a dropped + // dependency from a substituted one, and both are ways for a family to lose a member without + // the coherence test above ever seeing it (it skips names it cannot find). + let expected: BTreeSet<&str> = BTreeSet::from([ + "chia-bls", + "chia-protocol", + "chia-puzzle-types", + "chia-puzzles", + "chia-sdk-driver", + "chia-sdk-test", + "chia-sdk-types", + "chia-traits", + "clvm-traits", + "clvm-utils", + "clvmr", + ]); + + let actual: BTreeSet = declared_chia_deps().into_iter().map(|d| d.name).collect(); + let actual: BTreeSet<&str> = actual.iter().map(String::as_str).collect(); + + assert_eq!( + actual, expected, + "the crate's chia/clvm dependency set changed. Confirm the new set is on ONE line per \ + family, then update this expectation in the same commit.", + ); +} From b2f3bb9b4753fb4ffae0c6ae2f04b01dc05670f2 Mon Sep 17 00:00:00 2001 From: Michael Taylor Date: Wed, 26 Aug 2026 09:27:29 -0700 Subject: [PATCH 6/6] docs(test): warn that revert-proofing this guard pollutes Cargo.lock Proving the coherence guard fires means reintroducing a split into Cargo.toml. Running the suite in that state silently re-resolves Cargo.lock -- 217 lines, when this was first done -- so restoring only Cargo.toml leaves the lock carrying both the experiment's old line and the correct one. That is a two-line split created by the proof, in the crate whose entire job is to have none, and it would have shipped in this PR. What caught it was the follow-up run using --locked; without that flag cargo re-resolves again, prints green, and the pollution is committed. Documented here because this test file is exactly where the next person will run that experiment. Co-Authored-By: Claude --- tests/manifest_chia_coherence.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/manifest_chia_coherence.rs b/tests/manifest_chia_coherence.rs index cfe03ad..df55191 100644 --- a/tests/manifest_chia_coherence.rs +++ b/tests/manifest_chia_coherence.rs @@ -13,6 +13,18 @@ //! The defect was **manifest coherence**, and manifest coherence is mechanically assertable. That //! is what these tests assert. //! +//! ## If you revert-proof these tests, restore `Cargo.lock` as well +//! +//! Proving this guard fires means reintroducing a split into `Cargo.toml` and watching it fail. +//! Running the suite in that state **silently re-resolves `Cargo.lock`** — 217 lines, when this was +//! first done. Restoring only `Cargo.toml` therefore leaves the lock carrying BOTH the experiment's +//! old line and the correct one: a two-line split, created by the proof, in the very crate whose +//! job is to have none. +//! +//! Restore both files, and make the restore run pass `--locked`. That flag is what turns the +//! leftover into a loud refusal instead of a silent green — without it cargo re-resolves again and +//! the pollution ships. +//! //! ## Why the manifest, and not `Cargo.lock` //! //! #5 is about the versions this crate DECLARES. The resolved lock legitimately contains older