diff --git a/.github/workflows/audit-format.yaml b/.github/workflows/audit-format.yaml index 349b22672..6ec45d2bf 100644 --- a/.github/workflows/audit-format.yaml +++ b/.github/workflows/audit-format.yaml @@ -46,7 +46,7 @@ jobs: # This can only be ran in root dir - name: Run audit - run: cargo audit --ignore RUSTSEC-2022-0093 --ignore RUSTSEC-2021-0076 --ignore RUSTSEC-2022-0090 --ignore RUSTSEC-2022-0028 + run: cargo audit --ignore RUSTSEC-2022-0093 --ignore RUSTSEC-2021-0076 --ignore RUSTSEC-2022-0090 --ignore RUSTSEC-2022-002 --ignore RUSTSEC-2022-0028 - name: Run rustfmt run: cargo fmt --all -- --check diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 519eee6a2..fb366edb3 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -85,7 +85,7 @@ jobs: run: cargo install cargo-audit - name: Run audit - run: cargo audit --ignore RUSTSEC-2022-0093 --ignore RUSTSEC-2021-0076 --ignore RUSTSEC-2022-0090 --ignore RUSTSEC-2022-0028 + run: cargo audit --ignore RUSTSEC-2022-0093 --ignore RUSTSEC-2021-0076 --ignore RUSTSEC-2022-0090 --ignore RUSTSEC-2022-002 --ignore RUSTSEC-2022-0028 - name: Run rustfmt run: cargo fmt --all -- --check diff --git a/Cargo.lock b/Cargo.lock index 38291daa8..a51718053 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,16 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ - "gimli", + "gimli 0.27.1", +] + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli 0.28.1", ] [[package]] @@ -17,15 +26,51 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array 0.14.6", +] + +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle 2.4.1", +] + [[package]] name = "ahash" -version = "0.7.6" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ - "getrandom 0.2.8", + "cfg-if", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -37,6 +82,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -109,6 +160,18 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" + [[package]] name = "arc-swap" version = "1.6.0" @@ -130,11 +193,17 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "async-stream" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad445822218ce64be7a341abfb0b1ea43b5c23aa83902542a4542e78309d8e5e" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" dependencies = [ "async-stream-impl", "futures-core", @@ -143,33 +212,39 @@ dependencies = [ [[package]] name = "async-stream-impl" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4655ae1a7b0cdf149156f780c5bf3f1352bc53cbd9e0a361a7ef7b22947e965" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn 2.0.39", ] [[package]] name = "async-trait" -version = "0.1.66" +version = "0.1.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84f9ebcc6c1f5b8cb160f6990096a5c127f423fcb6e1ccc46c370cbdfb75dfc" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn 2.0.39", ] [[package]] name = "atomic" -version = "0.5.1" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" + +[[package]] +name = "atomic" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c" +checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994" dependencies = [ - "autocfg", + "bytemuck", ] [[package]] @@ -207,12 +282,12 @@ version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" dependencies = [ - "addr2line", + "addr2line 0.19.0", "cc", "cfg-if", "libc", "miniz_oxide", - "object", + "object 0.30.3", "rustc-demangle", ] @@ -279,6 +354,37 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.64.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 1.0.107", + "which", +] + [[package]] name = "bip39" version = "1.0.1" @@ -380,13 +486,25 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" dependencies = [ - "block-padding 0.1.5", + "block-padding", "byte-tools", "byteorder", "generic-array 0.12.4", @@ -398,7 +516,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding 0.2.1", "generic-array 0.14.6", ] @@ -420,23 +537,15 @@ dependencies = [ "byte-tools", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "bollard" -version = "0.11.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92fed694fd5a7468c971538351c61b9c115f1ae6ed411cd2800f0f299403a4b" +checksum = "f03db470b3c0213c47e978da93200259a1eb4dae2e5512cba9955e2b540a6fc6" dependencies = [ - "base64 0.13.1", + "base64 0.21.3", "bollard-stubs", "bytes", - "chrono", - "dirs-next", "futures-core", "futures-util", "hex 0.4.3", @@ -444,41 +553,69 @@ dependencies = [ "hyper", "hyperlocal", "log", - "pin-project", + "pin-project-lite", "serde", "serde_derive", "serde_json", + "serde_repr", "serde_urlencoded", "thiserror", "tokio", - "tokio-util 0.6.10", + "tokio-util", "url", "winapi", ] [[package]] name = "bollard-stubs" -version = "1.41.0" +version = "1.43.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2f2e73fffe9455141e170fb9c1feb0ac521ec7e7dcd47a7cab72a658490fb8" +checksum = "b58071e8fd9ec1e930efd28e3a90c1251015872a2ce49f81f36421b86466932e" dependencies = [ - "chrono", "serde", + "serde_repr", "serde_with", ] +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "tinyvec", +] + [[package]] name = "bumpalo" version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + [[package]] name = "byte-tools" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" +[[package]] +name = "bytemuck" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" + [[package]] name = "byteorder" version = "1.4.3" @@ -502,6 +639,18 @@ name = "cc" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] [[package]] name = "cfg-if" @@ -511,9 +660,8 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chainhook-sdk" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea96f80f7dee4dd2e921594dcff61e59c66bf15fd00d0c0cfec4770039a59dcc" +version = "0.12.0" +source = "git+https://github.com/hirosystems/chainhook.git?rev=a938e61846a430750ad31d84b2032efabf6d039f#a938e61846a430750ad31d84b2032efabf6d039f" dependencies = [ "base58 0.2.0", "base64 0.13.1", @@ -539,23 +687,22 @@ dependencies = [ "serde-hex", "serde_derive", "serde_json", - "stacks-rpc-client 2.0.0", + "stacks-rpc-client 2.1.0 (git+https://github.com/hirosystems/clarinet.git?branch=chore/upgrade-clarity-vm)", "threadpool", "tokio", ] [[package]] name = "chainhook-types" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458eb03de9a0a1d3f4ecb6b37bcd33cb127bb67ea3b4857fd41e13cc96e0d6a5" +version = "1.3.0" +source = "git+https://github.com/hirosystems/chainhook.git?rev=a938e61846a430750ad31d84b2032efabf6d039f#a938e61846a430750ad31d84b2032efabf6d039f" dependencies = [ "hex 0.4.3", "schemars", "serde", "serde_derive", "serde_json", - "strum", + "strum 0.23.0", ] [[package]] @@ -573,6 +720,27 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clang-sys" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +dependencies = [ + "glob", + "libc", + "libloading 0.7.4", +] + [[package]] name = "clap" version = "4.4.8" @@ -613,7 +781,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -622,6 +790,19 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +[[package]] +name = "clar2wasm" +version = "0.1.0" +source = "git+https://github.com/stacks-network/clarity-wasm.git#4e06a7b10efde6986ec8d12d4e791e677d033cb1" +dependencies = [ + "clap", + "clarity", + "lazy_static", + "regex", + "walrus", + "wat", +] + [[package]] name = "clarinet-cli" version = "2.1.0" @@ -639,7 +820,7 @@ dependencies = [ "clarity-lsp", "clarity-repl 2.1.0", "crossbeam-channel", - "crossterm 0.22.1", + "crossterm", "ctrlc", "dirs", "encoding_rs", @@ -653,12 +834,13 @@ dependencies = [ "libsecp256k1 0.7.1", "log", "mac_address", - "mio 0.8.6", + "mio", "nix 0.24.2", "num_cpus", "pbkdf2 0.12.2", "percent-encoding", "pin-project", + "ratatui", "regex", "reqwest", "segment", @@ -670,15 +852,14 @@ dependencies = [ "signal-hook-registry", "similar", "stacks-network", - "strum", + "strum 0.23.0", "tempfile", "termcolor", "tiny-hderive", "tokio", - "tokio-util 0.7.7", + "tokio-util", "toml 0.5.11", "tower-lsp", - "tui", "winapi", ] @@ -766,6 +947,30 @@ dependencies = [ "sha2 0.10.6", ] +[[package]] +name = "clarity" +version = "2.2.0" +source = "git+https://github.com/stacks-network/stacks-core.git?branch=feat/clarity-wasm-next#25b82d1dcc62d7353db1bd4056be8a4538816eae" +dependencies = [ + "integer-sqrt", + "lazy_static", + "rand 0.7.3", + "rand_chacha 0.2.2", + "regex", + "rstest", + "rstest_reuse", + "rusqlite", + "serde", + "serde_derive", + "serde_json", + "serde_stacker", + "sha2-asm", + "slog", + "stacks-common", + "time 0.2.27", + "wasmtime", +] + [[package]] name = "clarity-events" version = "1.0.0" @@ -820,29 +1025,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "clarity-repl" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb0935839b51a01d7436b31420713e0a9698d2920cfa0493482c9dbb4fe0a696" -dependencies = [ - "ansi_term", - "atty", - "chrono", - "clarity-vm", - "getrandom 0.2.8", - "hiro-system-kit 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "integer-sqrt", - "lazy_static", - "regex", - "reqwest", - "serde", - "serde_derive", - "serde_json", - "sha2 0.10.6", - "sha3 0.9.1", -] - [[package]] name = "clarity-repl" version = "2.1.0" @@ -851,7 +1033,8 @@ dependencies = [ "atty", "bytes", "chrono", - "clarity-vm", + "clar2wasm", + "clarity", "debug_types", "futures", "getrandom 0.2.8", @@ -871,32 +1054,32 @@ dependencies = [ "serde_json", "sha2 0.10.6", "tokio", - "tokio-util 0.7.7", + "tokio-util", "wasm-bindgen", "wasm-bindgen-futures", + "wsts", ] [[package]] -name = "clarity-vm" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90cebf93044798d7729008e9a467b16578aead7f0b3568219a2b20b421b683db" +name = "clarity-repl" +version = "2.1.0" +source = "git+https://github.com/hirosystems/clarinet.git?branch=chore/upgrade-clarity-vm#96eada8d55b3738d68e437c1d8474e1a247ed3f8" dependencies = [ + "ansi_term", + "atty", + "chrono", + "clarity", + "getrandom 0.2.8", + "hiro-system-kit 0.1.0 (git+https://github.com/hirosystems/clarinet.git?branch=chore/upgrade-clarity-vm)", "integer-sqrt", "lazy_static", - "rand 0.7.3", - "rand_chacha 0.2.2", "regex", - "rstest", - "rstest_reuse", - "rusqlite", + "reqwest", "serde", "serde_derive", "serde_json", - "serde_stacker", - "sha2-asm", - "stacks-common", - "time 0.2.27", + "sha2 0.10.6", + "wsts", ] [[package]] @@ -984,12 +1167,31 @@ dependencies = [ "version_check", ] +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +[[package]] +name = "cpp_demangle" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeaa953eaad386a53111e47172c2fedba671e5684c8dd601a5f474f4f118710f" +dependencies = [ + "cfg-if", +] + [[package]] name = "cpufeatures" version = "0.2.5" @@ -1000,68 +1202,194 @@ dependencies = [ ] [[package]] -name = "crossbeam-channel" -version = "0.5.6" +name = "cranelift-bforest" +version = "0.102.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "8e7e56668d2263f92b691cb9e4a2fcb186ca0384941fe420484322fa559c3329" dependencies = [ - "cfg-if", - "crossbeam-utils", + "cranelift-entity", ] [[package]] -name = "crossbeam-utils" -version = "0.8.14" +name = "cranelift-codegen" +version = "0.102.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +checksum = "2a9ff61938bf11615f55b80361288c68865318025632ea73c65c0b44fa16283c" dependencies = [ - "cfg-if", + "bumpalo", + "cranelift-bforest", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-control", + "cranelift-entity", + "cranelift-isle", + "gimli 0.28.1", + "hashbrown 0.14.0", + "log", + "regalloc2", + "smallvec 1.10.0", + "target-lexicon", ] [[package]] -name = "crossterm" -version = "0.22.1" +name = "cranelift-codegen-meta" +version = "0.102.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85525306c4291d1b73ce93c8acf9c339f9b213aef6c1d85c3830cbf1c16325c" +checksum = "50656bf19e3d4a153b404ff835b8b59e924cfa3682ebe0d3df408994f37983f6" dependencies = [ - "bitflags 1.3.2", - "crossterm_winapi", - "libc", - "mio 0.7.14", - "parking_lot 0.11.2", - "signal-hook", - "signal-hook-mio", - "winapi", + "cranelift-codegen-shared", ] [[package]] -name = "crossterm" -version = "0.23.2" +name = "cranelift-codegen-shared" +version = "0.102.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2102ea4f781910f8a5b98dd061f4c2023f479ce7bb1236330099ceb5a93cf17" -dependencies = [ - "bitflags 1.3.2", - "crossterm_winapi", - "libc", - "mio 0.8.6", - "parking_lot 0.12.1", - "signal-hook", - "signal-hook-mio", - "winapi", -] +checksum = "388041deeb26109f1ea73c1812ea26bfd406c94cbce0bb5230aa44277e43b209" [[package]] -name = "crossterm_winapi" -version = "0.9.0" +name = "cranelift-control" +version = "0.102.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" +checksum = "b39b7c512ffac527e5b5df9beae3d67ab85d07dca6d88942c16195439fedd1d3" dependencies = [ - "winapi", + "arbitrary", ] [[package]] -name = "crunchy" -version = "0.2.2" +name = "cranelift-entity" +version = "0.102.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb25f573701284fe2bcf88209d405342125df00764b396c923e11eafc94d892" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "cranelift-frontend" +version = "0.102.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57374fd11d72cf9ffb85ff64506ed831440818318f58d09f45b4185e5e9c376" +dependencies = [ + "cranelift-codegen", + "log", + "smallvec 1.10.0", + "target-lexicon", +] + +[[package]] +name = "cranelift-isle" +version = "0.102.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae769b235f6ea2f86623a3ff157cc04a4ff131dc9fe782c2ebd35f272043581e" + +[[package]] +name = "cranelift-native" +version = "0.102.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dc7bfb8f13a0526fe20db338711d9354729b861c336978380bb10f7f17dd207" +dependencies = [ + "cranelift-codegen", + "libc", + "target-lexicon", +] + +[[package]] +name = "cranelift-wasm" +version = "0.102.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c5f41a4af931b756be05af0dd374ce200aae2d52cea16b0beb07e8b52732c35" +dependencies = [ + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "itertools 0.10.5", + "log", + "smallvec 1.10.0", + "wasmparser 0.116.1", + "wasmtime-types", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset 0.9.0", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossterm" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +dependencies = [ + "bitflags 2.4.0", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "crunchy" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" @@ -1072,6 +1400,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array 0.14.6", + "rand_core 0.6.4", "typenum", ] @@ -1122,6 +1451,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + [[package]] name = "ctrlc" version = "3.2.5" @@ -1190,41 +1528,6 @@ dependencies = [ "syn 1.0.107", ] -[[package]] -name = "darling" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 1.0.107", -] - -[[package]] -name = "darling_macro" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" -dependencies = [ - "darling_core", - "quote", - "syn 1.0.107", -] - [[package]] name = "dashmap" version = "5.4.0" @@ -1235,7 +1538,7 @@ dependencies = [ "hashbrown 0.12.3", "lock_api", "once_cell", - "parking_lot_core 0.9.7", + "parking_lot_core", ] [[package]] @@ -1249,6 +1552,15 @@ dependencies = [ "serde_json", ] +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "uuid", +] + [[package]] name = "devise" version = "0.4.1" @@ -1277,9 +1589,9 @@ checksum = "35b50dba0afdca80b187392b24f2499a88c336d5a8493e4b4ccfb608708be56a" dependencies = [ "bitflags 2.4.0", "proc-macro2", - "proc-macro2-diagnostics 0.10.0", + "proc-macro2-diagnostics", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -1311,6 +1623,16 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "directories-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + [[package]] name = "dirs" version = "4.0.0" @@ -1379,9 +1701,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "encode_unicode" @@ -1467,6 +1789,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + [[package]] name = "fallible-streaming-iterator" version = "0.1.9" @@ -1492,18 +1820,30 @@ dependencies = [ [[package]] name = "figment" -version = "0.10.8" +version = "0.10.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e56602b469b2201400dec66a66aec5a9b8761ee97cd1b8c96ab2483fcc16cc9" +checksum = "649f3e5d826594057e9a519626304d8da859ea8a0b18ce99500c586b8d45faee" dependencies = [ - "atomic", + "atomic 0.6.0", "pear", "serde", - "toml 0.5.11", + "toml 0.8.8", "uncased", "version_check", ] +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1519,6 +1859,12 @@ 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" version = "0.3.26" @@ -1590,6 +1936,12 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" + [[package]] name = "futures-util" version = "0.3.26" @@ -1627,11 +1979,24 @@ dependencies = [ "byteorder", ] +[[package]] +name = "fxprof-processed-profile" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27d12c0aed7f1e24276a241aadc4cb8ea9f83000f34bc062b7cc2d51e3b0fabd" +dependencies = [ + "bitflags 2.4.0", + "debugid", + "fxhash", + "serde", + "serde_json", +] + [[package]] name = "generator" -version = "0.7.3" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a20a288a94683f5f4da0adecdbe095c94a77c295e514cc6484e9394dd8376e" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" dependencies = [ "cc", "libc", @@ -1683,12 +2048,44 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "ghash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug 0.3.0", + "polyval", +] + +[[package]] +name = "gimli" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" +dependencies = [ + "fallible-iterator 0.2.0", + "indexmap 1.9.2", + "stable_deref_trait", +] + [[package]] name = "gimli" version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec" +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +dependencies = [ + "fallible-iterator 0.3.0", + "indexmap 2.0.0", + "stable_deref_trait", +] + [[package]] name = "glob" version = "0.3.1" @@ -1710,9 +2107,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.18" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -1720,41 +2117,46 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.2", + "indexmap 2.0.0", "slab", "tokio", - "tokio-util 0.7.7", + "tokio-util", "tracing", ] [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash", -] +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.12.3" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] [[package]] name = "hashbrown" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +dependencies = [ + "ahash", + "allocator-api2", + "serde", +] [[package]] name = "hashlink" -version = "0.7.0" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.11.2", + "hashbrown 0.14.0", ] [[package]] @@ -1833,12 +2235,10 @@ dependencies = [ [[package]] name = "hiro-system-kit" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69a7ca4bddaacbc8180886d378ad8c2b9f74217503002346719b57adbd83124" +source = "git+https://github.com/hirosystems/clarinet.git?branch=chore/upgrade-clarity-vm#96eada8d55b3738d68e437c1d8474e1a247ed3f8" dependencies = [ "ansi_term", "atty", - "futures", "lazy_static", "tokio", ] @@ -1912,6 +2312,15 @@ dependencies = [ "hmac 0.8.1", ] +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "http" version = "0.2.8" @@ -1963,7 +2372,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.7", "tokio", "tower-service", "tracing", @@ -1972,10 +2381,11 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.23.2" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ + "futures-util", "http", "hyper", "rustls", @@ -2021,10 +2431,10 @@ dependencies = [ ] [[package]] -name = "ident_case" -version = "1.0.1" +name = "id-arena" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" [[package]] name = "idna" @@ -2036,6 +2446,26 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.107", +] + [[package]] name = "indexmap" version = "1.9.2" @@ -2055,8 +2485,15 @@ checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ "equivalent", "hashbrown 0.14.0", + "serde", ] +[[package]] +name = "indoc" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" + [[package]] name = "inlinable_string" version = "0.1.15" @@ -2064,12 +2501,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" [[package]] -name = "instant" -version = "0.1.12" +name = "inout" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ - "cfg-if", + "generic-array 0.14.6", ] [[package]] @@ -2110,11 +2547,58 @@ dependencies = [ ] [[package]] -name = "itoa" -version = "1.0.6" +name = "itertools" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" - +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "ittapi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b996fe614c41395cdaedf3cf408a9534851090959d90d54a535f675550b64b1" +dependencies = [ + "anyhow", + "ittapi-sys", + "log", +] + +[[package]] +name = "ittapi-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f5385394064fa2c886205dba02598013ce83d3e92d33dbdc0c52fe0e7bf4fc" +dependencies = [ + "cc", +] + +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.61" @@ -2157,11 +2641,23 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + [[package]] name = "libc" -version = "0.2.149" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libloading" @@ -2173,6 +2669,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + [[package]] name = "libsecp256k1" version = "0.3.5" @@ -2287,9 +2793,9 @@ dependencies = [ [[package]] name = "libsqlite3-sys" -version = "0.24.2" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14" +checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa" dependencies = [ "cc", "pkg-config", @@ -2319,9 +2825,9 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" [[package]] name = "lock_api" @@ -2358,6 +2864,15 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "lru" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2994eeba8ed550fd9b47a0b38f0242bc3344e496483c6180b69139cc2fa5d1d7" +dependencies = [ + "hashbrown 0.14.0", +] + [[package]] name = "lsp-types" version = "0.94.0" @@ -2381,6 +2896,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + [[package]] name = "matchers" version = "0.1.0" @@ -2402,6 +2926,15 @@ version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +[[package]] +name = "memfd" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" +dependencies = [ + "rustix 0.38.25", +] + [[package]] name = "memoffset" version = "0.6.5" @@ -2411,6 +2944,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + [[package]] name = "memzero" version = "0.1.0" @@ -2434,6 +2976,12 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniscript" version = "10.0.0" @@ -2455,43 +3003,21 @@ dependencies = [ [[package]] name = "mio" -version = "0.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" -dependencies = [ - "libc", - "log", - "miow", - "ntapi", - "winapi", -] - -[[package]] -name = "mio" -version = "0.8.6" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.45.0", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", + "windows-sys 0.48.0", ] [[package]] name = "multer" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed4198ce7a4cbd2a57af78d28c6fbb57d81ac5f1d6ad79ac6c5587419cbdf22" +checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" dependencies = [ "bytes", "encoding_rs", @@ -2501,9 +3027,9 @@ dependencies = [ "log", "memchr", "mime", - "spin 0.9.6", + "spin 0.9.8", "tokio", - "tokio-util 0.7.7", + "tokio-util", "version_check", ] @@ -2544,7 +3070,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02662cd2e62b131937bdef85d0918b05bc3c204daf4c64af62845403eccb60f3" dependencies = [ "cfg-if", - "libloading", + "libloading 0.6.7", "smallvec 1.10.0", ] @@ -2567,7 +3093,7 @@ dependencies = [ "cc", "cfg-if", "libc", - "memoffset", + "memoffset 0.6.5", ] [[package]] @@ -2579,7 +3105,7 @@ dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", - "memoffset", + "memoffset 0.6.5", ] [[package]] @@ -2601,12 +3127,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] -name = "ntapi" -version = "0.3.7" +name = "nom" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ - "winapi", + "memchr", + "minimal-lexical", ] [[package]] @@ -2711,6 +3238,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "crc32fast", + "hashbrown 0.14.0", + "indexmap 2.0.0", + "memchr", +] + [[package]] name = "once_cell" version = "1.17.0" @@ -2736,38 +3275,62 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] -name = "parking_lot" -version = "0.11.2" +name = "p256k1" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +checksum = "5afcf536d20c074ef45371ee9a654dcfc46fb2dde18ecc54ec30c936eb850fa2" dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", + "bindgen", + "bitvec", + "bs58 0.4.0", + "cc", + "hex 0.4.3", + "itertools 0.10.5", + "num-traits", + "primitive-types", + "proc-macro2", + "quote", + "rand_core 0.6.4", + "rustfmt-wrapper", + "serde", + "sha2 0.10.6", + "syn 2.0.39", ] [[package]] -name = "parking_lot" -version = "0.12.1" +name = "parity-scale-codec" +version = "3.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" dependencies = [ - "lock_api", - "parking_lot_core 0.9.7", + "arrayvec", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", ] [[package]] -name = "parking_lot_core" -version = "0.8.6" +name = "parity-scale-codec-derive" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec 1.10.0", - "winapi", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.107", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", ] [[package]] @@ -2805,6 +3368,12 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "pbkdf2" version = "0.11.0" @@ -2831,42 +3400,38 @@ dependencies = [ [[package]] name = "pear" -version = "0.2.3" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e44241c5e4c868e3eaa78b7c1848cadd6344ed4f54d029832d32b415a58702" +checksum = "61a386cd715229d399604b50d1361683fe687066f42d56f54be995bc6868f71c" dependencies = [ "inlinable_string", "pear_codegen", - "yansi", + "yansi 1.0.0-rc.1", ] [[package]] name = "pear_codegen" -version = "0.2.3" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a5ca643c2303ecb740d506539deba189e16f2754040a42901cd8105d0282d0" +checksum = "da9f0f13dac8069c139e8300a6510e3f4143ecf5259c60b116a9b271b4ca0d54" dependencies = [ "proc-macro2", - "proc-macro2-diagnostics 0.9.1", + "proc-macro2-diagnostics", "quote", - "syn 1.0.107", + "syn 2.0.39", ] [[package]] -name = "percent-encoding" -version = "2.2.0" +name = "peeking_take_while" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] -name = "pest" -version = "2.5.5" +name = "percent-encoding" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "028accff104c4e513bad663bbcd2ad7cfd5304144404c31ed0a77ac103d00660" -dependencies = [ - "thiserror", - "ucd-trie", -] +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pico-args" @@ -2896,9 +3461,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -2912,6 +3477,28 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +[[package]] +name = "polynomial" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27abb6e4638dcecc65a92b50d7f1d87dd6dea987ba71db987b6bf881f4877e9d" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "polyval" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug 0.3.0", + "universal-hash", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2932,6 +3519,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit 0.20.7", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -2964,37 +3571,24 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] [[package]] name = "proc-macro2-diagnostics" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", - "version_check", - "yansi", -] - -[[package]] -name = "proc-macro2-diagnostics" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "606c4ba35817e2922a308af55ad51bab3645b59eae5c570d4a6cf07e36bd493b" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", "version_check", - "yansi", + "yansi 1.0.0-rc.1", ] [[package]] @@ -3008,13 +3602,19 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.28" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "radix_trie" version = "0.2.1" @@ -3102,6 +3702,45 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "ratatui" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5659e52e4ba6e07b2dad9f1158f578ef84a73762625ddb51536019f34d180eb" +dependencies = [ + "bitflags 2.4.0", + "cassowary", + "crossterm", + "indoc", + "itertools 0.12.0", + "lru", + "paste", + "stability", + "strum 0.25.0", + "unicode-segmentation", + "unicode-width", +] + +[[package]] +name = "rayon" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -3133,22 +3772,35 @@ dependencies = [ [[package]] name = "ref-cast" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9af2cf09ef80e610097515e80095b7f76660a92743c4185aff5406cd5ce3dd5" +checksum = "85d07b1a5f16b5548f4255a978c94259971aff73f39e8d67e8250e8b2f6667c3" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c501201393982e275433bc55de7d6ae6f00e7699cd5572c5b57581cd69c881b" +checksum = "a930b010d9effee5834317bb7ff406b76af7724348fd572b38705b4bd099fa92" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn 2.0.39", +] + +[[package]] +name = "regalloc2" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6" +dependencies = [ + "hashbrown 0.13.2", + "log", + "rustc-hash", + "slice-group-by", + "smallvec 1.10.0", ] [[package]] @@ -3169,7 +3821,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "regex-syntax 0.6.28", + "regex-syntax 0.6.29", ] [[package]] @@ -3185,9 +3837,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" @@ -3197,9 +3849,9 @@ checksum = "56d84fdd47036b038fc80dd333d10b6aab10d5d31f4a366e20014def75328d33" [[package]] name = "reqwest" -version = "0.11.16" +version = "0.11.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254" +checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" dependencies = [ "base64 0.21.3", "bytes", @@ -3223,6 +3875,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "system-configuration", "tokio", "tokio-rustls", "tower-service", @@ -3244,11 +3897,25 @@ dependencies = [ "libc", "once_cell", "spin 0.5.2", - "untrusted", + "untrusted 0.7.1", "web-sys", "winapi", ] +[[package]] +name = "ring" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babe80d5c16becf6594aa32ad2be8fe08498e7ae60b77de8df700e67f191d7e" +dependencies = [ + "cc", + "getrandom 0.2.8", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + [[package]] name = "ripemd" version = "0.1.3" @@ -3277,7 +3944,7 @@ checksum = "58734f7401ae5cfd129685b48f61182331745b357b96f2367f01aebaf1cc9cc9" dependencies = [ "async-stream", "async-trait", - "atomic", + "atomic 0.5.3", "binascii", "bytes", "either", @@ -3289,7 +3956,7 @@ dependencies = [ "memchr", "multer", "num_cpus", - "parking_lot 0.12.1", + "parking_lot", "pin-project-lite", "rand 0.8.5", "ref-cast", @@ -3302,10 +3969,10 @@ dependencies = [ "time 0.3.17", "tokio", "tokio-stream", - "tokio-util 0.7.7", + "tokio-util", "ubyte", "version_check", - "yansi", + "yansi 0.5.1", ] [[package]] @@ -3320,7 +3987,7 @@ dependencies = [ "proc-macro2", "quote", "rocket_http", - "syn 2.0.28", + "syn 2.0.39", "unicode-xid", ] @@ -3353,40 +4020,53 @@ dependencies = [ [[package]] name = "rstest" -version = "0.11.0" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de1bb486a691878cd320c2f0d319ba91eeaa2e894066d8b5f8f117c000e9d962" +dependencies = [ + "futures", + "futures-timer", + "rstest_macros", + "rustc_version 0.4.0", +] + +[[package]] +name = "rstest_macros" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2288c66aeafe3b2ed227c981f364f9968fa952ef0b30e84ada4486e7ee24d00a" +checksum = "290ca1a1c8ca7edb7c3283bd44dc35dd54fdec6253a3912e201ba1072018fca8" dependencies = [ "cfg-if", "proc-macro2", "quote", "rustc_version 0.4.0", "syn 1.0.107", + "unicode-ident", ] [[package]] name = "rstest_reuse" -version = "0.1.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32c6cfaae58c048728261723a72b80a0aa9f3768e9a7da3b302a24d262525219" +checksum = "45f80dcc84beab3a327bbe161f77db25f336a1452428176787c8c79ac79d7073" dependencies = [ "quote", - "rustc_version 0.3.3", + "rand 0.8.5", + "rustc_version 0.4.0", "syn 1.0.107", ] [[package]] name = "rusqlite" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85127183a999f7db96d1a976a309eebbfb6ea3b0b400ddd8340190129de6eb7a" +checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" dependencies = [ "bitflags 1.3.2", - "fallible-iterator", + "fallible-iterator 0.2.0", "fallible-streaming-iterator", "hashlink", "libsqlite3-sys", - "memchr", "serde_json", "smallvec 1.10.0", ] @@ -3397,6 +4077,18 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + [[package]] name = "rustc_version" version = "0.2.3" @@ -3408,20 +4100,24 @@ dependencies = [ [[package]] name = "rustc_version" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 0.11.0", + "semver 1.0.16", ] [[package]] -name = "rustc_version" -version = "0.4.0" +name = "rustfmt-wrapper" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "f1adc9dfed5cc999077978cc7163b9282c5751c8d39827c4ea8c8c220ca5a440" dependencies = [ - "semver 1.0.16", + "serde", + "tempfile", + "thiserror", + "toml 0.8.8", + "toolchain_find", ] [[package]] @@ -3440,27 +4136,27 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.18" +version = "0.38.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a74ee2d7c2581cd139b42447d7d9389b889bdaad3a73f1ebb16f2a3237bb19c" +checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" dependencies = [ "bitflags 2.4.0", "errno", "libc", - "linux-raw-sys 0.4.10", + "linux-raw-sys 0.4.11", "windows-sys 0.48.0", ] [[package]] name = "rustls" -version = "0.20.8" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", - "ring", + "ring 0.17.3", + "rustls-webpki", "sct", - "webpki", ] [[package]] @@ -3472,6 +4168,16 @@ dependencies = [ "base64 0.21.3", ] +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.3", + "untrusted 0.9.0", +] + [[package]] name = "rustversion" version = "1.0.11" @@ -3509,10 +4215,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" [[package]] -name = "schemars" -version = "0.8.15" +name = "same-file" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schemars" +version = "0.8.12" +source = "git+https://github.com/hirosystems/schemars.git?branch=feat-chainhook-fixes#15fdd4711700114d57c090aad62516593bd4ca6d" dependencies = [ "dyn-clone", "schemars_derive", @@ -3522,9 +4236,8 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" +version = "0.8.12" +source = "git+https://github.com/hirosystems/schemars.git?branch=feat-chainhook-fixes#15fdd4711700114d57c090aad62516593bd4ca6d" dependencies = [ "proc-macro2", "quote", @@ -3556,8 +4269,8 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] @@ -3619,16 +4332,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser 0.7.0", -] - -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser 0.10.2", + "semver-parser", ] [[package]] @@ -3643,15 +4347,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - [[package]] name = "serde" version = "1.0.188" @@ -3691,7 +4386,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -3707,9 +4402,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.104" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "indexmap 2.0.0", "itoa", @@ -3728,6 +4423,15 @@ dependencies = [ "syn 1.0.107", ] +[[package]] +name = "serde_spanned" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" +dependencies = [ + "serde", +] + [[package]] name = "serde_stacker" version = "0.1.7" @@ -3752,24 +4456,18 @@ dependencies = [ [[package]] name = "serde_with" -version = "1.14.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" +checksum = "f58c3a1b3e418f61c25b2aeb43fc6c95eaa252b8cecdda67f401943e9e08d33f" dependencies = [ + "base64 0.21.3", + "chrono", + "hex 0.4.3", + "indexmap 1.9.2", + "indexmap 2.0.0", "serde", - "serde_with_macros", -] - -[[package]] -name = "serde_with_macros" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 1.0.107", + "serde_json", + "time 0.3.17", ] [[package]] @@ -3857,18 +4555,6 @@ dependencies = [ "opaque-debug 0.2.3", ] -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "keccak", - "opaque-debug 0.3.0", -] - [[package]] name = "sha3" version = "0.10.6" @@ -3888,11 +4574,17 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" dependencies = [ "libc", "signal-hook-registry", @@ -3905,8 +4597,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" dependencies = [ "libc", - "mio 0.7.14", - "mio 0.8.6", + "mio", "signal-hook", ] @@ -3934,6 +4625,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + [[package]] name = "slog" version = "2.7.0" @@ -4023,6 +4720,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "spin" version = "0.5.2" @@ -4031,9 +4738,25 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spin" -version = "0.9.6" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "sptr" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" + +[[package]] +name = "stability" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5d6e0250b93c8427a177b849d144a96d5acc57006149479403d7861ab721e34" +checksum = "ebd1b177894da2a2d9120208c3386066af06a488255caabc5de8ddca22dbc3ce" +dependencies = [ + "quote", + "syn 1.0.107", +] [[package]] name = "stable-pattern" @@ -4044,6 +4767,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "stacker" version = "0.1.15" @@ -4060,8 +4789,7 @@ dependencies = [ [[package]] name = "stacks-common" version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c887baefb047fb7cd1c82d5a62e1deaca4b9ea9c701f965407db6c39a3fc902f" +source = "git+https://github.com/stacks-network/stacks-core.git?branch=feat/clarity-wasm-next#25b82d1dcc62d7353db1bd4056be8a4538816eae" dependencies = [ "chrono", "curve25519-dalek", @@ -4069,6 +4797,7 @@ dependencies = [ "lazy_static", "libc", "libsecp256k1 0.5.0", + "nix 0.23.2", "percent-encoding", "rand 0.7.3", "ripemd", @@ -4079,7 +4808,12 @@ dependencies = [ "serde_json", "sha2 0.10.6", "sha3 0.10.6", + "slog", + "slog-json", + "slog-term", "time 0.2.27", + "winapi", + "wsts", ] [[package]] @@ -4117,30 +4851,29 @@ dependencies = [ "clarinet-utils 1.0.0", "clarity-repl 2.1.0", "crossbeam-channel", - "crossterm 0.22.1", + "crossterm", "ctrlc", "dirs", "futures", "hiro-system-kit 0.1.0", + "ratatui", "reqwest", "serde", "serde_derive", "serde_json", "serde_yaml", "stacks-rpc-client 2.1.0", + "tokio", "tracing", "tracing-appender", "tracing-subscriber", - "tui", ] [[package]] name = "stacks-rpc-client" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab91f2053d36c8caedfdb2b98ace2cf852aba6d27c40ae92e2b35d946504a6e" +version = "2.1.0" dependencies = [ - "clarity-repl 2.0.0", + "clarity-repl 2.1.0", "hmac 0.12.1", "libsecp256k1 0.7.1", "pbkdf2 0.12.2", @@ -4155,8 +4888,9 @@ dependencies = [ [[package]] name = "stacks-rpc-client" version = "2.1.0" +source = "git+https://github.com/hirosystems/clarinet.git?branch=chore/upgrade-clarity-vm#96eada8d55b3738d68e437c1d8474e1a247ed3f8" dependencies = [ - "clarity-repl 2.1.0", + "clarity-repl 2.1.0 (git+https://github.com/hirosystems/clarinet.git?branch=chore/upgrade-clarity-vm)", "hmac 0.12.1", "libsecp256k1 0.7.1", "pbkdf2 0.12.2", @@ -4259,7 +4993,16 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb" dependencies = [ - "strum_macros", + "strum_macros 0.23.1", +] + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros 0.25.3", ] [[package]] @@ -4275,6 +5018,19 @@ dependencies = [ "syn 1.0.107", ] +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.39", +] + [[package]] name = "subtle" version = "1.0.0" @@ -4300,21 +5056,54 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.28" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "take_mut" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "target-lexicon" +version = "0.12.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" + [[package]] name = "tempfile" version = "3.8.0" @@ -4324,7 +5113,7 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix 0.38.18", + "rustix 0.38.25", "windows-sys 0.48.0", ] @@ -4350,22 +5139,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.38" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.38" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn 2.0.39", ] [[package]] @@ -4484,76 +5273,60 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.25.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", - "memchr", - "mio 0.8.6", + "mio", "num_cpus", - "parking_lot 0.12.1", + "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.5", "tokio-macros", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "1.8.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn 2.0.39", ] [[package]] name = "tokio-rustls" -version = "0.23.4" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ "rustls", "tokio", - "webpki", ] [[package]] name = "tokio-stream" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.6.10" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" dependencies = [ - "bytes", "futures-core", - "futures-sink", - "log", "pin-project-lite", "tokio", ] [[package]] name = "tokio-util" -version = "0.7.7" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", @@ -4579,6 +5352,64 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.21.0", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap 2.0.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +dependencies = [ + "indexmap 2.0.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toolchain_find" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc8c9a7f0a2966e1acdaf0461023d0b01471eeead645370cf4c3f5cff153f2a" +dependencies = [ + "home", + "once_cell", + "regex", + "semver 1.0.16", + "walkdir", +] + [[package]] name = "tower" version = "0.4.13" @@ -4616,7 +5447,7 @@ dependencies = [ "serde", "serde_json", "tokio", - "tokio-util 0.7.7", + "tokio-util", "tower", "tower-lsp-macros", "tracing", @@ -4685,20 +5516,20 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] [[package]] name = "tracing-subscriber" -version = "0.3.16" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "matchers", "nu-ansi-term", @@ -4718,19 +5549,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" -[[package]] -name = "tui" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96fe69244ec2af261bced1d9046a6fee6c8c2a6b0228e59e5ba39bc8ba4ed729" -dependencies = [ - "bitflags 1.3.2", - "cassowary", - "crossterm 0.23.2", - "unicode-segmentation", - "unicode-width", -] - [[package]] name = "typenum" version = "1.16.0" @@ -4739,24 +5557,30 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ubyte" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c81f0dae7d286ad0d9366d7679a77934cfc3cf3a8d67e82669794412b2368fe6" +checksum = "f720def6ce1ee2fc44d40ac9ed6d3a59c361c80a75a7aa8e75bb9baed31cf2ea" dependencies = [ "serde", ] [[package]] -name = "ucd-trie" -version = "0.1.5" +name = "uint" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" - -[[package]] -name = "uncased" -version = "0.9.7" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex 0.4.3", + "static_assertions", +] + +[[package]] +name = "uncased" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b01702b0fd0b3fadcf98e098780badda8742d4f4a7676615cad90e8ac73622" +checksum = "9b9bc53168a4be7402ab86c3aad243a84dd7381d09be0eddc81280c1da95ca68" dependencies = [ "serde", "version_check", @@ -4801,12 +5625,28 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle 2.4.1", +] + [[package]] name = "untrusted" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.3.1" @@ -4852,6 +5692,44 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "walrus" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c03529cd0c4400a2449f640d2f27cd1b48c3065226d15e26d98e4429ab0adb7" +dependencies = [ + "anyhow", + "gimli 0.26.2", + "id-arena", + "leb128", + "log", + "walrus-macro", + "wasm-encoder 0.29.0", + "wasmparser 0.80.2", +] + +[[package]] +name = "walrus-macro" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e5bd22c71e77d60140b0bd5be56155a37e5bd14e24f5f87298040d0cc40d7" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "syn 1.0.107", +] + [[package]] name = "want" version = "0.3.0" @@ -4940,6 +5818,354 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +[[package]] +name = "wasm-encoder" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18c41dbd92eaebf3612a39be316540b8377c871cb9bde6b064af962984912881" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasm-encoder" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasm-encoder" +version = "0.38.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasmparser" +version = "0.80.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "449167e2832691a1bff24cde28d2804e90e09586a448c8e76984792c44334a6b" + +[[package]] +name = "wasmparser" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" +dependencies = [ + "indexmap 2.0.0", + "semver 1.0.16", +] + +[[package]] +name = "wasmtime" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "642e12d108e800215263e3b95972977f473957923103029d7d617db701d67ba4" +dependencies = [ + "anyhow", + "async-trait", + "bincode", + "bumpalo", + "cfg-if", + "fxprof-processed-profile", + "indexmap 2.0.0", + "libc", + "log", + "object 0.32.1", + "once_cell", + "paste", + "psm", + "rayon", + "serde", + "serde_derive", + "serde_json", + "target-lexicon", + "wasm-encoder 0.36.2", + "wasmparser 0.116.1", + "wasmtime-cache", + "wasmtime-component-macro", + "wasmtime-cranelift", + "wasmtime-environ", + "wasmtime-fiber", + "wasmtime-jit", + "wasmtime-runtime", + "wat", + "windows-sys 0.48.0", +] + +[[package]] +name = "wasmtime-asm-macros" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beada8bb15df52503de0a4c58de4357bfd2f96d9a44a6e547bad11efdd988b47" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "wasmtime-cache" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aba5bf44d044d25892c03fb3534373936ee204141ff92bac8297787ac7f22318" +dependencies = [ + "anyhow", + "base64 0.21.3", + "bincode", + "directories-next", + "log", + "rustix 0.38.25", + "serde", + "serde_derive", + "sha2 0.10.6", + "toml 0.5.11", + "windows-sys 0.48.0", + "zstd", +] + +[[package]] +name = "wasmtime-component-macro" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ccba556991465cca68d5a54769684bcf489fb532059da55105f851642d52c1" +dependencies = [ + "anyhow", + "proc-macro2", + "quote", + "syn 2.0.39", + "wasmtime-component-util", + "wasmtime-wit-bindgen", + "wit-parser", +] + +[[package]] +name = "wasmtime-component-util" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05492a177a6006cb73f034d6e9a6fad6da55b23c4398835cb0012b5fa51ecf67" + +[[package]] +name = "wasmtime-cranelift" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe2e7532f1d6adbcc57e69bb6a7c503f0859076d07a9b4b6aabe8021ff8a05fd" +dependencies = [ + "anyhow", + "cfg-if", + "cranelift-codegen", + "cranelift-control", + "cranelift-entity", + "cranelift-frontend", + "cranelift-native", + "cranelift-wasm", + "gimli 0.28.1", + "log", + "object 0.32.1", + "target-lexicon", + "thiserror", + "wasmparser 0.116.1", + "wasmtime-cranelift-shared", + "wasmtime-environ", + "wasmtime-versioned-export-macros", +] + +[[package]] +name = "wasmtime-cranelift-shared" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c98d5378a856cbf058d36278627dfabf0ed68a888142958c7ae8e6af507dafa" +dependencies = [ + "anyhow", + "cranelift-codegen", + "cranelift-control", + "cranelift-native", + "gimli 0.28.1", + "object 0.32.1", + "target-lexicon", + "wasmtime-environ", +] + +[[package]] +name = "wasmtime-environ" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6d33a9f421da810a070cd56add9bc51f852bd66afbb8b920489d6242f15b70e" +dependencies = [ + "anyhow", + "cranelift-entity", + "gimli 0.28.1", + "indexmap 2.0.0", + "log", + "object 0.32.1", + "serde", + "serde_derive", + "target-lexicon", + "thiserror", + "wasmparser 0.116.1", + "wasmtime-types", +] + +[[package]] +name = "wasmtime-fiber" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "404741f4c6d7f4e043be2e8b466406a2aee289ccdba22bf9eba6399921121b97" +dependencies = [ + "anyhow", + "cc", + "cfg-if", + "rustix 0.38.25", + "wasmtime-asm-macros", + "wasmtime-versioned-export-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "wasmtime-jit" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d0994a86d6dca5f7d9740d7f2bd0568be06d2014a550361dc1c397d289d81ef" +dependencies = [ + "addr2line 0.21.0", + "anyhow", + "bincode", + "cfg-if", + "cpp_demangle", + "gimli 0.28.1", + "ittapi", + "log", + "object 0.32.1", + "rustc-demangle", + "rustix 0.38.25", + "serde", + "serde_derive", + "target-lexicon", + "wasmtime-environ", + "wasmtime-jit-debug", + "wasmtime-jit-icache-coherence", + "wasmtime-runtime", + "windows-sys 0.48.0", +] + +[[package]] +name = "wasmtime-jit-debug" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e0c4b74e606d1462d648631d5bc328e3d5b14e7f9d3ff93bc6db062fb8c5cd8" +dependencies = [ + "object 0.32.1", + "once_cell", + "rustix 0.38.25", + "wasmtime-versioned-export-macros", +] + +[[package]] +name = "wasmtime-jit-icache-coherence" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3090a69ba1476979e090aa7ed4bc759178bafdb65b22f98b9ba24fc6e7e578d5" +dependencies = [ + "cfg-if", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "wasmtime-runtime" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b993ac8380385ed67bf71b51b9553edcf1ab0801b78a805a067de581b9a3e88a" +dependencies = [ + "anyhow", + "cc", + "cfg-if", + "indexmap 2.0.0", + "libc", + "log", + "mach", + "memfd", + "memoffset 0.9.0", + "paste", + "rand 0.8.5", + "rustix 0.38.25", + "sptr", + "wasm-encoder 0.36.2", + "wasmtime-asm-macros", + "wasmtime-environ", + "wasmtime-fiber", + "wasmtime-jit-debug", + "wasmtime-versioned-export-macros", + "wasmtime-wmemcheck", + "windows-sys 0.48.0", +] + +[[package]] +name = "wasmtime-types" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b5778112fcab2dc3d4371f4203ab8facf0c453dd94312b0a88dd662955e64e0" +dependencies = [ + "cranelift-entity", + "serde", + "serde_derive", + "thiserror", + "wasmparser 0.116.1", +] + +[[package]] +name = "wasmtime-versioned-export-macros" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f50f51f8d79bfd2aa8e9d9a0ae7c2d02b45fe412e62ff1b87c0c81b07c738231" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "wasmtime-wit-bindgen" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b804dfd3d0c0d6d37aa21026fe7772ba1a769c89ee4f5c4f13b82d91d75216f" +dependencies = [ + "anyhow", + "heck 0.4.1", + "indexmap 2.0.0", + "wit-parser", +] + +[[package]] +name = "wasmtime-wmemcheck" +version = "15.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6060bc082cc32d9a45587c7640e29e3c7b89ada82677ac25d87850aaccb368" + +[[package]] +name = "wast" +version = "69.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ee37317321afde358e4d7593745942c48d6d17e0e6e943704de9bbee121e7a" +dependencies = [ + "leb128", + "memchr", + "unicode-width", + "wasm-encoder 0.38.1", +] + +[[package]] +name = "wat" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aeb338ee8dee4d4cd05e6426683f21c5087dc7cfc8903e839ccf48d43332da3c" +dependencies = [ + "wast", +] + [[package]] name = "web-sys" version = "0.3.61" @@ -4951,22 +6177,21 @@ dependencies = [ ] [[package]] -name = "webpki" -version = "0.22.2" +name = "webpki-roots" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ecc0cd7cac091bf682ec5efa18b1cff79d617b84181f38b3951dbe135f607f" -dependencies = [ - "ring", - "untrusted", -] +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] -name = "webpki-roots" -version = "0.22.6" +name = "which" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" dependencies = [ - "webpki", + "either", + "home", + "once_cell", + "rustix 0.38.25", ] [[package]] @@ -5002,26 +6227,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.44.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" -dependencies = [ - "windows-targets 0.42.1", -] - -[[package]] -name = "windows-sys" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows_aarch64_gnullvm 0.42.1", - "windows_aarch64_msvc 0.42.1", - "windows_i686_gnu 0.42.1", - "windows_i686_msvc 0.42.1", - "windows_x86_64_gnu 0.42.1", - "windows_x86_64_gnullvm 0.42.1", - "windows_x86_64_msvc 0.42.1", + "windows-targets 0.48.5", ] [[package]] @@ -5156,13 +6366,71 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "winnow" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wit-parser" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.0.0", + "log", + "semver 1.0.16", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", +] + +[[package]] +name = "wsts" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c250118354755b4abb091a83cb8d659b511c0ae211ccdb3b1254e3db199cb86" +dependencies = [ + "aes-gcm", + "bs58 0.5.0", + "hashbrown 0.14.0", + "hex 0.4.3", + "num-traits", + "p256k1", + "polynomial", + "primitive-types", + "rand_core 0.6.4", + "serde", + "sha2 0.10.6", + "thiserror", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", ] [[package]] @@ -5180,6 +6448,32 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +[[package]] +name = "yansi" +version = "1.0.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1367295b8f788d371ce2dbc842c7b709c73ee1364d30351dd300ec2203b12377" + +[[package]] +name = "zerocopy" +version = "0.7.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "zeroize" version = "1.5.7" @@ -5207,3 +6501,32 @@ dependencies = [ "libc", "metadeps", ] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.9+zstd.1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/components/clarinet-cli/Cargo.toml b/components/clarinet-cli/Cargo.toml index 6230df317..f88421780 100644 --- a/components/clarinet-cli/Cargo.toml +++ b/components/clarinet-cli/Cargo.toml @@ -27,12 +27,12 @@ serde_derive = "1" log = { version = "=0.4.17", features = ["serde"] } signal-hook-registry = "1.4.0" secure_tempfile = { version = "3.8.0", package = "tempfile" } -tokio-util = { version = "0.7.1", features = ["io"], optional = true } libsecp256k1 = "0.7.0" hmac = "0.12.0" pbkdf2 = { version = "0.12.2", features = ["simple"], default-features = false } futures = "0.3.12" -tokio = { version = "1.24", features = ["full"] } +tokio = { version = "1.35.1", features = ["full"] } +tokio-util = { version = "0.7.10", features = ["io"], optional = true } lazy_static = "1.4.0" atty = "0.2.14" termcolor = "1.1.2" @@ -47,7 +47,8 @@ reqwest = { version = "0.11", default-features = false, features = [ "json", "rustls-tls", ] } -crossterm = "0.22.1" +crossterm = "0.27.0" +ratatui = { version = "0.25.0", default-features = false, features = ["crossterm"] } base58 = "0.2.0" ctrlc = "3.1.9" strum = { version = "0.23.0", features = ["derive"] } @@ -75,11 +76,6 @@ hiro-system-kit = { path = "../hiro-system-kit" } clarinet-utils = { path = "../clarinet-utils" } stacks-network = { path = "../stacks-network" } -[dependencies.tui] -version = "0.18.0" -default-features = false -features = ["crossterm"] - [target.'cfg(unix)'.dependencies] nix = "=0.24.2" diff --git a/components/clarinet-cli/examples/swappool/settings/Devnet.toml b/components/clarinet-cli/examples/swappool/settings/Devnet.toml index ab225e935..209513788 100644 --- a/components/clarinet-cli/examples/swappool/settings/Devnet.toml +++ b/components/clarinet-cli/examples/swappool/settings/Devnet.toml @@ -121,7 +121,6 @@ disable_stacks_api = false # epoch_2_0 = 100 # epoch_2_05 = 102 # epoch_2_1 = 106 -# pox_2_activation = 109 # Send some stacking orders diff --git a/components/clarinet-cli/src/deployments/ui/app.rs b/components/clarinet-cli/src/deployments/ui/app.rs index b63647efc..9873d6716 100644 --- a/components/clarinet-cli/src/deployments/ui/app.rs +++ b/components/clarinet-cli/src/deployments/ui/app.rs @@ -1,5 +1,5 @@ use clarinet_deployments::onchain::TransactionTracker; -use tui::widgets::ListState; +use ratatui::widgets::ListState; pub struct StatefulList { pub state: ListState, diff --git a/components/clarinet-cli/src/deployments/ui/mod.rs b/components/clarinet-cli/src/deployments/ui/mod.rs index bb61eb4c2..4fd9ad941 100644 --- a/components/clarinet-cli/src/deployments/ui/mod.rs +++ b/components/clarinet-cli/src/deployments/ui/mod.rs @@ -10,9 +10,9 @@ use crossterm::{ execute, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, }; +use ratatui::{backend::CrosstermBackend, Terminal}; use std::io::stdout; use std::sync::mpsc::Receiver; -use tui::{backend::CrosstermBackend, Terminal}; pub fn start_ui( node_url: &str, diff --git a/components/clarinet-cli/src/deployments/ui/ui.rs b/components/clarinet-cli/src/deployments/ui/ui.rs index 7b8f5ca64..264dce218 100644 --- a/components/clarinet-cli/src/deployments/ui/ui.rs +++ b/components/clarinet-cli/src/deployments/ui/ui.rs @@ -1,22 +1,18 @@ use clarinet_deployments::onchain::TransactionStatus; use super::App; -use tui::{ - backend::Backend, +use ratatui::{ layout::{Constraint, Rect}, style::{Color, Style}, widgets::{Block, Cell, Row, Table}, Frame, }; -pub fn draw(f: &mut Frame, app: &mut App) { +pub fn draw(f: &mut Frame, app: &mut App) { draw_contracts_status(f, app, f.size()); } -fn draw_contracts_status(f: &mut Frame, app: &mut App, area: Rect) -where - B: Backend, -{ +fn draw_contracts_status(f: &mut Frame, app: &mut App, area: Rect) { let rows = app.transactions.items.iter().map(|tx| { let (status, default_comment) = match &tx.status { TransactionStatus::Queued => ("🟪", "Transaction indexed".to_string()), @@ -39,10 +35,10 @@ where .bottom_margin(0) }); - let t = Table::new(rows) + let t = Table::new(rows, vec![] as Vec<&Constraint>) .block(Block::default().title(format!("Broadcasting transactions to {}", app.node_url))) .style(Style::default().fg(Color::White)) - .widths(&[ + .widths([ Constraint::Length(3), Constraint::Length(90), Constraint::Length(110), diff --git a/components/clarinet-cli/src/frontend/cli.rs b/components/clarinet-cli/src/frontend/cli.rs index 94c6d4751..1883c7955 100644 --- a/components/clarinet-cli/src/frontend/cli.rs +++ b/components/clarinet-cli/src/frontend/cli.rs @@ -1081,12 +1081,13 @@ pub fn main() { } }; let contract_id = QualifiedContractIdentifier::transient(); + let epoch = DEFAULT_EPOCH; let contract = ClarityContract { code_source: ClarityCodeSource::ContractInMemory(code_source), deployer: ContractDeployer::Transient, name: "transient".to_string(), - clarity_version: ClarityVersion::Clarity1, - epoch: DEFAULT_EPOCH, + clarity_version: ClarityVersion::default_for_epoch(epoch), + epoch, }; let (ast, mut diagnostics, mut success) = session.interpreter.build_ast(&contract); let (annotations, mut annotation_diagnostics) = session diff --git a/components/clarinet-cli/src/generate/mod.rs b/components/clarinet-cli/src/generate/mod.rs index aa29f352f..55184e93c 100644 --- a/components/clarinet-cli/src/generate/mod.rs +++ b/components/clarinet-cli/src/generate/mod.rs @@ -4,7 +4,7 @@ mod contract; mod project; use chainhook::GetChangesForNewChainhook; -pub use changes::{Changes, DirectoryCreation, FileCreation, TOMLEdition}; +pub use changes::Changes; use clarinet_files::chainhook_types::Chain; use clarinet_files::FileLocation; use contract::GetChangesForNewContract; diff --git a/components/clarinet-cli/src/generate/project.rs b/components/clarinet-cli/src/generate/project.rs index 9ac51dc9a..cbf94f83b 100644 --- a/components/clarinet-cli/src/generate/project.rs +++ b/components/clarinet-cli/src/generate/project.rs @@ -1,10 +1,10 @@ use clarinet_files::{ DEFAULT_BITCOIN_EXPLORER_IMAGE, DEFAULT_BITCOIN_NODE_IMAGE, DEFAULT_DERIVATION_PATH, DEFAULT_EPOCH_2_0, DEFAULT_EPOCH_2_05, DEFAULT_EPOCH_2_1, DEFAULT_EPOCH_2_2, DEFAULT_EPOCH_2_3, - DEFAULT_EPOCH_2_4, DEFAULT_FAUCET_MNEMONIC, DEFAULT_POSTGRES_IMAGE, DEFAULT_POX2_ACTIVATION, - DEFAULT_STACKS_API_IMAGE, DEFAULT_STACKS_EXPLORER_IMAGE, DEFAULT_STACKS_MINER_MNEMONIC, - DEFAULT_STACKS_NODE_IMAGE, DEFAULT_SUBNET_API_IMAGE, DEFAULT_SUBNET_CONTRACT_ID, - DEFAULT_SUBNET_MNEMONIC, DEFAULT_SUBNET_NODE_IMAGE, + DEFAULT_EPOCH_2_4, DEFAULT_EPOCH_2_5, DEFAULT_EPOCH_3_0, DEFAULT_FAUCET_MNEMONIC, + DEFAULT_POSTGRES_IMAGE, DEFAULT_STACKS_API_IMAGE, DEFAULT_STACKS_EXPLORER_IMAGE, + DEFAULT_STACKS_MINER_MNEMONIC, DEFAULT_STACKS_NODE_IMAGE, DEFAULT_SUBNET_API_IMAGE, + DEFAULT_SUBNET_CONTRACT_ID, DEFAULT_SUBNET_MNEMONIC, DEFAULT_SUBNET_NODE_IMAGE, }; use super::changes::{Changes, DirectoryCreation, FileCreation}; @@ -403,32 +403,33 @@ disable_stacks_api = false # subnet_api_postgres_database = "subnet_api" # For testing in epoch 2.1 / using Clarity2 -# epoch_2_0 = {default_epoch_2_0} -# epoch_2_05 = {default_epoch_2_05} -# epoch_2_1 = {default_epoch_2_1} -# pox_2_activation = {default_pox2_activation} -# epoch_2_2 = {default_epoch_2_2} -# epoch_2_3 = {default_epoch_2_3} -# epoch_2_4 = {default_epoch_2_4} +# epoch_2_0 = {DEFAULT_EPOCH_2_0} +# epoch_2_05 = {DEFAULT_EPOCH_2_05} +# epoch_2_1 = {DEFAULT_EPOCH_2_1} +# epoch_2_2 = {DEFAULT_EPOCH_2_2} +# epoch_2_3 = {DEFAULT_EPOCH_2_3} +# epoch_2_4 = {DEFAULT_EPOCH_2_4} +# epoch_2_5 = {DEFAULT_EPOCH_2_5} +# epoch_3_0 = {DEFAULT_EPOCH_3_0} # Send some stacking orders [[devnet.pox_stacking_orders]] -start_at_cycle = 3 +start_at_cycle = 0 duration = 12 wallet = "wallet_1" slots = 2 btc_address = "mr1iPkD9N3RJZZxXRk7xF9d36gffa6exNC" [[devnet.pox_stacking_orders]] -start_at_cycle = 3 +start_at_cycle = 1 duration = 12 wallet = "wallet_2" slots = 1 btc_address = "muYdXKmX9bByAueDe6KFfHd5Ff1gdN9ErG" [[devnet.pox_stacking_orders]] -start_at_cycle = 3 +start_at_cycle = 2 duration = 12 wallet = "wallet_3" slots = 1 @@ -447,13 +448,6 @@ btc_address = "mvZtbibDAAA3WLpY7zXXFqRa3T4XSknBX7" default_subnet_api_image = DEFAULT_SUBNET_API_IMAGE, default_stacks_miner_mnemonic = DEFAULT_STACKS_MINER_MNEMONIC, default_stacks_faucet_mnemonic = DEFAULT_FAUCET_MNEMONIC, - default_epoch_2_0 = DEFAULT_EPOCH_2_0, - default_epoch_2_05 = DEFAULT_EPOCH_2_05, - default_epoch_2_1 = DEFAULT_EPOCH_2_1, - default_pox2_activation = DEFAULT_POX2_ACTIVATION, - default_epoch_2_2 = DEFAULT_EPOCH_2_2, - default_epoch_2_3 = DEFAULT_EPOCH_2_3, - default_epoch_2_4 = DEFAULT_EPOCH_2_4, ); let name = "Devnet.toml".into(); let path = format!( diff --git a/components/clarinet-deployments/src/lib.rs b/components/clarinet-deployments/src/lib.rs index 20e1c5148..13861a275 100644 --- a/components/clarinet-deployments/src/lib.rs +++ b/components/clarinet-deployments/src/lib.rs @@ -1,4 +1,4 @@ -use clarity_repl::clarity::stacks_common::types::StacksEpochId; +use clarity_repl::clarity::StacksEpochId; use clarity_repl::repl::{ClarityCodeSource, ClarityContract, ContractDeployer}; use clarity_repl::repl::{DEFAULT_CLARITY_VERSION, DEFAULT_EPOCH}; @@ -119,10 +119,10 @@ pub fn update_session_with_contracts_executions( ) -> BTreeMap>> { let boot_contracts_data = BOOT_CONTRACTS_DATA.clone(); - for (_, (boot_contract, mut ast)) in boot_contracts_data { + for (_, (boot_contract, ast)) in boot_contracts_data { session .interpreter - .run_ast(&boot_contract, &mut ast, &mut vec![], true, false, None) + .run(&boot_contract, &mut Some(ast), false, None) .expect("failed to interprete boot contract"); } diff --git a/components/clarinet-deployments/src/onchain/mod.rs b/components/clarinet-deployments/src/onchain/mod.rs index 9d7e29537..a4f89b5e7 100644 --- a/components/clarinet-deployments/src/onchain/mod.rs +++ b/components/clarinet-deployments/src/onchain/mod.rs @@ -2,8 +2,8 @@ use bitcoincore_rpc::{Auth, Client}; use clarinet_files::chainhook_types::StacksNetwork; use clarinet_files::{AccountConfig, NetworkManifest}; use clarinet_utils::get_bip39_seed_from_mnemonic; +use clarity_repl::clarity::chainstate::StacksAddress; use clarity_repl::clarity::codec::StacksMessageCodec; -use clarity_repl::clarity::stacks_common::types::chainstate::StacksAddress; use clarity_repl::clarity::util::secp256k1::{ MessageSignature, Secp256k1PrivateKey, Secp256k1PublicKey, }; @@ -537,9 +537,7 @@ pub fn apply_on_chain_deployment( let _ = deployment_event_tx.send(DeploymentEvent::Interrupted(format!( "unable to encode contract_call {}::{} ({})", - tx.contract_id.to_string(), - tx.method, - e + tx.contract_id, tx.method, e ))); return; } @@ -548,7 +546,7 @@ pub fn apply_on_chain_deployment( accounts_cached_nonces.insert(issuer_address.clone(), nonce + 1); let name = format!( "Call ({} {} {})", - tx.contract_id.to_string(), + tx.contract_id, tx.method, tx.parameters.join(" ") ); @@ -758,6 +756,8 @@ pub fn apply_on_chain_deployment( EpochSpec::Epoch2_2 => network_manifest.devnet.as_ref().unwrap().epoch_2_2, EpochSpec::Epoch2_3 => network_manifest.devnet.as_ref().unwrap().epoch_2_3, EpochSpec::Epoch2_4 => network_manifest.devnet.as_ref().unwrap().epoch_2_4, + EpochSpec::Epoch2_5 => network_manifest.devnet.as_ref().unwrap().epoch_2_5, + EpochSpec::Epoch3_0 => network_manifest.devnet.as_ref().unwrap().epoch_3_0, }; let mut epoch_transition_successful = current_bitcoin_block_height > after_bitcoin_block; diff --git a/components/clarinet-deployments/src/requirements.rs b/components/clarinet-deployments/src/requirements.rs index 3161f00ae..337ce96d5 100644 --- a/components/clarinet-deployments/src/requirements.rs +++ b/components/clarinet-deployments/src/requirements.rs @@ -1,6 +1,8 @@ use clarinet_files::{FileAccessor, FileLocation}; -use clarity_repl::clarity::stacks_common::types::StacksEpochId; -use clarity_repl::clarity::{vm::types::QualifiedContractIdentifier, ClarityVersion}; +use clarity_repl::{ + clarity::{vm::types::QualifiedContractIdentifier, ClarityVersion, StacksEpochId}, + repl::{DEFAULT_CLARITY_VERSION, DEFAULT_EPOCH}, +}; use reqwest; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -12,8 +14,8 @@ pub struct ContractMetadata { impl Default for ContractMetadata { fn default() -> Self { ContractMetadata { - epoch: StacksEpochId::latest(), - clarity_version: ClarityVersion::latest(), + epoch: DEFAULT_EPOCH, + clarity_version: DEFAULT_CLARITY_VERSION, } } } @@ -119,6 +121,9 @@ pub const MAINNET_21_START_HEIGHT: u32 = 99_113; pub const MAINNET_22_START_HEIGHT: u32 = 103_900; pub const MAINNET_23_START_HEIGHT: u32 = 104_359; pub const MAINNET_24_START_HEIGHT: u32 = 107_055; +// @TODO: set right heights once epochs are live on mainnet +pub const MAINNET_25_START_HEIGHT: u32 = 200_000; +pub const MAINNET_30_START_HEIGHT: u32 = 300_000; pub const TESTNET_20_START_HEIGHT: u32 = 1; pub const TESTNET_2_05_START_HEIGHT: u32 = 20_216; @@ -126,6 +131,9 @@ pub const TESTNET_21_START_HEIGHT: u32 = 99_113; pub const TESTNET_22_START_HEIGHT: u32 = 105_923; pub const TESTNET_23_START_HEIGHT: u32 = 106_196; pub const TESTNET_24_START_HEIGHT: u32 = 106_979; +// @TODO: set right heights once epochs are live on testnet +pub const TESTNET_25_START_HEIGHT: u32 = 200_000; +pub const TESTNET_30_START_HEIGHT: u32 = 300_000; fn epoch_for_height(is_mainnet: bool, height: u32) -> StacksEpochId { if is_mainnet { @@ -146,8 +154,12 @@ fn epoch_for_mainnet_height(height: u32) -> StacksEpochId { StacksEpochId::Epoch22 } else if height < MAINNET_24_START_HEIGHT { StacksEpochId::Epoch23 - } else { + } else if height < MAINNET_25_START_HEIGHT { StacksEpochId::Epoch24 + } else if height < MAINNET_30_START_HEIGHT { + StacksEpochId::Epoch25 + } else { + StacksEpochId::Epoch30 } } @@ -162,8 +174,12 @@ fn epoch_for_testnet_height(height: u32) -> StacksEpochId { StacksEpochId::Epoch22 } else if height < TESTNET_24_START_HEIGHT { StacksEpochId::Epoch23 - } else { + } else if height < TESTNET_25_START_HEIGHT { StacksEpochId::Epoch24 + } else if height < TESTNET_30_START_HEIGHT { + StacksEpochId::Epoch25 + } else { + StacksEpochId::Epoch30 } } diff --git a/components/clarinet-deployments/src/types.rs b/components/clarinet-deployments/src/types.rs index 959c21658..d9d6135fe 100644 --- a/components/clarinet-deployments/src/types.rs +++ b/components/clarinet-deployments/src/types.rs @@ -1,5 +1,5 @@ +use clarinet_files::chainhook_types::StacksNetwork; use clarinet_files::FileLocation; -use clarity_repl::clarity::stacks_common::types::StacksEpochId; use clarity_repl::clarity::util::hash::{hex_bytes, to_hex}; use clarity_repl::clarity::vm::analysis::ContractAnalysis; use clarity_repl::clarity::vm::ast::ContractAST; @@ -8,9 +8,8 @@ use clarity_repl::clarity::vm::types::{ PrincipalData, QualifiedContractIdentifier, StandardPrincipalData, }; -use clarinet_files::chainhook_types::StacksNetwork; use clarity_repl::analysis::ast_dependency_detector::DependencySet; -use clarity_repl::clarity::{ClarityName, ClarityVersion, ContractName}; +use clarity_repl::clarity::{ClarityName, ClarityVersion, ContractName, StacksEpochId}; use clarity_repl::repl::{Session, DEFAULT_CLARITY_VERSION}; use serde::{Deserialize, Serialize}; use serde_yaml; @@ -31,6 +30,10 @@ pub enum EpochSpec { Epoch2_3, #[serde(rename = "2.4")] Epoch2_4, + #[serde(rename = "2.5")] + Epoch2_5, + #[serde(rename = "3.0")] + Epoch3_0, } impl From for EpochSpec { @@ -42,6 +45,8 @@ impl From for EpochSpec { StacksEpochId::Epoch22 => EpochSpec::Epoch2_2, StacksEpochId::Epoch23 => EpochSpec::Epoch2_3, StacksEpochId::Epoch24 => EpochSpec::Epoch2_4, + StacksEpochId::Epoch25 => EpochSpec::Epoch2_5, + StacksEpochId::Epoch30 => EpochSpec::Epoch3_0, StacksEpochId::Epoch10 => unreachable!("epoch 1.0 is not supported"), } } @@ -56,6 +61,8 @@ impl From for StacksEpochId { EpochSpec::Epoch2_2 => StacksEpochId::Epoch22, EpochSpec::Epoch2_3 => StacksEpochId::Epoch23, EpochSpec::Epoch2_4 => StacksEpochId::Epoch24, + EpochSpec::Epoch2_5 => StacksEpochId::Epoch25, + EpochSpec::Epoch3_0 => StacksEpochId::Epoch30, } } } diff --git a/components/clarinet-files/Cargo.toml b/components/clarinet-files/Cargo.toml index da0e9ce7a..d19e5ded3 100644 --- a/components/clarinet-files/Cargo.toml +++ b/components/clarinet-files/Cargo.toml @@ -8,8 +8,8 @@ edition = "2021" [dependencies] serde = "1" serde_derive = "1" -chainhook-types = "1.2" -# chainhook-types = { version = "=1.2", path = "../../../chainhook/components/chainhook-types-rs" } +# chainhook-types = "1.2" +chainhook-types = { version = "1.2", git = "https://github.com/hirosystems/chainhook.git", rev="a938e61846a430750ad31d84b2032efabf6d039f" } bip39 = { version = "1.0.1", default-features = false } libsecp256k1 = "0.7.0" toml = { version = "0.5.6", features = ["preserve_order"] } diff --git a/components/clarinet-files/src/lib.rs b/components/clarinet-files/src/lib.rs index 7dc1f085c..34608a617 100644 --- a/components/clarinet-files/src/lib.rs +++ b/components/clarinet-files/src/lib.rs @@ -22,9 +22,10 @@ pub use network_manifest::{ NetworkManifestFile, PoxStackingOrder, DEFAULT_BITCOIN_EXPLORER_IMAGE, DEFAULT_BITCOIN_NODE_IMAGE, DEFAULT_DERIVATION_PATH, DEFAULT_DOCKER_PLATFORM, DEFAULT_EPOCH_2_0, DEFAULT_EPOCH_2_05, DEFAULT_EPOCH_2_1, DEFAULT_EPOCH_2_2, DEFAULT_EPOCH_2_3, - DEFAULT_EPOCH_2_4, DEFAULT_FAUCET_MNEMONIC, DEFAULT_POSTGRES_IMAGE, DEFAULT_POX2_ACTIVATION, - DEFAULT_STACKS_API_IMAGE, DEFAULT_STACKS_EXPLORER_IMAGE, DEFAULT_STACKS_MINER_MNEMONIC, - DEFAULT_STACKS_NODE_IMAGE, DEFAULT_SUBNET_API_IMAGE, DEFAULT_SUBNET_CONTRACT_ID, + DEFAULT_EPOCH_2_4, DEFAULT_EPOCH_2_5, DEFAULT_EPOCH_3_0, DEFAULT_FAUCET_MNEMONIC, + DEFAULT_POSTGRES_IMAGE, DEFAULT_STACKS_API_IMAGE, DEFAULT_STACKS_API_IMAGE_NAKA, + DEFAULT_STACKS_EXPLORER_IMAGE, DEFAULT_STACKS_MINER_MNEMONIC, DEFAULT_STACKS_NODE_IMAGE, + DEFAULT_STACKS_NODE_IMAGE_NAKA, DEFAULT_SUBNET_API_IMAGE, DEFAULT_SUBNET_CONTRACT_ID, DEFAULT_SUBNET_MNEMONIC, DEFAULT_SUBNET_NODE_IMAGE, }; pub use project_manifest::{ diff --git a/components/clarinet-files/src/network_manifest.rs b/components/clarinet-files/src/network_manifest.rs index 1b5afb876..e6d20d960 100644 --- a/components/clarinet-files/src/network_manifest.rs +++ b/components/clarinet-files/src/network_manifest.rs @@ -4,22 +4,26 @@ use super::{FileAccessor, FileLocation}; use bip39::{Language, Mnemonic}; use chainhook_types::{BitcoinNetwork, StacksNetwork}; use clarinet_utils::get_bip39_seed_from_mnemonic; -use clarity_repl::clarity::address::AddressHashMode; -use clarity_repl::clarity::stacks_common::types::chainstate::StacksAddress; use clarity_repl::clarity::util::hash::bytes_to_hex; use clarity_repl::clarity::util::secp256k1::Secp256k1PublicKey; use clarity_repl::clarity::vm::types::QualifiedContractIdentifier; +use clarity_repl::clarity::{address::AddressHashMode, chainstate::StacksAddress}; use libsecp256k1::{PublicKey, SecretKey}; use tiny_hderive::bip32::ExtendedPrivKey; use toml::value::Value; pub const DEFAULT_DERIVATION_PATH: &str = "m/44'/5757'/0'/0/0"; -pub const DEFAULT_BITCOIN_NODE_IMAGE: &str = "quay.io/hirosystems/bitcoind:devnet-v3"; + pub const DEFAULT_STACKS_NODE_IMAGE: &str = "quay.io/hirosystems/stacks-node:devnet-2.4.0.0.0"; -pub const DEFAULT_BITCOIN_EXPLORER_IMAGE: &str = "quay.io/hirosystems/bitcoin-explorer:devnet"; pub const DEFAULT_STACKS_API_IMAGE: &str = "hirosystems/stacks-blockchain-api:latest"; +// Nakamoto images overrides +pub const DEFAULT_STACKS_NODE_IMAGE_NAKA: &str = "blockstack/stacks-blockchain:next-devnet"; +pub const DEFAULT_STACKS_API_IMAGE_NAKA: &str = "hirosystems/stacks-blockchain-api:nakamoto"; + +pub const DEFAULT_BITCOIN_NODE_IMAGE: &str = "quay.io/hirosystems/bitcoind:26.0"; +pub const DEFAULT_BITCOIN_EXPLORER_IMAGE: &str = "quay.io/hirosystems/bitcoin-explorer:devnet"; pub const DEFAULT_STACKS_EXPLORER_IMAGE: &str = "hirosystems/explorer:latest"; -pub const DEFAULT_POSTGRES_IMAGE: &str = "postgres:14"; +pub const DEFAULT_POSTGRES_IMAGE: &str = "postgres:alpine"; pub const DEFAULT_SUBNET_NODE_IMAGE: &str = "hirosystems/stacks-subnets:0.8.1"; pub const DEFAULT_SUBNET_API_IMAGE: &str = "hirosystems/stacks-blockchain-api:latest"; pub const DEFAULT_SUBNET_CONTRACT_ID: &str = @@ -38,10 +42,11 @@ pub const DEFAULT_DOCKER_PLATFORM: &str = "linux/amd64"; pub const DEFAULT_EPOCH_2_0: u64 = 100; pub const DEFAULT_EPOCH_2_05: u64 = 100; pub const DEFAULT_EPOCH_2_1: u64 = 101; -pub const DEFAULT_POX2_ACTIVATION: u64 = 102; -pub const DEFAULT_EPOCH_2_2: u64 = 103; -pub const DEFAULT_EPOCH_2_3: u64 = 104; -pub const DEFAULT_EPOCH_2_4: u64 = 105; +pub const DEFAULT_EPOCH_2_2: u64 = 102; +pub const DEFAULT_EPOCH_2_3: u64 = 103; +pub const DEFAULT_EPOCH_2_4: u64 = 104; +pub const DEFAULT_EPOCH_2_5: u64 = 105; +pub const DEFAULT_EPOCH_3_0: u64 = 121; #[derive(Serialize, Deserialize, Debug)] pub struct NetworkManifestFile { @@ -87,6 +92,7 @@ pub struct DevnetConfigFile { pub miner_mnemonic: Option, pub miner_derivation_path: Option, pub miner_coinbase_recipient: Option, + pub miner_wallet_name: Option, pub faucet_mnemonic: Option, pub faucet_derivation_path: Option, pub bitcoin_controller_block_time: Option, @@ -131,9 +137,11 @@ pub struct DevnetConfigFile { pub epoch_2_2: Option, pub epoch_2_3: Option, pub epoch_2_4: Option, - pub pox_2_activation: Option, + pub epoch_2_5: Option, + pub epoch_3_0: Option, pub use_docker_gateway_routing: Option, pub docker_platform: Option, + pub use_nakamoto: Option, } #[derive(Serialize, Deserialize, Debug)] @@ -243,6 +251,7 @@ pub struct DevnetConfig { pub miner_mnemonic: String, pub miner_derivation_path: String, pub miner_coinbase_recipient: String, + pub miner_wallet_name: String, pub faucet_stx_address: String, pub faucet_secret_key_hex: String, pub faucet_btc_address: String, @@ -293,9 +302,11 @@ pub struct DevnetConfig { pub epoch_2_2: u64, pub epoch_2_3: u64, pub epoch_2_4: u64, - pub pox_2_activation: u64, + pub epoch_2_5: u64, + pub epoch_3_0: u64, pub use_docker_gateway_routing: bool, pub docker_platform: String, + pub use_nakamoto: bool, } #[derive(Serialize, Deserialize, Debug, Clone)] @@ -663,8 +674,12 @@ impl NetworkManifest { devnet_config.epoch_2_4 = Some(*val); } - if let Some(ref val) = devnet_override.pox_2_activation { - devnet_config.pox_2_activation = Some(*val); + if let Some(ref val) = devnet_override.epoch_2_5 { + devnet_config.epoch_2_5 = Some(*val); + } + + if let Some(ref val) = devnet_override.epoch_3_0 { + devnet_config.epoch_3_0 = Some(*val); } if let Some(val) = devnet_override.network_id { @@ -800,6 +815,7 @@ impl NetworkManifest { miner_coinbase_recipient: devnet_config .miner_coinbase_recipient .unwrap_or(miner_stx_address), + miner_wallet_name: devnet_config.miner_wallet_name.unwrap_or("".to_string()), faucet_btc_address, faucet_stx_address, faucet_mnemonic, @@ -831,14 +847,24 @@ impl NetworkManifest { .bitcoin_node_image_url .take() .unwrap_or(DEFAULT_BITCOIN_NODE_IMAGE.to_string()), - stacks_node_image_url: devnet_config - .stacks_node_image_url - .take() - .unwrap_or(DEFAULT_STACKS_NODE_IMAGE.to_string()), - stacks_api_image_url: devnet_config - .stacks_api_image_url - .take() - .unwrap_or(DEFAULT_STACKS_API_IMAGE.to_string()), + stacks_node_image_url: devnet_config.stacks_node_image_url.take().unwrap_or_else( + || { + if devnet_config.use_nakamoto.unwrap_or(false) { + DEFAULT_STACKS_NODE_IMAGE_NAKA.to_string() + } else { + DEFAULT_STACKS_NODE_IMAGE.to_string() + } + }, + ), + stacks_api_image_url: devnet_config.stacks_api_image_url.take().unwrap_or_else( + || { + if devnet_config.use_nakamoto.unwrap_or(false) { + DEFAULT_STACKS_API_IMAGE_NAKA.to_string() + } else { + DEFAULT_STACKS_API_IMAGE.to_string() + } + }, + ), postgres_image_url: devnet_config .postgres_image_url .take() @@ -894,9 +920,8 @@ impl NetworkManifest { epoch_2_2: devnet_config.epoch_2_2.unwrap_or(DEFAULT_EPOCH_2_2), epoch_2_3: devnet_config.epoch_2_3.unwrap_or(DEFAULT_EPOCH_2_3), epoch_2_4: devnet_config.epoch_2_4.unwrap_or(DEFAULT_EPOCH_2_4), - pox_2_activation: devnet_config - .pox_2_activation - .unwrap_or(DEFAULT_POX2_ACTIVATION), + epoch_2_5: devnet_config.epoch_2_5.unwrap_or(DEFAULT_EPOCH_2_5), + epoch_3_0: devnet_config.epoch_3_0.unwrap_or(DEFAULT_EPOCH_3_0), stacks_node_env_vars: devnet_config.stacks_node_env_vars.take().unwrap_or(vec![]), stacks_api_env_vars: devnet_config.stacks_api_env_vars.take().unwrap_or(vec![]), stacks_explorer_env_vars: devnet_config @@ -911,6 +936,7 @@ impl NetworkManifest { docker_platform: devnet_config .docker_platform .unwrap_or(DEFAULT_DOCKER_PLATFORM.to_string()), + use_nakamoto: devnet_config.use_nakamoto.unwrap_or(false), }; Some(config) } else { diff --git a/components/clarinet-files/src/project_manifest.rs b/components/clarinet-files/src/project_manifest.rs index ad2888393..d263851e8 100644 --- a/components/clarinet-files/src/project_manifest.rs +++ b/components/clarinet-files/src/project_manifest.rs @@ -1,8 +1,7 @@ use crate::FileAccessor; use super::FileLocation; -use clarity_repl::clarity::stacks_common::types::StacksEpochId; -use clarity_repl::clarity::ClarityVersion; +use clarity_repl::clarity::{ClarityVersion, StacksEpochId}; use clarity_repl::repl; use clarity_repl::repl::{ClarityCodeSource, ClarityContract, ContractDeployer}; use serde::ser::SerializeMap; @@ -113,6 +112,10 @@ where StacksEpochId::Epoch23 } else if epoch.eq("2.4") { StacksEpochId::Epoch24 + } else if epoch.eq("2.5") { + StacksEpochId::Epoch25 + } else if epoch.eq("3.0") { + StacksEpochId::Epoch30 } else { return Err(serde::de::Error::custom(INVALID_EPOCH)); } @@ -131,6 +134,10 @@ where StacksEpochId::Epoch23 } else if epoch.eq(&2.4) { StacksEpochId::Epoch24 + } else if epoch.eq(&2.5) { + StacksEpochId::Epoch25 + } else if epoch.eq(&3.0) { + StacksEpochId::Epoch30 } else { return Err(serde::de::Error::custom(INVALID_EPOCH)); } @@ -302,6 +309,7 @@ impl ProjectManifest { "pox".to_string(), "pox-2".to_string(), "pox-3".to_string(), + "pox-4".to_string(), "lockup".to_string(), "costs-2".to_string(), "costs-3".to_string(), @@ -411,6 +419,10 @@ fn get_epoch_and_clarity_version( StacksEpochId::Epoch23 } else if epoch.eq("2.4") { StacksEpochId::Epoch24 + } else if epoch.eq("2.5") { + StacksEpochId::Epoch25 + } else if epoch.eq("3.0") { + StacksEpochId::Epoch30 } else { return Err(INVALID_EPOCH.into()); } @@ -428,6 +440,10 @@ fn get_epoch_and_clarity_version( StacksEpochId::Epoch23 } else if epoch.eq(&2.4) { StacksEpochId::Epoch24 + } else if epoch.eq(&2.5) { + StacksEpochId::Epoch25 + } else if epoch.eq(&3.0) { + StacksEpochId::Epoch30 } else { return Err(INVALID_EPOCH.into()); } diff --git a/components/clarinet-sdk-wasm/src/core.rs b/components/clarinet-sdk-wasm/src/core.rs index 9f7f10c27..da6fd3df4 100644 --- a/components/clarinet-sdk-wasm/src/core.rs +++ b/components/clarinet-sdk-wasm/src/core.rs @@ -10,9 +10,10 @@ use clarity_repl::analysis::coverage::CoverageReporter; use clarity_repl::clarity::analysis::contract_interface_builder::{ ContractInterface, ContractInterfaceFunction, ContractInterfaceFunctionAccess, }; -use clarity_repl::clarity::stacks_common::types::StacksEpochId; use clarity_repl::clarity::vm::types::QualifiedContractIdentifier; -use clarity_repl::clarity::{ClarityVersion, EvaluationResult, ExecutionResult, ParsedContract}; +use clarity_repl::clarity::{ + ClarityVersion, EvaluationResult, ExecutionResult, ParsedContract, StacksEpochId, +}; use clarity_repl::repl::{ ClarityCodeSource, ClarityContract, ContractDeployer, Session, DEFAULT_CLARITY_VERSION, DEFAULT_EPOCH, @@ -409,6 +410,8 @@ impl SDK { "2.2" => StacksEpochId::Epoch22, "2.3" => StacksEpochId::Epoch23, "2.4" => StacksEpochId::Epoch24, + "2.5" => StacksEpochId::Epoch25, + "3.0" => StacksEpochId::Epoch30, _ => { log!("Invalid epoch {epoch}. Using default epoch"); DEFAULT_EPOCH diff --git a/components/clarinet-sdk/clarinet-sdk.code-workspace b/components/clarinet-sdk/clarinet-sdk.code-workspace index 81e627f4a..57fa45a0f 100644 --- a/components/clarinet-sdk/clarinet-sdk.code-workspace +++ b/components/clarinet-sdk/clarinet-sdk.code-workspace @@ -9,6 +9,7 @@ "--no-default-features", "--package=clarinet-sdk-wasm", "--features=wasm", + "--target=wasm32-unknown-unknown", "--message-format=json" ] } diff --git a/components/clarinet-sdk/tests/fixtures/settings/Devnet.toml b/components/clarinet-sdk/tests/fixtures/settings/Devnet.toml index aee512ed3..6f3d595a4 100644 --- a/components/clarinet-sdk/tests/fixtures/settings/Devnet.toml +++ b/components/clarinet-sdk/tests/fixtures/settings/Devnet.toml @@ -38,10 +38,9 @@ disable_stacks_api = false # epoch_2_0 = 100 # epoch_2_05 = 100 # epoch_2_1 = 101 -# pox_2_activation = 102 -# epoch_2_2 = 103 -# epoch_2_3 = 104 -# epoch_2_4 = 105 +# epoch_2_2 = 102 +# epoch_2_3 = 103 +# epoch_2_4 = 104 # Send some stacking orders [[devnet.pox_stacking_orders]] diff --git a/components/clarity-lsp/src/common/requests/completion.rs b/components/clarity-lsp/src/common/requests/completion.rs index 233f709ef..ab8672d41 100644 --- a/components/clarity-lsp/src/common/requests/completion.rs +++ b/components/clarity-lsp/src/common/requests/completion.rs @@ -772,8 +772,8 @@ fn get_iterator_cb_completion_item(version: &ClarityVersion, func: &str) -> Vec< #[cfg(test)] mod get_contract_global_data_tests { use clarity_repl::clarity::ast::build_ast_with_rules; - use clarity_repl::clarity::stacks_common::types::StacksEpochId; - use clarity_repl::clarity::{vm::types::QualifiedContractIdentifier, ClarityVersion}; + use clarity_repl::clarity::vm::types::QualifiedContractIdentifier; + use clarity_repl::clarity::{ClarityVersion, StacksEpochId}; use lsp_types::Position; use super::ContractDefinedData; @@ -821,7 +821,7 @@ mod get_contract_global_data_tests { #[cfg(test)] mod get_contract_local_data_tests { use clarity_repl::clarity::ast::build_ast_with_rules; - use clarity_repl::clarity::stacks_common::types::StacksEpochId; + use clarity_repl::clarity::StacksEpochId; use clarity_repl::clarity::{vm::types::QualifiedContractIdentifier, ClarityVersion}; use lsp_types::Position; @@ -876,8 +876,8 @@ mod get_contract_local_data_tests { #[cfg(test)] mod populate_snippet_with_options_tests { use clarity_repl::clarity::ast::build_ast_with_rules; - use clarity_repl::clarity::stacks_common::types::StacksEpochId; - use clarity_repl::clarity::{vm::types::QualifiedContractIdentifier, ClarityVersion}; + use clarity_repl::clarity::vm::types::QualifiedContractIdentifier; + use clarity_repl::clarity::{ClarityVersion, StacksEpochId}; use lsp_types::Position; use super::ContractDefinedData; diff --git a/components/clarity-lsp/src/common/requests/definitions.rs b/components/clarity-lsp/src/common/requests/definitions.rs index e038c0cb5..d2e6fe4e3 100644 --- a/components/clarity-lsp/src/common/requests/definitions.rs +++ b/components/clarity-lsp/src/common/requests/definitions.rs @@ -587,11 +587,10 @@ mod definitions_visitor_tests { use std::collections::HashMap; use clarity_repl::clarity::ast::build_ast_with_rules; - use clarity_repl::clarity::stacks_common::types::StacksEpochId; + use clarity_repl::clarity::vm::types::QualifiedContractIdentifier; use clarity_repl::clarity::vm::types::StandardPrincipalData; - use clarity_repl::clarity::{ - vm::types::QualifiedContractIdentifier, ClarityVersion, SymbolicExpression, - }; + use clarity_repl::clarity::StacksEpochId; + use clarity_repl::clarity::{ClarityVersion, SymbolicExpression}; use lsp_types::{Position, Range}; use super::{DefinitionLocation, Definitions}; diff --git a/components/clarity-lsp/src/common/requests/document_symbols.rs b/components/clarity-lsp/src/common/requests/document_symbols.rs index a84ea21d1..ed3f1f98e 100644 --- a/components/clarity-lsp/src/common/requests/document_symbols.rs +++ b/components/clarity-lsp/src/common/requests/document_symbols.rs @@ -483,9 +483,10 @@ impl<'a> ASTVisitor<'a> for ASTSymbols { #[cfg(test)] mod tests { use clarity_repl::clarity::ast::{build_ast_with_rules, ASTRules}; + use clarity_repl::clarity::StacksEpochId; use clarity_repl::clarity::{ - representations::Span, stacks_common::types::StacksEpochId, - vm::types::QualifiedContractIdentifier, ClarityVersion, SymbolicExpression, + representations::Span, vm::types::QualifiedContractIdentifier, ClarityVersion, + SymbolicExpression, }; use lsp_types::{DocumentSymbol, SymbolKind}; diff --git a/components/clarity-lsp/src/common/requests/signature_help.rs b/components/clarity-lsp/src/common/requests/signature_help.rs index a4afd2683..84859522c 100644 --- a/components/clarity-lsp/src/common/requests/signature_help.rs +++ b/components/clarity-lsp/src/common/requests/signature_help.rs @@ -85,10 +85,8 @@ pub fn get_signatures( #[cfg(test)] mod definitions_visitor_tests { - use clarity_repl::clarity::ClarityVersion::Clarity2; - use clarity_repl::clarity::{ - functions::NativeFunctions, stacks_common::types::StacksEpochId::Epoch21, - }; + use clarity_repl::clarity::functions::NativeFunctions; + use clarity_repl::clarity::{ClarityVersion::Clarity2, StacksEpochId::Epoch21}; use lsp_types::{ParameterInformation, ParameterLabel::Simple, Position, SignatureInformation}; use crate::state::ActiveContractData; diff --git a/components/clarity-lsp/src/common/state.rs b/components/clarity-lsp/src/common/state.rs index 40982344b..cdb645a80 100644 --- a/components/clarity-lsp/src/common/state.rs +++ b/components/clarity-lsp/src/common/state.rs @@ -10,11 +10,10 @@ use clarity_repl::analysis::ast_dependency_detector::DependencySet; use clarity_repl::clarity::analysis::ContractAnalysis; use clarity_repl::clarity::ast::{build_ast_with_rules, ASTRules}; use clarity_repl::clarity::diagnostic::{Diagnostic as ClarityDiagnostic, Level as ClarityLevel}; -use clarity_repl::clarity::stacks_common::types::StacksEpochId; use clarity_repl::clarity::vm::ast::ContractAST; use clarity_repl::clarity::vm::types::{QualifiedContractIdentifier, StandardPrincipalData}; use clarity_repl::clarity::vm::EvaluationResult; -use clarity_repl::clarity::{ClarityName, ClarityVersion, SymbolicExpression}; +use clarity_repl::clarity::{ClarityName, ClarityVersion, StacksEpochId, SymbolicExpression}; use clarity_repl::repl::{ContractDeployer, DEFAULT_CLARITY_VERSION}; use lsp_types::{ CompletionItem, DocumentSymbol, Hover, Location, MessageType, Position, Range, SignatureHelp, diff --git a/components/clarity-repl/Cargo.toml b/components/clarity-repl/Cargo.toml index 3824a9fd8..f4c588e45 100644 --- a/components/clarity-repl/Cargo.toml +++ b/components/clarity-repl/Cargo.toml @@ -32,11 +32,15 @@ serde_derive = "1.0" integer-sqrt = "0.1.3" getrandom = { version = "0.2.3", features = ["js"] } atty = "0.2.14" -clarity-vm = { version = "2", default-features = false, optional = true } +wsts = "5.0.0" +# clarity-vm = "2" +clarity = { version = "2", default-features = false, optional = true, git = "https://github.com/stacks-network/stacks-core.git", branch = "feat/clarity-wasm-next", package = "clarity" } +# clarity = { version = "2", default-features = false, optional = true, path ="../../../clarity-wasm/stacks-blockchain/clarity" } +clar2wasm = { git = "https://github.com/stacks-network/clarity-wasm.git", optional = true } # DAP Debugger -tokio = { version = "1.24", features = ["full"], optional = true } -tokio-util = { version = "0.7.1", features = ["codec"], optional = true } +tokio = { version = "1.35.1", features = ["full"], optional = true } +tokio-util = { version = "0.7.10", features = ["codec"], optional = true } futures = { version = "0.3.12", optional = true } debug_types = { version = "1.0.0", optional = true } httparse = { version = "1.6.0", optional = true } @@ -76,13 +80,16 @@ cli = [ "pico-args", "rustyline", "prettytable-rs", - "clarity-vm/canonical", - "clarity-vm/developer-mode", + "clarity/canonical", + "clarity/developer-mode", + "clarity/log", "hiro_system_kit/tokio_helpers", + "clar2wasm", ] sdk = [ - "clarity-vm/canonical", - "clarity-vm/developer-mode", + "clarity/canonical", + "clarity/developer-mode", + "clarity/log", "hiro_system_kit/tokio_helpers", ] dap = [ @@ -95,7 +102,7 @@ dap = [ "memchr", "log", ] -wasm = ["wasm-bindgen", "wasm-bindgen-futures", "clarity-vm/wasm"] +wasm = ["wasm-bindgen", "wasm-bindgen-futures", "clarity/wasm"] [package.metadata.wasm-pack.profile.release.wasm-bindgen] debug-js-glue = false diff --git a/components/clarity-repl/src/analysis/annotation.rs b/components/clarity-repl/src/analysis/annotation.rs index a1747b722..e4b013a58 100644 --- a/components/clarity-repl/src/analysis/annotation.rs +++ b/components/clarity-repl/src/analysis/annotation.rs @@ -1,7 +1,6 @@ use clarity::vm::representations::Span; use clarity::vm::ClarityName; use regex::Regex; -use std::convert::TryFrom; #[derive(Debug)] pub enum AnnotationKind { @@ -33,7 +32,7 @@ impl std::str::FromStr for AnnotationKind { let params: Vec = value .split(',') .filter(|s| !s.is_empty()) - .map(|s| ClarityName::try_from(s.trim()).unwrap()) + .map(|s| ClarityName::from(s.trim())) .collect(); if params.is_empty() { Err("missing value for 'filter' annotation".to_string()) diff --git a/components/clarity-repl/src/analysis/check_checker/mod.rs b/components/clarity-repl/src/analysis/check_checker/mod.rs index 236b454bb..f095f5d97 100644 --- a/components/clarity-repl/src/analysis/check_checker/mod.rs +++ b/components/clarity-repl/src/analysis/check_checker/mod.rs @@ -879,6 +879,7 @@ mod tests { #[test] fn allow_unchecked_bool_in_private_function_with_unchecked_params_annotation() { let mut settings = SessionSettings::default(); + settings.repl_settings.disable_clarity_wasm(); // TODO(hugo): re-enable when fixed on clarity-wasm settings.repl_settings.analysis.passes = vec![Pass::CheckChecker]; let mut session = Session::new(settings); let snippet = " @@ -2653,6 +2654,7 @@ mod tests { #[test] fn dynamic_contract_call() { let mut settings = SessionSettings::default(); + settings.repl_settings.disable_clarity_wasm(); // TODO(hugo): re-enable when fixed on clarity-wasm settings.repl_settings.analysis.passes = vec![Pass::CheckChecker]; let mut session = Session::new(settings); let snippet = " @@ -3464,6 +3466,7 @@ mod tests { #[test] fn filter_trait() { let mut settings = SessionSettings::default(); + settings.repl_settings.disable_clarity_wasm(); // TODO(hugo): re-enable when fixed on clarity-wasm settings.repl_settings.analysis.passes = vec![Pass::CheckChecker]; let mut session = Session::new(settings); let snippet = " diff --git a/components/clarity-repl/src/codec/mod.rs b/components/clarity-repl/src/codec/mod.rs index 4b5b64b0b..f22e8373e 100644 --- a/components/clarity-repl/src/codec/mod.rs +++ b/components/clarity-repl/src/codec/mod.rs @@ -1,20 +1,25 @@ use crate::impl_byte_array_newtype; + +pub use clarity::codec::StacksMessageCodec; + use clarity::address::AddressHashMode; use clarity::address::{ C32_ADDRESS_VERSION_MAINNET_MULTISIG, C32_ADDRESS_VERSION_MAINNET_SINGLESIG, C32_ADDRESS_VERSION_TESTNET_MULTISIG, C32_ADDRESS_VERSION_TESTNET_SINGLESIG, }; use clarity::codec::MAX_MESSAGE_LEN; -use clarity::codec::{read_next, write_next, Error as CodecError, StacksMessageCodec}; -use clarity::stacks_common::types::chainstate::{ - BlockHeaderHash, BurnchainHeaderHash, ConsensusHash, StacksWorkScore, TrieHash, +use clarity::codec::{read_next, write_next, Error as CodecError}; +use clarity::types::chainstate::{ + BlockHeaderHash, BurnchainHeaderHash, ConsensusHash, StacksBlockId, StacksWorkScore, TrieHash, }; -use clarity::stacks_common::types::chainstate::{StacksAddress, StacksPublicKey}; +use clarity::types::chainstate::{StacksAddress, StacksPublicKey}; +use clarity::types::PrivateKey; use clarity::util::hash::{Hash160, Sha512Trunc256Sum}; use clarity::util::retry::BoundReader; use clarity::util::secp256k1::{ MessageSignature, Secp256k1PrivateKey, Secp256k1PublicKey, MESSAGE_SIGNATURE_ENCODED_SIZE, }; +use clarity::util::vrf::VRFProof; use clarity::vm::types::{ PrincipalData, QualifiedContractIdentifier, StandardPrincipalData, Value, }; @@ -32,9 +37,9 @@ use std::io::{Read, Write}; use std::ops::Deref; use std::ops::DerefMut; use std::str::FromStr; - -#[cfg(not(feature = "wasm"))] -use clarity::stacks_common::types::PrivateKey; +use wsts::common::Signature as Secp256k1Signature; +use wsts::curve::point::{Compressed as Secp256k1Compressed, Point as Secp256k1Point}; +use wsts::curve::scalar::Scalar as Secp256k1Scalar; pub const MAX_BLOCK_LEN: u32 = 2 * 1024 * 1024; pub const MAX_TRANSACTION_LEN: u32 = MAX_BLOCK_LEN; @@ -1307,6 +1312,128 @@ pub struct TransactionSmartContract { pub code_body: StacksString, } +/// Schnorr threshold signature using types from `wsts` +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct ThresholdSignature(pub wsts::common::Signature); + +impl StacksMessageCodec for ThresholdSignature { + fn consensus_serialize(&self, fd: &mut W) -> Result<(), CodecError> { + let compressed = self.0.R.compress(); + let bytes = compressed.as_bytes(); + fd.write_all(bytes).map_err(CodecError::WriteError)?; + write_next(fd, &self.0.z.to_bytes())?; + Ok(()) + } + + fn consensus_deserialize(fd: &mut R) -> Result { + // Read curve point + let mut buf = [0u8; 33]; + fd.read_exact(&mut buf).map_err(CodecError::ReadError)?; + let r = Secp256k1Point::try_from(&Secp256k1Compressed::from(buf)) + .map_err(|_| CodecError::DeserializeError("Failed to read curve point".into()))?; + + // Read scalar + let mut buf = [0u8; 32]; + fd.read_exact(&mut buf).map_err(CodecError::ReadError)?; + let z = Secp256k1Scalar::from(buf); + + Ok(Self(Secp256k1Signature { R: r, z })) + } +} + +/// Cause of change in mining tenure +/// Depending on cause, tenure can be ended or extended +#[repr(u8)] +#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] +pub enum TenureChangeCause { + /// A valid winning block-commit + BlockFound = 0, + /// The next burnchain block is taking too long, so extend the runtime budget + Extended = 1, +} + +impl TryFrom for TenureChangeCause { + type Error = (); + + fn try_from(num: u8) -> Result { + match num { + 0 => Ok(Self::BlockFound), + 1 => Ok(Self::Extended), + _ => Err(()), + } + } +} + +impl StacksMessageCodec for TenureChangeCause { + fn consensus_serialize(&self, fd: &mut W) -> Result<(), CodecError> { + let byte = (*self) as u8; + write_next(fd, &byte) + } + + fn consensus_deserialize(fd: &mut R) -> Result { + let byte: u8 = read_next(fd)?; + TenureChangeCause::try_from(byte).map_err(|_| { + CodecError::DeserializeError(format!("Unrecognized TenureChangeCause byte {byte}")) + }) + } +} + +/// A transaction from Stackers to signal new mining tenure +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct TenureChangePayload { + /// Consensus hash of this tenure. Corresponds to the sortition in which the miner of this + /// block was chosen. It may be the case that this miner's tenure gets _extended_ across + /// subsequent sortitions; if this happens, then this `consensus_hash` value _remains the same_ + /// as the sortition in which the winning block-commit was mined. + pub tenure_consensus_hash: ConsensusHash, + /// Consensus hash of the previous tenure. Corresponds to the sortition of the previous + /// winning block-commit. + pub prev_tenure_consensus_hash: ConsensusHash, + /// Current consensus hash on the underlying burnchain. Corresponds to the last-seen + /// sortition. + pub burn_view_consensus_hash: ConsensusHash, + /// The StacksBlockId of the last block from the previous tenure + pub previous_tenure_end: StacksBlockId, + /// The number of blocks produced since the last sortition-linked tenure + pub previous_tenure_blocks: u32, + /// A flag to indicate the cause of this tenure change + pub cause: TenureChangeCause, + /// The ECDSA public key hash of the current tenure + pub pubkey_hash: Hash160, + /// The Stacker signature + pub signature: ThresholdSignature, + /// A bitmap of which Stackers signed + pub signers: Vec, +} + +impl StacksMessageCodec for TenureChangePayload { + fn consensus_serialize(&self, fd: &mut W) -> Result<(), CodecError> { + write_next(fd, &self.tenure_consensus_hash)?; + write_next(fd, &self.prev_tenure_consensus_hash)?; + write_next(fd, &self.burn_view_consensus_hash)?; + write_next(fd, &self.previous_tenure_end)?; + write_next(fd, &self.previous_tenure_blocks)?; + write_next(fd, &self.cause)?; + write_next(fd, &self.pubkey_hash)?; + write_next(fd, &self.signature)?; + write_next(fd, &self.signers) + } + + fn consensus_deserialize(fd: &mut R) -> Result { + Ok(Self { + tenure_consensus_hash: read_next(fd)?, + prev_tenure_consensus_hash: read_next(fd)?, + burn_view_consensus_hash: read_next(fd)?, + previous_tenure_end: read_next(fd)?, + previous_tenure_blocks: read_next(fd)?, + cause: read_next(fd)?, + pubkey_hash: read_next(fd)?, + signature: read_next(fd)?, + signers: read_next(fd)?, + }) + } +} + /// A coinbase commits to 32 bytes of control-plane information pub struct CoinbasePayload(pub [u8; 32]); impl_byte_array_message_codec!(CoinbasePayload, 32); @@ -1327,8 +1454,10 @@ pub enum TransactionPayload { TokenTransfer(PrincipalData, u64, TokenTransferMemo), ContractCall(TransactionContractCall), SmartContract(TransactionSmartContract, Option), - PoisonMicroblock(StacksMicroblockHeader, StacksMicroblockHeader), // the previous epoch leader sent two microblocks with the same sequence, and this is proof - Coinbase(CoinbasePayload, Option), + // the previous epoch leader sent two microblocks with the same sequence, and this is proof + PoisonMicroblock(StacksMicroblockHeader, StacksMicroblockHeader), + Coinbase(CoinbasePayload, Option, Option), + TenureChange(TenureChangePayload), } impl TransactionPayload { @@ -1339,6 +1468,7 @@ impl TransactionPayload { TransactionPayload::SmartContract(..) => "SmartContract", TransactionPayload::PoisonMicroblock(..) => "PoisonMicroblock", TransactionPayload::Coinbase(..) => "Coinbase", + TransactionPayload::TenureChange(..) => "TenureChange", } } } @@ -1351,8 +1481,12 @@ pub enum TransactionPayloadID { ContractCall = 2, PoisonMicroblock = 3, Coinbase = 4, + // has an alt principal, but no VRF proof CoinbaseToAltRecipient = 5, VersionedSmartContract = 6, + TenureChange = 7, + // has a VRF proof, and may have an alt principal + NakamotoCoinbase = 8, } /// Encoding of an asset type identifier @@ -2438,7 +2572,7 @@ impl StacksMessageCodec for TransactionPayload { } x if x == TransactionPayloadID::Coinbase as u8 => { let payload: CoinbasePayload = read_next(fd)?; - TransactionPayload::Coinbase(payload, None) + TransactionPayload::Coinbase(payload, None, None) } x if x == TransactionPayloadID::CoinbaseToAltRecipient as u8 => { let payload: CoinbasePayload = read_next(fd)?; @@ -2450,7 +2584,30 @@ impl StacksMessageCodec for TransactionPayload { } }; - TransactionPayload::Coinbase(payload, Some(recipient)) + TransactionPayload::Coinbase(payload, Some(recipient), None) + } + x if x == TransactionPayloadID::NakamotoCoinbase as u8 => { + let payload: CoinbasePayload = read_next(fd)?; + let principal_value_opt: Value = read_next(fd)?; + let recipient_opt = if let Value::Optional(optional_data) = principal_value_opt { + if let Some(principal_value) = optional_data.data { + if let Value::Principal(recipient_principal) = *principal_value { + Some(recipient_principal) + } else { + None + } + } else { + None + } + } else { + return Err(CodecError::DeserializeError("Failed to parse nakamoto coinbase transaction -- did not receive an optional recipient principal value".to_string())); + }; + let vrf_proof: VRFProof = read_next(fd)?; + TransactionPayload::Coinbase(payload, recipient_opt, Some(vrf_proof)) + } + x if x == TransactionPayloadID::TenureChange as u8 => { + let payload: TenureChangePayload = read_next(fd)?; + TransactionPayload::TenureChange(payload) } _ => { return Err(CodecError::DeserializeError(format!( diff --git a/components/clarity-repl/src/lib.rs b/components/clarity-repl/src/lib.rs index d1b31ad06..51f373f0e 100644 --- a/components/clarity-repl/src/lib.rs +++ b/components/clarity-repl/src/lib.rs @@ -24,7 +24,7 @@ pub mod test_fixtures; pub mod clarity { #![allow(ambiguous_glob_reexports)] - pub use ::clarity::stacks_common::*; + pub use ::clarity::types::*; pub use ::clarity::vm::*; pub use ::clarity::*; } diff --git a/components/clarity-repl/src/repl/boot/mod.rs b/components/clarity-repl/src/repl/boot/mod.rs index 21afd6c65..8d96750f6 100644 --- a/components/clarity-repl/src/repl/boot/mod.rs +++ b/components/clarity-repl/src/repl/boot/mod.rs @@ -31,9 +31,11 @@ const BOOT_CODE_GENESIS: &str = std::include_str!("genesis.clar"); pub const POX_1_NAME: &str = "pox"; pub const POX_2_NAME: &str = "pox-2"; pub const POX_3_NAME: &str = "pox-3"; +pub const POX_4_NAME: &str = "pox-4"; const POX_2_BODY: &str = std::include_str!("pox-2.clar"); const POX_3_BODY: &str = std::include_str!("pox-3.clar"); +const POX_4_BODY: &str = std::include_str!("pox-4.clar"); pub const COSTS_1_NAME: &str = "costs"; pub const COSTS_2_NAME: &str = "costs-2"; @@ -51,8 +53,12 @@ lazy_static! { format!("{}\n{}", BOOT_CODE_POX_MAINNET_CONSTS, POX_3_BODY); pub static ref POX_3_TESTNET_CODE: String = format!("{}\n{}", BOOT_CODE_POX_TESTNET_CONSTS, POX_3_BODY); + pub static ref POX_4_MAINNET_CODE: String = + format!("{}\n{}", BOOT_CODE_POX_MAINNET_CONSTS, POX_4_BODY); + pub static ref POX_4_TESTNET_CODE: String = + format!("{}\n{}", BOOT_CODE_POX_TESTNET_CONSTS, POX_4_BODY); pub static ref BOOT_CODE_COST_VOTING_TESTNET: String = make_testnet_cost_voting(); - pub static ref STACKS_BOOT_CODE_MAINNET: [(&'static str, &'static str); 10] = [ + pub static ref STACKS_BOOT_CODE_MAINNET: [(&'static str, &'static str); 11] = [ ("pox", &BOOT_CODE_POX_MAINNET), ("lockup", &BOOT_CODE_LOCKUP), ("costs", &BOOT_CODE_COSTS), @@ -63,8 +69,9 @@ lazy_static! { ("pox-2", &POX_2_MAINNET_CODE), ("costs-3", &BOOT_CODE_COSTS_3), ("pox-3", &POX_3_MAINNET_CODE), + ("pox-4", &POX_4_MAINNET_CODE), ]; - pub static ref STACKS_BOOT_CODE_TESTNET: [(&'static str, &'static str); 10] = [ + pub static ref STACKS_BOOT_CODE_TESTNET: [(&'static str, &'static str); 11] = [ ("pox", &BOOT_CODE_POX_TESTNET), ("lockup", &BOOT_CODE_LOCKUP), ("costs", &BOOT_CODE_COSTS), @@ -75,6 +82,7 @@ lazy_static! { ("pox-2", &POX_2_TESTNET_CODE), ("costs-3", &BOOT_CODE_COSTS_3_TESTNET), ("pox-3", &POX_3_TESTNET_CODE), + ("pox-4", &POX_4_TESTNET_CODE), ]; } diff --git a/components/clarity-repl/src/repl/boot/pox-4.clar b/components/clarity-repl/src/repl/boot/pox-4.clar new file mode 100644 index 000000000..ff6463140 --- /dev/null +++ b/components/clarity-repl/src/repl/boot/pox-4.clar @@ -0,0 +1,1338 @@ +;; The .pox-4 contract +;; Error codes +(define-constant ERR_STACKING_UNREACHABLE 255) +(define-constant ERR_STACKING_CORRUPTED_STATE 254) +(define-constant ERR_STACKING_INSUFFICIENT_FUNDS 1) +(define-constant ERR_STACKING_INVALID_LOCK_PERIOD 2) +(define-constant ERR_STACKING_ALREADY_STACKED 3) +(define-constant ERR_STACKING_NO_SUCH_PRINCIPAL 4) +(define-constant ERR_STACKING_EXPIRED 5) +(define-constant ERR_STACKING_STX_LOCKED 6) +(define-constant ERR_STACKING_PERMISSION_DENIED 9) +(define-constant ERR_STACKING_THRESHOLD_NOT_MET 11) +(define-constant ERR_STACKING_POX_ADDRESS_IN_USE 12) +(define-constant ERR_STACKING_INVALID_POX_ADDRESS 13) +(define-constant ERR_STACKING_ALREADY_REJECTED 17) +(define-constant ERR_STACKING_INVALID_AMOUNT 18) +(define-constant ERR_NOT_ALLOWED 19) +(define-constant ERR_STACKING_ALREADY_DELEGATED 20) +(define-constant ERR_DELEGATION_EXPIRES_DURING_LOCK 21) +(define-constant ERR_DELEGATION_TOO_MUCH_LOCKED 22) +(define-constant ERR_DELEGATION_POX_ADDR_REQUIRED 23) +(define-constant ERR_INVALID_START_BURN_HEIGHT 24) +(define-constant ERR_NOT_CURRENT_STACKER 25) +(define-constant ERR_STACK_EXTEND_NOT_LOCKED 26) +(define-constant ERR_STACK_INCREASE_NOT_LOCKED 27) +(define-constant ERR_DELEGATION_NO_REWARD_SLOT 28) +(define-constant ERR_DELEGATION_WRONG_REWARD_SLOT 29) +(define-constant ERR_STACKING_IS_DELEGATED 30) +(define-constant ERR_STACKING_NOT_DELEGATED 31) + +;; PoX disabling threshold (a percent) +(define-constant POX_REJECTION_FRACTION u25) + +;; Valid values for burnchain address versions. +;; These first four correspond to address hash modes in Stacks 2.1, +;; and are defined in pox-mainnet.clar and pox-testnet.clar (so they +;; cannot be defined here again). +;; (define-constant ADDRESS_VERSION_P2PKH 0x00) +;; (define-constant ADDRESS_VERSION_P2SH 0x01) +;; (define-constant ADDRESS_VERSION_P2WPKH 0x02) +;; (define-constant ADDRESS_VERSION_P2WSH 0x03) +(define-constant ADDRESS_VERSION_NATIVE_P2WPKH 0x04) +(define-constant ADDRESS_VERSION_NATIVE_P2WSH 0x05) +(define-constant ADDRESS_VERSION_NATIVE_P2TR 0x06) +;; Keep these constants in lock-step with the address version buffs above +;; Maximum value of an address version as a uint +(define-constant MAX_ADDRESS_VERSION u6) +;; Maximum value of an address version that has a 20-byte hashbytes +;; (0x00, 0x01, 0x02, 0x03, and 0x04 have 20-byte hashbytes) +(define-constant MAX_ADDRESS_VERSION_BUFF_20 u4) +;; Maximum value of an address version that has a 32-byte hashbytes +;; (0x05 and 0x06 have 32-byte hashbytes) +(define-constant MAX_ADDRESS_VERSION_BUFF_32 u6) + +;; Data vars that store a copy of the burnchain configuration. +;; Implemented as data-vars, so that different configurations can be +;; used in e.g. test harnesses. +(define-data-var pox-prepare-cycle-length uint PREPARE_CYCLE_LENGTH) +(define-data-var pox-reward-cycle-length uint REWARD_CYCLE_LENGTH) +(define-data-var pox-rejection-fraction uint POX_REJECTION_FRACTION) +(define-data-var first-burnchain-block-height uint u0) +(define-data-var configured bool false) +(define-data-var first-2-1-reward-cycle uint u0) + +;; This function can only be called once, when it boots up +(define-public (set-burnchain-parameters (first-burn-height uint) + (prepare-cycle-length uint) + (reward-cycle-length uint) + (rejection-fraction uint) + (begin-2-1-reward-cycle uint)) + (begin + (asserts! (not (var-get configured)) (err ERR_NOT_ALLOWED)) + (var-set first-burnchain-block-height first-burn-height) + (var-set pox-prepare-cycle-length prepare-cycle-length) + (var-set pox-reward-cycle-length reward-cycle-length) + (var-set pox-rejection-fraction rejection-fraction) + (var-set first-2-1-reward-cycle begin-2-1-reward-cycle) + (var-set configured true) + (ok true)) +) + +;; The Stacking lock-up state and associated metadata. +;; Records are inserted into this map via `stack-stx`, `delegate-stack-stx`, `stack-extend` +;; `delegate-stack-extend` and burnchain transactions for invoking `stack-stx`, etc. +;; Records will be deleted from this map when auto-unlocks are processed +;; +;; This map de-normalizes some state from the `reward-cycle-pox-address-list` map +;; and the `pox-4` contract tries to keep this state in sync with the reward-cycle +;; state. The major invariants of this `stacking-state` map are: +;; (1) any entry in `reward-cycle-pox-address-list` with `some stacker` points to a real `stacking-state` +;; (2) `stacking-state.reward-set-indexes` matches the index of that `reward-cycle-pox-address-list` +;; (3) all `stacking-state.reward-set-indexes` match the index of their reward cycle entries +;; (4) `stacking-state.pox-addr` matches `reward-cycle-pox-address-list.pox-addr` +;; (5) if set, (len reward-set-indexes) == lock-period +;; (6) (reward-cycle-to-burn-height (+ lock-period first-reward-cycle)) == (get unlock-height (stx-account stacker)) +;; These invariants only hold while `cur-reward-cycle < (+ lock-period first-reward-cycle)` +;; +(define-map stacking-state + { stacker: principal } + { + ;; Description of the underlying burnchain address that will + ;; receive PoX'ed tokens. Translating this into an address + ;; depends on the burnchain being used. When Bitcoin is + ;; the burnchain, this gets translated into a p2pkh, p2sh, + ;; p2wpkh-p2sh, p2wsh-p2sh, p2wpkh, p2wsh, or p2tr UTXO, + ;; depending on the version. The `hashbytes` field *must* be + ;; either 20 bytes or 32 bytes, depending on the output. + pox-addr: { version: (buff 1), hashbytes: (buff 32) }, + ;; how long the uSTX are locked, in reward cycles. + lock-period: uint, + ;; reward cycle when rewards begin + first-reward-cycle: uint, + ;; indexes in each reward-set associated with this user. + ;; these indexes are only valid looking forward from + ;; `first-reward-cycle` (i.e., they do not correspond + ;; to entries in the reward set that may have been from + ;; previous stack-stx calls, or prior to an extend) + reward-set-indexes: (list 12 uint), + ;; principal of the delegate, if stacker has delegated + delegated-to: (optional principal) + } +) + +;; Delegation relationships +(define-map delegation-state + { stacker: principal } + { + amount-ustx: uint, ;; how many uSTX delegated? + delegated-to: principal, ;; who are we delegating? + until-burn-ht: (optional uint), ;; how long does the delegation last? + ;; does the delegate _need_ to use a specific + ;; pox recipient address? + pox-addr: (optional { version: (buff 1), hashbytes: (buff 32) }) + } +) + +;; allowed contract-callers +(define-map allowance-contract-callers + { sender: principal, contract-caller: principal } + { until-burn-ht: (optional uint) }) + +;; How many uSTX are stacked in a given reward cycle. +;; Updated when a new PoX address is registered, or when more STX are granted +;; to it. +(define-map reward-cycle-total-stacked + { reward-cycle: uint } + { total-ustx: uint } +) + +;; Internal map read by the Stacks node to iterate through the list of +;; PoX reward addresses on a per-reward-cycle basis. +(define-map reward-cycle-pox-address-list + { reward-cycle: uint, index: uint } + { + pox-addr: { version: (buff 1), hashbytes: (buff 32) }, + total-ustx: uint, + stacker: (optional principal) + } +) + +(define-map reward-cycle-pox-address-list-len + { reward-cycle: uint } + { len: uint } +) + +;; how much has been locked up for this address before +;; committing? +;; this map allows stackers to stack amounts < minimum +;; by paying the cost of aggregation during the commit +(define-map partial-stacked-by-cycle + { + pox-addr: { version: (buff 1), hashbytes: (buff 32) }, + reward-cycle: uint, + sender: principal + } + { stacked-amount: uint } +) + +;; This is identical to partial-stacked-by-cycle, but its data is never deleted. +;; It is used to preserve data for downstream clients to observe aggregate +;; commits. Each key/value pair in this map is simply the last value of +;; partial-stacked-by-cycle right after it was deleted (so, subsequent calls +;; to the `stack-aggregation-*` functions will overwrite this). +(define-map logged-partial-stacked-by-cycle + { + pox-addr: { version: (buff 1), hashbytes: (buff 32) }, + reward-cycle: uint, + sender: principal + } + { stacked-amount: uint } +) + +;; Amount of uSTX that reject PoX, by reward cycle +(define-map stacking-rejection + { reward-cycle: uint } + { amount: uint } +) + +;; Who rejected in which reward cycle +(define-map stacking-rejectors + { stacker: principal, reward-cycle: uint } + { amount: uint } +) + +;; The stackers' aggregate public key +;; for the given reward cycle +(define-map aggregate-public-keys uint (buff 33)) + +;; Getter for stacking-rejectors +(define-read-only (get-pox-rejection (stacker principal) (reward-cycle uint)) + (map-get? stacking-rejectors { stacker: stacker, reward-cycle: reward-cycle })) + +;; Has PoX been rejected in the given reward cycle? +(define-read-only (is-pox-active (reward-cycle uint)) + (let ( + (reject-votes + (default-to + u0 + (get amount (map-get? stacking-rejection { reward-cycle: reward-cycle })))) + ) + ;; (100 * reject-votes) / stx-liquid-supply < pox-rejection-fraction + (< (* u100 reject-votes) + (* (var-get pox-rejection-fraction) stx-liquid-supply))) +) + +;; What's the reward cycle number of the burnchain block height? +;; Will runtime-abort if height is less than the first burnchain block (this is intentional) +(define-read-only (burn-height-to-reward-cycle (height uint)) + (/ (- height (var-get first-burnchain-block-height)) (var-get pox-reward-cycle-length))) + +;; What's the block height at the start of a given reward cycle? +(define-read-only (reward-cycle-to-burn-height (cycle uint)) + (+ (var-get first-burnchain-block-height) (* cycle (var-get pox-reward-cycle-length)))) + +;; What's the current PoX reward cycle? +(define-read-only (current-pox-reward-cycle) + (burn-height-to-reward-cycle burn-block-height)) + +;; Get the _current_ PoX stacking principal information. If the information +;; is expired, or if there's never been such a stacker, then returns none. +(define-read-only (get-stacker-info (stacker principal)) + (match (map-get? stacking-state { stacker: stacker }) + stacking-info + (if (<= (+ (get first-reward-cycle stacking-info) (get lock-period stacking-info)) (current-pox-reward-cycle)) + ;; present, but lock has expired + none + ;; present, and lock has not expired + (some stacking-info) + ) + ;; no state at all + none + )) + +(define-read-only (check-caller-allowed) + (or (is-eq tx-sender contract-caller) + (let ((caller-allowed + ;; if not in the caller map, return false + (unwrap! (map-get? allowance-contract-callers + { sender: tx-sender, contract-caller: contract-caller }) + false)) + (expires-at + ;; if until-burn-ht not set, then return true (because no expiry) + (unwrap! (get until-burn-ht caller-allowed) true))) + ;; is the caller allowance expired? + (if (>= burn-block-height expires-at) + false + true)))) + +(define-read-only (get-check-delegation (stacker principal)) + (let ((delegation-info (try! (map-get? delegation-state { stacker: stacker })))) + ;; did the existing delegation expire? + (if (match (get until-burn-ht delegation-info) + until-burn-ht (> burn-block-height until-burn-ht) + false) + ;; it expired, return none + none + ;; delegation is active + (some delegation-info)))) + +;; Get the size of the reward set for a reward cycle. +;; Note that this does _not_ return duplicate PoX addresses. +;; Note that this also _will_ return PoX addresses that are beneath +;; the minimum threshold -- i.e. the threshold can increase after insertion. +;; Used internally by the Stacks node, which filters out the entries +;; in this map to select PoX addresses with enough STX. +(define-read-only (get-reward-set-size (reward-cycle uint)) + (default-to + u0 + (get len (map-get? reward-cycle-pox-address-list-len { reward-cycle: reward-cycle })))) + +;; How many rejection votes have we been accumulating for the next block +(define-read-only (next-cycle-rejection-votes) + (default-to + u0 + (get amount (map-get? stacking-rejection { reward-cycle: (+ u1 (current-pox-reward-cycle)) })))) + +;; Add a single PoX address to a single reward cycle. +;; Used to build up a set of per-reward-cycle PoX addresses. +;; No checking will be done -- don't call if this PoX address is already registered in this reward cycle! +;; Returns the index into the reward cycle that the PoX address is stored to +(define-private (append-reward-cycle-pox-addr (pox-addr (tuple (version (buff 1)) (hashbytes (buff 32)))) + (reward-cycle uint) + (amount-ustx uint) + (stacker (optional principal))) + (let ((sz (get-reward-set-size reward-cycle))) + (map-set reward-cycle-pox-address-list + { reward-cycle: reward-cycle, index: sz } + { pox-addr: pox-addr, total-ustx: amount-ustx, stacker: stacker }) + (map-set reward-cycle-pox-address-list-len + { reward-cycle: reward-cycle } + { len: (+ u1 sz) }) + sz)) + +;; How many uSTX are stacked? +(define-read-only (get-total-ustx-stacked (reward-cycle uint)) + (default-to + u0 + (get total-ustx (map-get? reward-cycle-total-stacked { reward-cycle: reward-cycle }))) +) + +;; Called internally by the node to iterate through the list of PoX addresses in this reward cycle. +;; Returns (optional (tuple (pox-addr ) (total-ustx ))) +(define-read-only (get-reward-set-pox-address (reward-cycle uint) (index uint)) + (map-get? reward-cycle-pox-address-list { reward-cycle: reward-cycle, index: index })) + +(define-private (fold-unlock-reward-cycle (set-index uint) + (data-res (response { cycle: uint, + first-unlocked-cycle: uint, + stacker: principal + } int))) + (let ((data (try! data-res)) + (cycle (get cycle data)) + (first-unlocked-cycle (get first-unlocked-cycle data))) + ;; if current-cycle hasn't reached first-unlocked-cycle, just continue to next iter + (asserts! (>= cycle first-unlocked-cycle) (ok (merge data { cycle: (+ u1 cycle) }))) + (let ((cycle-entry (unwrap-panic (map-get? reward-cycle-pox-address-list { reward-cycle: cycle, index: set-index }))) + (cycle-entry-u (get stacker cycle-entry)) + (cycle-entry-total-ustx (get total-ustx cycle-entry)) + (cycle-last-entry-ix (- (get len (unwrap-panic (map-get? reward-cycle-pox-address-list-len { reward-cycle: cycle }))) u1))) + (asserts! (is-eq cycle-entry-u (some (get stacker data))) (err ERR_STACKING_CORRUPTED_STATE)) + (if (not (is-eq cycle-last-entry-ix set-index)) + ;; do a "move" if the entry to remove isn't last + (let ((move-entry (unwrap-panic (map-get? reward-cycle-pox-address-list { reward-cycle: cycle, index: cycle-last-entry-ix })))) + (map-set reward-cycle-pox-address-list + { reward-cycle: cycle, index: set-index } + move-entry) + (match (get stacker move-entry) moved-stacker + ;; if the moved entry had an associated stacker, update its state + (let ((moved-state (unwrap-panic (map-get? stacking-state { stacker: moved-stacker }))) + ;; calculate the index into the reward-set-indexes that `cycle` is at + (moved-cycle-index (- cycle (get first-reward-cycle moved-state))) + (moved-reward-list (get reward-set-indexes moved-state)) + ;; reward-set-indexes[moved-cycle-index] = set-index via slice?, append, concat. + (update-list (unwrap-panic (replace-at? moved-reward-list moved-cycle-index set-index)))) + (map-set stacking-state { stacker: moved-stacker } + (merge moved-state { reward-set-indexes: update-list }))) + ;; otherwise, we don't need to update stacking-state after move + true)) + ;; if not moving, just noop + true) + ;; in all cases, we now need to delete the last list entry + (map-delete reward-cycle-pox-address-list { reward-cycle: cycle, index: cycle-last-entry-ix }) + (map-set reward-cycle-pox-address-list-len { reward-cycle: cycle } { len: cycle-last-entry-ix }) + ;; finally, update `reward-cycle-total-stacked` + (map-set reward-cycle-total-stacked { reward-cycle: cycle } + { total-ustx: (- (get total-ustx (unwrap-panic (map-get? reward-cycle-total-stacked { reward-cycle: cycle }))) + cycle-entry-total-ustx) }) + (ok (merge data { cycle: (+ u1 cycle)} ))))) + +;; This method is called by the Stacks block processor directly in order to handle the contract state mutations +;; associated with an early unlock. This can only be invoked by the block processor: it is private, and no methods +;; from this contract invoke it. +(define-private (handle-unlock (user principal) (amount-locked uint) (cycle-to-unlock uint)) + (let ((user-stacking-state (unwrap-panic (map-get? stacking-state { stacker: user }))) + (first-cycle-locked (get first-reward-cycle user-stacking-state)) + (reward-set-indexes (get reward-set-indexes user-stacking-state))) + ;; iterate over each reward set the user is a member of, and remove them from the sets. only apply to reward sets after cycle-to-unlock. + (try! (fold fold-unlock-reward-cycle reward-set-indexes (ok { cycle: first-cycle-locked, first-unlocked-cycle: cycle-to-unlock, stacker: user }))) + ;; Now that we've cleaned up all the reward set entries for the user, delete the user's stacking-state + (map-delete stacking-state { stacker: user }) + (ok true))) + +;; Add a PoX address to the `cycle-index`-th reward cycle, if `cycle-index` is between 0 and the given num-cycles (exclusive). +;; Arguments are given as a tuple, so this function can be (folded ..)'ed onto a list of its arguments. +;; Used by add-pox-addr-to-reward-cycles. +;; No checking is done. +;; The returned tuple is the same as inputted `params`, but the `i` field is incremented if +;; the pox-addr was added to the given cycle. Also, `reward-set-indexes` grows to include all +;; of the `reward-cycle-index` key parts of the `reward-cycle-pox-address-list` which get added by this function. +;; This way, the caller knows which items in a given reward cycle's PoX address list got updated. +(define-private (add-pox-addr-to-ith-reward-cycle (cycle-index uint) (params (tuple + (pox-addr (tuple (version (buff 1)) (hashbytes (buff 32)))) + (reward-set-indexes (list 12 uint)) + (first-reward-cycle uint) + (num-cycles uint) + (stacker (optional principal)) + (amount-ustx uint) + (i uint)))) + (let ((reward-cycle (+ (get first-reward-cycle params) (get i params))) + (num-cycles (get num-cycles params)) + (i (get i params)) + (reward-set-index (if (< i num-cycles) + (let ((total-ustx (get-total-ustx-stacked reward-cycle)) + (reward-index + ;; record how many uSTX this pox-addr will stack for in the given reward cycle + (append-reward-cycle-pox-addr + (get pox-addr params) + reward-cycle + (get amount-ustx params) + (get stacker params) + ))) + ;; update running total + (map-set reward-cycle-total-stacked + { reward-cycle: reward-cycle } + { total-ustx: (+ (get amount-ustx params) total-ustx) }) + (some reward-index)) + none)) + (next-i (if (< i num-cycles) (+ i u1) i))) + { + pox-addr: (get pox-addr params), + first-reward-cycle: (get first-reward-cycle params), + num-cycles: num-cycles, + amount-ustx: (get amount-ustx params), + stacker: (get stacker params), + reward-set-indexes: (match + reward-set-index new (unwrap-panic (as-max-len? (append (get reward-set-indexes params) new) u12)) + (get reward-set-indexes params)), + i: next-i + })) + +;; Add a PoX address to a given sequence of reward cycle lists. +;; A PoX address can be added to at most 12 consecutive cycles. +;; No checking is done. +(define-private (add-pox-addr-to-reward-cycles (pox-addr (tuple (version (buff 1)) (hashbytes (buff 32)))) + (first-reward-cycle uint) + (num-cycles uint) + (amount-ustx uint) + (stacker principal)) + (let ((cycle-indexes (list u0 u1 u2 u3 u4 u5 u6 u7 u8 u9 u10 u11)) + (results (fold add-pox-addr-to-ith-reward-cycle cycle-indexes + { pox-addr: pox-addr, first-reward-cycle: first-reward-cycle, num-cycles: num-cycles, + reward-set-indexes: (list), amount-ustx: amount-ustx, i: u0, stacker: (some stacker) })) + (reward-set-indexes (get reward-set-indexes results))) + ;; For safety, add up the number of times (add-principal-to-ith-reward-cycle) returns 1. + ;; It _should_ be equal to num-cycles. + (asserts! (is-eq num-cycles (get i results)) (err ERR_STACKING_UNREACHABLE)) + (asserts! (is-eq num-cycles (len reward-set-indexes)) (err ERR_STACKING_UNREACHABLE)) + (ok reward-set-indexes))) + +(define-private (add-pox-partial-stacked-to-ith-cycle + (cycle-index uint) + (params { pox-addr: { version: (buff 1), hashbytes: (buff 32) }, + reward-cycle: uint, + num-cycles: uint, + amount-ustx: uint })) + (let ((pox-addr (get pox-addr params)) + (num-cycles (get num-cycles params)) + (reward-cycle (get reward-cycle params)) + (amount-ustx (get amount-ustx params))) + (let ((current-amount + (default-to u0 + (get stacked-amount + (map-get? partial-stacked-by-cycle { sender: tx-sender, pox-addr: pox-addr, reward-cycle: reward-cycle }))))) + (if (>= cycle-index num-cycles) + ;; do not add to cycles >= cycle-index + false + ;; otherwise, add to the partial-stacked-by-cycle + (map-set partial-stacked-by-cycle + { sender: tx-sender, pox-addr: pox-addr, reward-cycle: reward-cycle } + { stacked-amount: (+ amount-ustx current-amount) })) + ;; produce the next params tuple + { pox-addr: pox-addr, + reward-cycle: (+ u1 reward-cycle), + num-cycles: num-cycles, + amount-ustx: amount-ustx }))) + +;; Add a PoX address to a given sequence of partial reward cycle lists. +;; A PoX address can be added to at most 12 consecutive cycles. +;; No checking is done. +(define-private (add-pox-partial-stacked (pox-addr (tuple (version (buff 1)) (hashbytes (buff 32)))) + (first-reward-cycle uint) + (num-cycles uint) + (amount-ustx uint)) + (let ((cycle-indexes (list u0 u1 u2 u3 u4 u5 u6 u7 u8 u9 u10 u11))) + (fold add-pox-partial-stacked-to-ith-cycle cycle-indexes + { pox-addr: pox-addr, reward-cycle: first-reward-cycle, num-cycles: num-cycles, amount-ustx: amount-ustx }) + true)) + +;; What is the minimum number of uSTX to be stacked in the given reward cycle? +;; Used internally by the Stacks node, and visible publicly. +(define-read-only (get-stacking-minimum) + (/ stx-liquid-supply STACKING_THRESHOLD_25)) + +;; Is the address mode valid for a PoX address? +(define-read-only (check-pox-addr-version (version (buff 1))) + (<= (buff-to-uint-be version) MAX_ADDRESS_VERSION)) + +;; Is this buffer the right length for the given PoX address? +(define-read-only (check-pox-addr-hashbytes (version (buff 1)) (hashbytes (buff 32))) + (if (<= (buff-to-uint-be version) MAX_ADDRESS_VERSION_BUFF_20) + (is-eq (len hashbytes) u20) + (if (<= (buff-to-uint-be version) MAX_ADDRESS_VERSION_BUFF_32) + (is-eq (len hashbytes) u32) + false))) + +;; Is the given lock period valid? +(define-read-only (check-pox-lock-period (lock-period uint)) + (and (>= lock-period MIN_POX_REWARD_CYCLES) + (<= lock-period MAX_POX_REWARD_CYCLES))) + +;; Evaluate if a participant can stack an amount of STX for a given period. +;; This method is designed as a read-only method so that it can be used as +;; a set of guard conditions and also as a read-only RPC call that can be +;; performed beforehand. +(define-read-only (can-stack-stx (pox-addr (tuple (version (buff 1)) (hashbytes (buff 32)))) + (amount-ustx uint) + (first-reward-cycle uint) + (num-cycles uint)) + (begin + ;; minimum uSTX must be met + (asserts! (<= (get-stacking-minimum) amount-ustx) + (err ERR_STACKING_THRESHOLD_NOT_MET)) + + (minimal-can-stack-stx pox-addr amount-ustx first-reward-cycle num-cycles))) + +;; Evaluate if a participant can stack an amount of STX for a given period. +;; This method is designed as a read-only method so that it can be used as +;; a set of guard conditions and also as a read-only RPC call that can be +;; performed beforehand. +(define-read-only (minimal-can-stack-stx + (pox-addr (tuple (version (buff 1)) (hashbytes (buff 32)))) + (amount-ustx uint) + (first-reward-cycle uint) + (num-cycles uint)) + (begin + ;; amount must be valid + (asserts! (> amount-ustx u0) + (err ERR_STACKING_INVALID_AMOUNT)) + + ;; sender principal must not have rejected in this upcoming reward cycle + (asserts! (is-none (get-pox-rejection tx-sender first-reward-cycle)) + (err ERR_STACKING_ALREADY_REJECTED)) + + ;; lock period must be in acceptable range. + (asserts! (check-pox-lock-period num-cycles) + (err ERR_STACKING_INVALID_LOCK_PERIOD)) + + ;; address version must be valid + (asserts! (check-pox-addr-version (get version pox-addr)) + (err ERR_STACKING_INVALID_POX_ADDRESS)) + + ;; address hashbytes must be valid for the version + (asserts! (check-pox-addr-hashbytes (get version pox-addr) (get hashbytes pox-addr)) + (err ERR_STACKING_INVALID_POX_ADDRESS)) + + (ok true))) + +;; Revoke contract-caller authorization to call stacking methods +(define-public (disallow-contract-caller (caller principal)) + (begin + (asserts! (is-eq tx-sender contract-caller) + (err ERR_STACKING_PERMISSION_DENIED)) + (ok (map-delete allowance-contract-callers { sender: tx-sender, contract-caller: caller })))) + +;; Give a contract-caller authorization to call stacking methods +;; normally, stacking methods may only be invoked by _direct_ transactions +;; (i.e., the tx-sender issues a direct contract-call to the stacking methods) +;; by issuing an allowance, the tx-sender may call through the allowed contract +(define-public (allow-contract-caller (caller principal) (until-burn-ht (optional uint))) + (begin + (asserts! (is-eq tx-sender contract-caller) + (err ERR_STACKING_PERMISSION_DENIED)) + (ok (map-set allowance-contract-callers + { sender: tx-sender, contract-caller: caller } + { until-burn-ht: until-burn-ht })))) + +;; Lock up some uSTX for stacking! Note that the given amount here is in micro-STX (uSTX). +;; The STX will be locked for the given number of reward cycles (lock-period). +;; This is the self-service interface. tx-sender will be the Stacker. +;; +;; * The given stacker cannot currently be stacking. +;; * You will need the minimum uSTX threshold. This will be determined by (get-stacking-minimum) +;; at the time this method is called. +;; * You may need to increase the amount of uSTX locked up later, since the minimum uSTX threshold +;; may increase between reward cycles. +;; * The Stacker will receive rewards in the reward cycle following `start-burn-ht`. +;; Importantly, `start-burn-ht` may not be further into the future than the next reward cycle, +;; and in most cases should be set to the current burn block height. +;; +;; The tokens will unlock and be returned to the Stacker (tx-sender) automatically. +(define-public (stack-stx (amount-ustx uint) + (pox-addr (tuple (version (buff 1)) (hashbytes (buff 32)))) + (start-burn-ht uint) + (lock-period uint)) + ;; this stacker's first reward cycle is the _next_ reward cycle + (let ((first-reward-cycle (+ u1 (current-pox-reward-cycle))) + (specified-reward-cycle (+ u1 (burn-height-to-reward-cycle start-burn-ht)))) + ;; the start-burn-ht must result in the next reward cycle, do not allow stackers + ;; to "post-date" their `stack-stx` transaction + (asserts! (is-eq first-reward-cycle specified-reward-cycle) + (err ERR_INVALID_START_BURN_HEIGHT)) + + ;; must be called directly by the tx-sender or by an allowed contract-caller + (asserts! (check-caller-allowed) + (err ERR_STACKING_PERMISSION_DENIED)) + + ;; tx-sender principal must not be stacking + (asserts! (is-none (get-stacker-info tx-sender)) + (err ERR_STACKING_ALREADY_STACKED)) + + ;; tx-sender must not be delegating + (asserts! (is-none (get-check-delegation tx-sender)) + (err ERR_STACKING_ALREADY_DELEGATED)) + + ;; the Stacker must have sufficient unlocked funds + (asserts! (>= (stx-get-balance tx-sender) amount-ustx) + (err ERR_STACKING_INSUFFICIENT_FUNDS)) + + ;; ensure that stacking can be performed + (try! (can-stack-stx pox-addr amount-ustx first-reward-cycle lock-period)) + + ;; register the PoX address with the amount stacked + (let ((reward-set-indexes (try! (add-pox-addr-to-reward-cycles pox-addr first-reward-cycle lock-period amount-ustx tx-sender)))) + ;; add stacker record + (map-set stacking-state + { stacker: tx-sender } + { pox-addr: pox-addr, + reward-set-indexes: reward-set-indexes, + first-reward-cycle: first-reward-cycle, + lock-period: lock-period, + delegated-to: none }) + + ;; return the lock-up information, so the node can actually carry out the lock. + (ok { stacker: tx-sender, lock-amount: amount-ustx, unlock-burn-height: (reward-cycle-to-burn-height (+ first-reward-cycle lock-period)) })))) + +(define-public (revoke-delegate-stx) + (begin + ;; must be called directly by the tx-sender or by an allowed contract-caller + (asserts! (check-caller-allowed) + (err ERR_STACKING_PERMISSION_DENIED)) + (ok (map-delete delegation-state { stacker: tx-sender })))) + +;; Delegate to `delegate-to` the ability to stack from a given address. +;; This method _does not_ lock the funds, rather, it allows the delegate +;; to issue the stacking lock. +;; The caller specifies: +;; * amount-ustx: the total amount of ustx the delegate may be allowed to lock +;; * until-burn-ht: an optional burn height at which this delegation expires +;; * pox-addr: an optional address to which any rewards *must* be sent +(define-public (delegate-stx (amount-ustx uint) + (delegate-to principal) + (until-burn-ht (optional uint)) + (pox-addr (optional { version: (buff 1), + hashbytes: (buff 32) }))) + (begin + ;; must be called directly by the tx-sender or by an allowed contract-caller + (asserts! (check-caller-allowed) + (err ERR_STACKING_PERMISSION_DENIED)) + + ;; delegate-stx no longer requires the delegator to not currently + ;; be stacking. + ;; delegate-stack-* functions assert that + ;; 1. users can't swim in two pools at the same time. + ;; 2. users can't switch pools without cool down cycle. + ;; Other pool admins can't increase or extend. + ;; 3. users can't join a pool while already directly stacking. + + ;; pox-addr, if given, must be valid + (match pox-addr + address + (asserts! (check-pox-addr-version (get version address)) + (err ERR_STACKING_INVALID_POX_ADDRESS)) + true) + + ;; tx-sender must not be delegating + (asserts! (is-none (get-check-delegation tx-sender)) + (err ERR_STACKING_ALREADY_DELEGATED)) + + ;; add delegation record + (map-set delegation-state + { stacker: tx-sender } + { amount-ustx: amount-ustx, + delegated-to: delegate-to, + until-burn-ht: until-burn-ht, + pox-addr: pox-addr }) + + (ok true))) + +;; Commit partially stacked STX and allocate a new PoX reward address slot. +;; This allows a stacker/delegate to lock fewer STX than the minimal threshold in multiple transactions, +;; so long as: 1. The pox-addr is the same. +;; 2. This "commit" transaction is called _before_ the PoX anchor block. +;; This ensures that each entry in the reward set returned to the stacks-node is greater than the threshold, +;; but does not require it be all locked up within a single transaction +;; +;; Returns (ok uint) on success, where the given uint is the reward address's index in the list of reward +;; addresses allocated in this reward cycle. This index can then be passed to `stack-aggregation-increase` +;; to later increment the STX this PoX address represents, in amounts less than the stacking minimum. +;; +;; *New in Stacks 2.1.* +(define-private (inner-stack-aggregation-commit (pox-addr { version: (buff 1), hashbytes: (buff 32) }) + (reward-cycle uint)) + (let ((partial-stacked + ;; fetch the partial commitments + (unwrap! (map-get? partial-stacked-by-cycle { pox-addr: pox-addr, sender: tx-sender, reward-cycle: reward-cycle }) + (err ERR_STACKING_NO_SUCH_PRINCIPAL)))) + ;; must be called directly by the tx-sender or by an allowed contract-caller + (asserts! (check-caller-allowed) + (err ERR_STACKING_PERMISSION_DENIED)) + (let ((amount-ustx (get stacked-amount partial-stacked))) + (try! (can-stack-stx pox-addr amount-ustx reward-cycle u1)) + ;; Add the pox addr to the reward cycle, and extract the index of the PoX address + ;; so the delegator can later use it to call stack-aggregation-increase. + (let ((add-pox-addr-info + (add-pox-addr-to-ith-reward-cycle + u0 + { pox-addr: pox-addr, + first-reward-cycle: reward-cycle, + num-cycles: u1, + reward-set-indexes: (list), + stacker: none, + amount-ustx: amount-ustx, + i: u0 })) + (pox-addr-index (unwrap-panic + (element-at (get reward-set-indexes add-pox-addr-info) u0)))) + + ;; don't update the stacking-state map, + ;; because it _already has_ this stacker's state + ;; don't lock the STX, because the STX is already locked + ;; + ;; clear the partial-stacked state, and log it + (map-delete partial-stacked-by-cycle { pox-addr: pox-addr, sender: tx-sender, reward-cycle: reward-cycle }) + (map-set logged-partial-stacked-by-cycle { pox-addr: pox-addr, sender: tx-sender, reward-cycle: reward-cycle } partial-stacked) + (ok pox-addr-index))))) + +;; Legacy interface for stack-aggregation-commit. +;; Wraps inner-stack-aggregation-commit. See its docstring for details. +;; Returns (ok true) on success +;; Returns (err ...) on failure. +(define-public (stack-aggregation-commit (pox-addr { version: (buff 1), hashbytes: (buff 32) }) + (reward-cycle uint)) + (match (inner-stack-aggregation-commit pox-addr reward-cycle) + pox-addr-index (ok true) + commit-err (err commit-err))) + +;; Public interface to `inner-stack-aggregation-commit`. See its documentation for details. +;; *New in Stacks 2.1.* +(define-public (stack-aggregation-commit-indexed (pox-addr { version: (buff 1), hashbytes: (buff 32) }) + (reward-cycle uint)) + (inner-stack-aggregation-commit pox-addr reward-cycle)) + +;; Commit partially stacked STX to a PoX address which has already received some STX (more than the Stacking min). +;; This allows a delegator to lock up marginally more STX from new delegates, even if they collectively do not +;; exceed the Stacking minimum, so long as the target PoX address already represents at least as many STX as the +;; Stacking minimum. +;; +;; The `reward-cycle-index` is emitted as a contract event from `stack-aggregation-commit` when the initial STX are +;; locked up by this delegator. It must be passed here to add more STX behind this PoX address. If the delegator +;; called `stack-aggregation-commit` multiple times for the same PoX address, then any such `reward-cycle-index` will +;; work here. +;; +;; *New in Stacks 2.1* +;; +(define-public (stack-aggregation-increase (pox-addr { version: (buff 1), hashbytes: (buff 32) }) + (reward-cycle uint) + (reward-cycle-index uint)) + (let ((partial-stacked + ;; fetch the partial commitments + (unwrap! (map-get? partial-stacked-by-cycle { pox-addr: pox-addr, sender: tx-sender, reward-cycle: reward-cycle }) + (err ERR_STACKING_NO_SUCH_PRINCIPAL)))) + + ;; must be called directly by the tx-sender or by an allowed contract-caller + (asserts! (check-caller-allowed) + (err ERR_STACKING_PERMISSION_DENIED)) + + ;; reward-cycle must be in the future + (asserts! (> reward-cycle (current-pox-reward-cycle)) + (err ERR_STACKING_INVALID_LOCK_PERIOD)) + + (let ((amount-ustx (get stacked-amount partial-stacked)) + ;; reward-cycle must point to an existing record in reward-cycle-total-stacked + ;; infallible; getting something from partial-stacked-by-cycle succeeded so this must succeed + (existing-total (unwrap-panic (map-get? reward-cycle-total-stacked { reward-cycle: reward-cycle }))) + ;; reward-cycle and reward-cycle-index must point to an existing record in reward-cycle-pox-address-list + (existing-entry (unwrap! (map-get? reward-cycle-pox-address-list { reward-cycle: reward-cycle, index: reward-cycle-index }) + (err ERR_DELEGATION_NO_REWARD_SLOT))) + (increased-ustx (+ (get total-ustx existing-entry) amount-ustx)) + (total-ustx (+ (get total-ustx existing-total) amount-ustx))) + + ;; must be stackable + (try! (minimal-can-stack-stx pox-addr total-ustx reward-cycle u1)) + + ;; new total must exceed the stacking minimum + (asserts! (<= (get-stacking-minimum) total-ustx) + (err ERR_STACKING_THRESHOLD_NOT_MET)) + + ;; there must *not* be a stacker entry (since this is a delegator) + (asserts! (is-none (get stacker existing-entry)) + (err ERR_DELEGATION_WRONG_REWARD_SLOT)) + + ;; the given PoX address must match the one on record + (asserts! (is-eq pox-addr (get pox-addr existing-entry)) + (err ERR_DELEGATION_WRONG_REWARD_SLOT)) + + ;; update the pox-address list -- bump the total-ustx + (map-set reward-cycle-pox-address-list + { reward-cycle: reward-cycle, index: reward-cycle-index } + { pox-addr: pox-addr, + total-ustx: increased-ustx, + stacker: none }) + + ;; update the total ustx in this cycle + (map-set reward-cycle-total-stacked + { reward-cycle: reward-cycle } + { total-ustx: total-ustx }) + + ;; don't update the stacking-state map, + ;; because it _already has_ this stacker's state + ;; don't lock the STX, because the STX is already locked + ;; + ;; clear the partial-stacked state, and log it + (map-delete partial-stacked-by-cycle { pox-addr: pox-addr, sender: tx-sender, reward-cycle: reward-cycle }) + (map-set logged-partial-stacked-by-cycle { pox-addr: pox-addr, sender: tx-sender, reward-cycle: reward-cycle } partial-stacked) + (ok true)))) + +;; As a delegate, stack the given principal's STX using partial-stacked-by-cycle +;; Once the delegate has stacked > minimum, the delegate should call stack-aggregation-commit +(define-public (delegate-stack-stx (stacker principal) + (amount-ustx uint) + (pox-addr { version: (buff 1), hashbytes: (buff 32) }) + (start-burn-ht uint) + (lock-period uint)) + ;; this stacker's first reward cycle is the _next_ reward cycle + (let ((first-reward-cycle (+ u1 (current-pox-reward-cycle))) + (specified-reward-cycle (+ u1 (burn-height-to-reward-cycle start-burn-ht))) + (unlock-burn-height (reward-cycle-to-burn-height (+ (current-pox-reward-cycle) u1 lock-period)))) + ;; the start-burn-ht must result in the next reward cycle, do not allow stackers + ;; to "post-date" their `stack-stx` transaction + (asserts! (is-eq first-reward-cycle specified-reward-cycle) + (err ERR_INVALID_START_BURN_HEIGHT)) + + ;; must be called directly by the tx-sender or by an allowed contract-caller + (asserts! (check-caller-allowed) + (err ERR_STACKING_PERMISSION_DENIED)) + + ;; stacker must have delegated to the caller + (let ((delegation-info (unwrap! (get-check-delegation stacker) (err ERR_STACKING_PERMISSION_DENIED)))) + ;; must have delegated to tx-sender + (asserts! (is-eq (get delegated-to delegation-info) tx-sender) + (err ERR_STACKING_PERMISSION_DENIED)) + ;; must have delegated enough stx + (asserts! (>= (get amount-ustx delegation-info) amount-ustx) + (err ERR_DELEGATION_TOO_MUCH_LOCKED)) + ;; if pox-addr is set, must be equal to pox-addr + (asserts! (match (get pox-addr delegation-info) + specified-pox-addr (is-eq pox-addr specified-pox-addr) + true) + (err ERR_DELEGATION_POX_ADDR_REQUIRED)) + ;; delegation must not expire before lock period + (asserts! (match (get until-burn-ht delegation-info) + until-burn-ht (>= until-burn-ht + unlock-burn-height) + true) + (err ERR_DELEGATION_EXPIRES_DURING_LOCK))) + + ;; stacker principal must not be stacking + (asserts! (is-none (get-stacker-info stacker)) + (err ERR_STACKING_ALREADY_STACKED)) + + ;; the Stacker must have sufficient unlocked funds + (asserts! (>= (stx-get-balance stacker) amount-ustx) + (err ERR_STACKING_INSUFFICIENT_FUNDS)) + + ;; ensure that stacking can be performed + (try! (minimal-can-stack-stx pox-addr amount-ustx first-reward-cycle lock-period)) + + ;; register the PoX address with the amount stacked via partial stacking + ;; before it can be included in the reward set, this must be committed! + (add-pox-partial-stacked pox-addr first-reward-cycle lock-period amount-ustx) + + ;; add stacker record + (map-set stacking-state + { stacker: stacker } + { pox-addr: pox-addr, + first-reward-cycle: first-reward-cycle, + reward-set-indexes: (list), + lock-period: lock-period, + delegated-to: (some tx-sender) }) + + ;; return the lock-up information, so the node can actually carry out the lock. + (ok { stacker: stacker, + lock-amount: amount-ustx, + unlock-burn-height: unlock-burn-height }))) + +;; Reject Stacking for this reward cycle. +;; tx-sender votes all its uSTX for rejection. +;; Note that unlike PoX, rejecting PoX does not lock the tx-sender's +;; tokens. PoX rejection acts like a coin vote. +(define-public (reject-pox) + (let ( + (balance (stx-get-balance tx-sender)) + (vote-reward-cycle (+ u1 (current-pox-reward-cycle))) + ) + + ;; tx-sender principal must not have rejected in this upcoming reward cycle + (asserts! (is-none (get-pox-rejection tx-sender vote-reward-cycle)) + (err ERR_STACKING_ALREADY_REJECTED)) + + ;; tx-sender can't be a stacker + (asserts! (is-none (get-stacker-info tx-sender)) + (err ERR_STACKING_ALREADY_STACKED)) + + ;; vote for rejection + (map-set stacking-rejection + { reward-cycle: vote-reward-cycle } + { amount: (+ (next-cycle-rejection-votes) balance) } + ) + + ;; mark voted + (map-set stacking-rejectors + { stacker: tx-sender, reward-cycle: vote-reward-cycle } + { amount: balance } + ) + + (ok true)) +) + +;; Used for PoX parameters discovery +(define-read-only (get-pox-info) + (ok { + min-amount-ustx: (get-stacking-minimum), + reward-cycle-id: (current-pox-reward-cycle), + prepare-cycle-length: (var-get pox-prepare-cycle-length), + first-burnchain-block-height: (var-get first-burnchain-block-height), + reward-cycle-length: (var-get pox-reward-cycle-length), + rejection-fraction: (var-get pox-rejection-fraction), + current-rejection-votes: (next-cycle-rejection-votes), + total-liquid-supply-ustx: stx-liquid-supply, + }) +) + +;; Update the number of stacked STX in a given reward cycle entry. +;; `reward-cycle-index` is the index into the `reward-cycle-pox-address-list` map for a given reward cycle number. +;; `updates`, if `(some ..)`, encodes which PoX reward cycle entry (if any) gets updated. In particular, it must have +;; `(some stacker)` as the listed stacker, and must be an upcoming reward cycle. +(define-private (increase-reward-cycle-entry + (reward-cycle-index uint) + (updates (optional { first-cycle: uint, reward-cycle: uint, stacker: principal, add-amount: uint }))) + (let ((data (try! updates)) + (first-cycle (get first-cycle data)) + (reward-cycle (get reward-cycle data))) + (if (> first-cycle reward-cycle) + ;; not at first cycle to process yet + (some { first-cycle: first-cycle, reward-cycle: (+ u1 reward-cycle), stacker: (get stacker data), add-amount: (get add-amount data) }) + (let ((existing-entry (unwrap-panic (map-get? reward-cycle-pox-address-list { reward-cycle: reward-cycle, index: reward-cycle-index }))) + (existing-total (unwrap-panic (map-get? reward-cycle-total-stacked { reward-cycle: reward-cycle }))) + (add-amount (get add-amount data)) + (total-ustx (+ (get total-ustx existing-total) add-amount))) + ;; stacker must match + (asserts! (is-eq (get stacker existing-entry) (some (get stacker data))) none) + ;; update the pox-address list + (map-set reward-cycle-pox-address-list + { reward-cycle: reward-cycle, index: reward-cycle-index } + { pox-addr: (get pox-addr existing-entry), + ;; This addresses the bug in pox-2 (see SIP-022) + total-ustx: (+ (get total-ustx existing-entry) add-amount), + stacker: (some (get stacker data)) }) + ;; update the total + (map-set reward-cycle-total-stacked + { reward-cycle: reward-cycle } + { total-ustx: total-ustx }) + (some { first-cycle: first-cycle, + reward-cycle: (+ u1 reward-cycle), + stacker: (get stacker data), + add-amount: (get add-amount data) }))))) + +;; Increase the number of STX locked. +;; *New in Stacks 2.1* +;; This method locks up an additional amount of STX from `tx-sender`'s, indicated +;; by `increase-by`. The `tx-sender` must already be Stacking. +(define-public (stack-increase (increase-by uint)) + (let ((stacker-info (stx-account tx-sender)) + (amount-stacked (get locked stacker-info)) + (amount-unlocked (get unlocked stacker-info)) + (unlock-height (get unlock-height stacker-info)) + (cur-cycle (current-pox-reward-cycle)) + (first-increased-cycle (+ cur-cycle u1)) + (stacker-state (unwrap! (map-get? stacking-state + { stacker: tx-sender }) + (err ERR_STACK_INCREASE_NOT_LOCKED)))) + ;; tx-sender must be currently locked + (asserts! (> amount-stacked u0) + (err ERR_STACK_INCREASE_NOT_LOCKED)) + ;; must be called with positive `increase-by` + (asserts! (>= increase-by u1) + (err ERR_STACKING_INVALID_AMOUNT)) + ;; stacker must have enough stx to lock + (asserts! (>= amount-unlocked increase-by) + (err ERR_STACKING_INSUFFICIENT_FUNDS)) + ;; must be called directly by the tx-sender or by an allowed contract-caller + (asserts! (check-caller-allowed) + (err ERR_STACKING_PERMISSION_DENIED)) + ;; stacker must be directly stacking + (asserts! (> (len (get reward-set-indexes stacker-state)) u0) + (err ERR_STACKING_IS_DELEGATED)) + ;; stacker must not be delegating + (asserts! (is-none (get delegated-to stacker-state)) + (err ERR_STACKING_IS_DELEGATED)) + ;; update reward cycle amounts + (asserts! (is-some (fold increase-reward-cycle-entry + (get reward-set-indexes stacker-state) + (some { first-cycle: first-increased-cycle, + reward-cycle: (get first-reward-cycle stacker-state), + stacker: tx-sender, + add-amount: increase-by }))) + (err ERR_STACKING_UNREACHABLE)) + ;; NOTE: stacking-state map is unchanged: it does not track amount-stacked in PoX-4 + (ok { stacker: tx-sender, total-locked: (+ amount-stacked increase-by)}))) + +;; Extend an active Stacking lock. +;; *New in Stacks 2.1* +;; This method extends the `tx-sender`'s current lockup for an additional `extend-count` +;; and associates `pox-addr` with the rewards +(define-public (stack-extend (extend-count uint) + (pox-addr { version: (buff 1), hashbytes: (buff 32) })) + (let ((stacker-info (stx-account tx-sender)) + ;; to extend, there must already be an etry in the stacking-state + (stacker-state (unwrap! (get-stacker-info tx-sender) (err ERR_STACK_EXTEND_NOT_LOCKED))) + (amount-ustx (get locked stacker-info)) + (unlock-height (get unlock-height stacker-info)) + (cur-cycle (current-pox-reward-cycle)) + ;; first-extend-cycle will be the cycle in which tx-sender *would have* unlocked + (first-extend-cycle (burn-height-to-reward-cycle unlock-height)) + ;; new first cycle should be max(cur-cycle, stacker-state.first-reward-cycle) + (cur-first-reward-cycle (get first-reward-cycle stacker-state)) + (first-reward-cycle (if (> cur-cycle cur-first-reward-cycle) cur-cycle cur-first-reward-cycle))) + + ;; must be called with positive extend-count + (asserts! (>= extend-count u1) + (err ERR_STACKING_INVALID_LOCK_PERIOD)) + + ;; stacker must be directly stacking + (asserts! (> (len (get reward-set-indexes stacker-state)) u0) + (err ERR_STACKING_IS_DELEGATED)) + + ;; stacker must not be delegating + (asserts! (is-none (get delegated-to stacker-state)) + (err ERR_STACKING_IS_DELEGATED)) + + ;; TODO: add more assertions to sanity check the `stacker-info` values with + ;; the `stacker-state` values + + (let ((last-extend-cycle (- (+ first-extend-cycle extend-count) u1)) + (lock-period (+ u1 (- last-extend-cycle first-reward-cycle))) + (new-unlock-ht (reward-cycle-to-burn-height (+ u1 last-extend-cycle)))) + + ;; first cycle must be after the current cycle + (asserts! (> first-extend-cycle cur-cycle) (err ERR_STACKING_INVALID_LOCK_PERIOD)) + ;; lock period must be positive + (asserts! (> lock-period u0) (err ERR_STACKING_INVALID_LOCK_PERIOD)) + + ;; must be called directly by the tx-sender or by an allowed contract-caller + (asserts! (check-caller-allowed) + (err ERR_STACKING_PERMISSION_DENIED)) + + ;; tx-sender must be locked + (asserts! (> amount-ustx u0) + (err ERR_STACK_EXTEND_NOT_LOCKED)) + + ;; tx-sender must not be delegating + (asserts! (is-none (get-check-delegation tx-sender)) + (err ERR_STACKING_ALREADY_DELEGATED)) + + ;; standard can-stack-stx checks + (try! (can-stack-stx pox-addr amount-ustx first-extend-cycle lock-period)) + + ;; register the PoX address with the amount stacked + ;; for the new cycles + (let ((extended-reward-set-indexes (try! (add-pox-addr-to-reward-cycles pox-addr first-extend-cycle extend-count amount-ustx tx-sender))) + (reward-set-indexes + ;; use the active stacker state and extend the existing reward-set-indexes + (let ((cur-cycle-index (- first-reward-cycle (get first-reward-cycle stacker-state))) + (old-indexes (get reward-set-indexes stacker-state)) + ;; build index list by taking the old-indexes starting from cur cycle + ;; and adding the new indexes to it. this way, the index is valid starting from the current cycle + (new-list (concat (default-to (list) (slice? old-indexes cur-cycle-index (len old-indexes))) + extended-reward-set-indexes))) + (unwrap-panic (as-max-len? new-list u12))))) + ;; update stacker record + (map-set stacking-state + { stacker: tx-sender } + { pox-addr: pox-addr, + reward-set-indexes: reward-set-indexes, + first-reward-cycle: first-reward-cycle, + lock-period: lock-period, + delegated-to: none }) + + ;; return lock-up information + (ok { stacker: tx-sender, unlock-burn-height: new-unlock-ht }))))) + +;; As a delegator, increase an active Stacking lock, issuing a "partial commitment" for the +;; increased cycles. +;; *New in Stacks 2.1* +;; This method increases `stacker`'s current lockup and partially commits the additional +;; STX to `pox-addr` +(define-public (delegate-stack-increase + (stacker principal) + (pox-addr { version: (buff 1), hashbytes: (buff 32) }) + (increase-by uint)) + (let ((stacker-info (stx-account stacker)) + (existing-lock (get locked stacker-info)) + (available-stx (get unlocked stacker-info)) + (unlock-height (get unlock-height stacker-info))) + + ;; must be called with positive `increase-by` + (asserts! (>= increase-by u1) + (err ERR_STACKING_INVALID_AMOUNT)) + + (let ((unlock-in-cycle (burn-height-to-reward-cycle unlock-height)) + (cur-cycle (current-pox-reward-cycle)) + (first-increase-cycle (+ cur-cycle u1)) + (last-increase-cycle (- unlock-in-cycle u1)) + (cycle-count (try! (if (<= first-increase-cycle last-increase-cycle) + (ok (+ u1 (- last-increase-cycle first-increase-cycle))) + (err ERR_STACKING_INVALID_LOCK_PERIOD)))) + (new-total-locked (+ increase-by existing-lock)) + (stacker-state + (unwrap! (map-get? stacking-state { stacker: stacker }) + (err ERR_STACK_INCREASE_NOT_LOCKED)))) + + ;; must be called directly by the tx-sender or by an allowed contract-caller + (asserts! (check-caller-allowed) + (err ERR_STACKING_PERMISSION_DENIED)) + + ;; stacker must not be directly stacking + (asserts! (is-eq (len (get reward-set-indexes stacker-state)) u0) + (err ERR_STACKING_NOT_DELEGATED)) + + ;; stacker must be delegated to tx-sender + (asserts! (is-eq (unwrap! (get delegated-to stacker-state) + (err ERR_STACKING_NOT_DELEGATED)) + tx-sender) + (err ERR_STACKING_PERMISSION_DENIED)) + + ;; stacker must be currently locked + (asserts! (> existing-lock u0) + (err ERR_STACK_INCREASE_NOT_LOCKED)) + + ;; stacker must have enough stx to lock + (asserts! (>= available-stx increase-by) + (err ERR_STACKING_INSUFFICIENT_FUNDS)) + + ;; stacker must have delegated to the caller + (let ((delegation-info (unwrap! (get-check-delegation stacker) (err ERR_STACKING_PERMISSION_DENIED))) + (delegated-to (get delegated-to delegation-info)) + (delegated-amount (get amount-ustx delegation-info)) + (delegated-pox-addr (get pox-addr delegation-info)) + (delegated-until (get until-burn-ht delegation-info))) + ;; must have delegated to tx-sender + (asserts! (is-eq delegated-to tx-sender) + (err ERR_STACKING_PERMISSION_DENIED)) + ;; must have delegated enough stx + (asserts! (>= delegated-amount new-total-locked) + (err ERR_DELEGATION_TOO_MUCH_LOCKED)) + ;; if pox-addr is set, must be equal to pox-addr + (asserts! (match delegated-pox-addr + specified-pox-addr (is-eq pox-addr specified-pox-addr) + true) + (err ERR_DELEGATION_POX_ADDR_REQUIRED)) + ;; delegation must not expire before lock period + (asserts! (match delegated-until + until-burn-ht + (>= until-burn-ht unlock-height) + true) + (err ERR_DELEGATION_EXPIRES_DURING_LOCK))) + + ;; delegate stacking does minimal-can-stack-stx + (try! (minimal-can-stack-stx pox-addr new-total-locked first-increase-cycle (+ u1 (- last-increase-cycle first-increase-cycle)))) + + ;; register the PoX address with the amount stacked via partial stacking + ;; before it can be included in the reward set, this must be committed! + (add-pox-partial-stacked pox-addr first-increase-cycle cycle-count increase-by) + + ;; stacking-state is unchanged, so no need to update + + ;; return the lock-up information, so the node can actually carry out the lock. + (ok { stacker: stacker, total-locked: new-total-locked})))) + +;; As a delegator, extend an active stacking lock, issuing a "partial commitment" for the +;; extended-to cycles. +;; *New in Stacks 2.1* +;; This method extends `stacker`'s current lockup for an additional `extend-count` +;; and partially commits those new cycles to `pox-addr` +(define-public (delegate-stack-extend + (stacker principal) + (pox-addr { version: (buff 1), hashbytes: (buff 32) }) + (extend-count uint)) + (let ((stacker-info (stx-account stacker)) + ;; to extend, there must already be an entry in the stacking-state + (stacker-state (unwrap! (get-stacker-info stacker) (err ERR_STACK_EXTEND_NOT_LOCKED))) + (amount-ustx (get locked stacker-info)) + (unlock-height (get unlock-height stacker-info)) + ;; first-extend-cycle will be the cycle in which tx-sender *would have* unlocked + (first-extend-cycle (burn-height-to-reward-cycle unlock-height)) + (cur-cycle (current-pox-reward-cycle)) + ;; new first cycle should be max(cur-cycle, stacker-state.first-reward-cycle) + (cur-first-reward-cycle (get first-reward-cycle stacker-state)) + (first-reward-cycle (if (> cur-cycle cur-first-reward-cycle) cur-cycle cur-first-reward-cycle))) + + ;; must be called with positive extend-count + (asserts! (>= extend-count u1) + (err ERR_STACKING_INVALID_LOCK_PERIOD)) + + (let ((last-extend-cycle (- (+ first-extend-cycle extend-count) u1)) + (lock-period (+ u1 (- last-extend-cycle first-reward-cycle))) + (new-unlock-ht (reward-cycle-to-burn-height (+ u1 last-extend-cycle)))) + + ;; first cycle must be after the current cycle + (asserts! (> first-extend-cycle cur-cycle) (err ERR_STACKING_INVALID_LOCK_PERIOD)) + ;; lock period must be positive + (asserts! (> lock-period u0) (err ERR_STACKING_INVALID_LOCK_PERIOD)) + + ;; must be called directly by the tx-sender or by an allowed contract-caller + (asserts! (check-caller-allowed) + (err ERR_STACKING_PERMISSION_DENIED)) + + ;; stacker must not be directly stacking + (asserts! (is-eq (len (get reward-set-indexes stacker-state)) u0) + (err ERR_STACKING_NOT_DELEGATED)) + + ;; stacker must be delegated to tx-sender + (asserts! (is-eq (unwrap! (get delegated-to stacker-state) + (err ERR_STACKING_NOT_DELEGATED)) + tx-sender) + (err ERR_STACKING_PERMISSION_DENIED)) + + ;; check valid lock period + (asserts! (check-pox-lock-period lock-period) + (err ERR_STACKING_INVALID_LOCK_PERIOD)) + + ;; stacker must be currently locked + (asserts! (> amount-ustx u0) + (err ERR_STACK_EXTEND_NOT_LOCKED)) + + ;; stacker must have delegated to the caller + (let ((delegation-info (unwrap! (get-check-delegation stacker) (err ERR_STACKING_PERMISSION_DENIED)))) + ;; must have delegated to tx-sender + (asserts! (is-eq (get delegated-to delegation-info) tx-sender) + (err ERR_STACKING_PERMISSION_DENIED)) + ;; must have delegated enough stx + (asserts! (>= (get amount-ustx delegation-info) amount-ustx) + (err ERR_DELEGATION_TOO_MUCH_LOCKED)) + ;; if pox-addr is set, must be equal to pox-addr + (asserts! (match (get pox-addr delegation-info) + specified-pox-addr (is-eq pox-addr specified-pox-addr) + true) + (err ERR_DELEGATION_POX_ADDR_REQUIRED)) + ;; delegation must not expire before lock period + (asserts! (match (get until-burn-ht delegation-info) + until-burn-ht (>= until-burn-ht + new-unlock-ht) + true) + (err ERR_DELEGATION_EXPIRES_DURING_LOCK))) + + ;; delegate stacking does minimal-can-stack-stx + (try! (minimal-can-stack-stx pox-addr amount-ustx first-extend-cycle lock-period)) + + ;; register the PoX address with the amount stacked via partial stacking + ;; before it can be included in the reward set, this must be committed! + (add-pox-partial-stacked pox-addr first-extend-cycle extend-count amount-ustx) + + (map-set stacking-state + { stacker: stacker } + { pox-addr: pox-addr, + reward-set-indexes: (list), + first-reward-cycle: first-reward-cycle, + lock-period: lock-period, + delegated-to: (some tx-sender) }) + + ;; return the lock-up information, so the node can actually carry out the lock. + (ok { stacker: stacker, + unlock-burn-height: new-unlock-ht })))) + +;; Get the _current_ PoX stacking delegation information for a stacker. If the information +;; is expired, or if there's never been such a stacker, then returns none. +;; *New in Stacks 2.1* +(define-read-only (get-delegation-info (stacker principal)) + (get-check-delegation stacker) +) + +;; Get the burn height at which a particular contract is allowed to stack for a particular principal. +;; *New in Stacks 2.1* +;; Returns (some (some X)) if X is the burn height at which the allowance terminates +;; Returns (some none) if the caller is allowed indefinitely +;; Returns none if there is no allowance record +(define-read-only (get-allowance-contract-callers (sender principal) (calling-contract principal)) + (map-get? allowance-contract-callers { sender: sender, contract-caller: calling-contract }) +) + +;; How many PoX addresses in this reward cycle? +;; *New in Stacks 2.1* +(define-read-only (get-num-reward-set-pox-addresses (reward-cycle uint)) + (match (map-get? reward-cycle-pox-address-list-len { reward-cycle: reward-cycle }) + num-addrs + (get len num-addrs) + u0 + ) +) + +;; How many uSTX have been locked up for this address so far, before the delegator commits them? +;; *New in Stacks 2.1* +(define-read-only (get-partial-stacked-by-cycle (pox-addr { version: (buff 1), hashbytes: (buff 32) }) (reward-cycle uint) (sender principal)) + (map-get? partial-stacked-by-cycle { pox-addr: pox-addr, reward-cycle: reward-cycle, sender: sender }) +) + +;; How many uSTX have voted to reject PoX in a given reward cycle? +;; *New in Stacks 2.1* +(define-read-only (get-total-pox-rejection (reward-cycle uint)) + (match (map-get? stacking-rejection { reward-cycle: reward-cycle }) + rejected + (get amount rejected) + u0 + ) +) + +;; What is the given reward cycle's stackers' aggregate public key? +;; *New in Stacks 3.0* +(define-read-only (get-aggregate-public-key (reward-cycle uint)) + (map-get? aggregate-public-keys reward-cycle) +) + +;; Set the aggregate public key to the provided value +;; *New in Stacks 3.0* +(define-private (set-aggregate-public-key (reward-cycle uint) (aggregate-public-key (buff 33))) + (begin + (ok (map-set aggregate-public-keys reward-cycle aggregate-public-key)) + ) +) diff --git a/components/clarity-repl/src/repl/datastore.rs b/components/clarity-repl/src/repl/datastore.rs index 325d7c5d3..28f0fad2a 100644 --- a/components/clarity-repl/src/repl/datastore.rs +++ b/components/clarity-repl/src/repl/datastore.rs @@ -437,10 +437,18 @@ impl BurnStateDB for BurnDatastore { 0 } + fn get_v3_unlock_height(&self) -> u32 { + 0 + } + fn get_pox_3_activation_height(&self) -> u32 { 0 } + fn get_pox_4_activation_height(&self) -> u32 { + 0 + } + /// Returns the *burnchain block height* for the `sortition_id` is associated with. fn get_burn_block_height(&self, sortition_id: &SortitionId) -> Option { self.sortition_lookup diff --git a/components/clarity-repl/src/repl/debug/dap/mod.rs b/components/clarity-repl/src/repl/debug/dap/mod.rs index 1c79cb1fa..d3e56207f 100644 --- a/components/clarity-repl/src/repl/debug/dap/mod.rs +++ b/components/clarity-repl/src/repl/debug/dap/mod.rs @@ -1,6 +1,8 @@ use std::collections::HashMap; use std::path::PathBuf; +use crate::repl::DEFAULT_EPOCH; + use super::{extract_watch_variable, AccessType, State}; use clarity::vm::callables::FunctionIdentifier; use clarity::vm::contexts::{ContractContext, GlobalContext}; @@ -692,7 +694,7 @@ impl DAPDebugger { let value = env .global_context .database - .lookup_variable(contract_id, name, data_types) + .lookup_variable(contract_id, name, data_types, &DEFAULT_EPOCH) .unwrap(); Response { request_seq: seq, @@ -910,6 +912,7 @@ impl DAPDebugger { &contract_context.contract_identifier, name.as_str(), data_types, + &DEFAULT_EPOCH, ) .unwrap(); variables.push(Variable { diff --git a/components/clarity-repl/src/repl/interpreter.rs b/components/clarity-repl/src/repl/interpreter.rs index b2c9b7d43..f0aa58133 100644 --- a/components/clarity-repl/src/repl/interpreter.rs +++ b/components/clarity-repl/src/repl/interpreter.rs @@ -6,16 +6,18 @@ use crate::analysis::{self}; use crate::repl::datastore::BurnDatastore; use crate::repl::datastore::Datastore; use crate::repl::Settings; +#[cfg(all(feature = "cli", not(feature = "wasm")))] +use clar2wasm::Module; use clarity::consts::CHAIN_ID_TESTNET; use clarity::vm::analysis::ContractAnalysis; use clarity::vm::ast::{build_ast_with_diagnostics, ContractAST}; +#[cfg(all(feature = "cli", not(feature = "wasm")))] +use clarity::vm::clarity_wasm::{call_function, initialize_contract}; use clarity::vm::contexts::{CallStack, ContractContext, Environment, GlobalContext, LocalContext}; use clarity::vm::contracts::Contract; - use clarity::vm::costs::{ExecutionCost, LimitedCostTracker}; use clarity::vm::database::{ClarityDatabase, StoreType}; use clarity::vm::diagnostic::{Diagnostic, Level}; -use clarity::vm::errors::Error; use clarity::vm::events::*; use clarity::vm::representations::SymbolicExpressionType::{Atom, List}; use clarity::vm::representations::{Span, SymbolicExpression}; @@ -28,7 +30,7 @@ use clarity::vm::{ContractEvaluationResult, EvalHook}; use clarity::vm::{CostSynthesis, ExecutionResult, ParsedContract}; use super::datastore::StacksConstants; -use super::{ClarityContract, DEFAULT_EPOCH}; +use super::{ClarityContract, ContractDeployer, DEFAULT_EPOCH}; pub const BLOCK_LIMIT_MAINNET: ExecutionCost = ExecutionCost { write_length: 15_000_000, @@ -116,46 +118,85 @@ impl ClarityInterpreter { } } - pub fn run( + pub fn run_both( &mut self, contract: &ClarityContract, + ast: &mut Option, cost_track: bool, eval_hooks: Option>, ) -> Result> { - let (mut ast, mut diagnostics, success) = self.build_ast(contract); + let result = self.run(contract, ast, cost_track, eval_hooks); + + // when running clarity-repl/wasm (ie. not natively), we can't run clar2wasm + #[cfg(all(feature = "cli", not(feature = "wasm")))] + if self.repl_settings.is_clarity_wasm_enabled() { + let mut contract_wasm = contract.clone(); + contract_wasm.deployer = + ContractDeployer::Address("ST3NBRSFKX28FQ2ZJ1MAKX58HKHSDGNV5N7R21XCP".into()); + let result_wasm = self.run_wasm(&contract_wasm, ast, cost_track, None); + match (result.clone(), result_wasm) { + (Ok(result), Ok(result_wasm)) => { + let value = match result.result { + EvaluationResult::Contract(contract_result) => contract_result.result, + EvaluationResult::Snippet(snippet_result) => Some(snippet_result.result), + }; + let value_wasm = match result_wasm.result { + EvaluationResult::Contract(contract_result) => contract_result.result, + EvaluationResult::Snippet(snippet_result) => Some(snippet_result.result), + }; + if value != value_wasm { + println!("values do not match"); + println!("value: {:?}", value); + println!("value_wasm: {:?}", value_wasm); + }; + } + (Ok(result), Err(error_wasm)) => { + println!("values do not match"); + println!("wasm error: {:?}", error_wasm); + println!("result: {:?}", result); + } + (Err(error), Ok(result_wasm)) => { + println!("values do not match"); + println!("result error: {:?}", error); + println!("result_wasm: {:?}", result_wasm); + } + (Err(error), Err(error_wasm)) => { + if error != error_wasm { + println!("values do not match"); + println!("result error: {:?}", error); + println!("wasm error: {:?}", error_wasm); + } + } + }; + } - self.run_ast( - contract, - &mut ast, - &mut diagnostics, - success, - cost_track, - eval_hooks, - ) + result } - pub fn run_ast( + pub fn run( &mut self, contract: &ClarityContract, - ast: &mut ContractAST, - diagnostics: &mut Vec, - success: bool, + ast: &mut Option, cost_track: bool, eval_hooks: Option>, ) -> Result> { + let (mut ast, mut diagnostics, success) = match ast { + Some(ast) => (ast.clone(), vec![], true), + None => self.build_ast(contract), + }; + let code_source = contract.expect_in_memory_code_source(); let (annotations, mut annotation_diagnostics) = self.collect_annotations(code_source); diagnostics.append(&mut annotation_diagnostics); let (analysis, mut analysis_diagnostics) = - match self.run_analysis(contract, ast, &annotations) { + match self.run_analysis(contract, &mut ast, &annotations) { Ok((analysis, diagnostics)) => (analysis, diagnostics), - Err((_, Some(diagnostic), _)) => { + Err(diagnostic) => { diagnostics.push(diagnostic); return Err(diagnostics.to_vec()); } - Err(_) => return Err(diagnostics.to_vec()), }; diagnostics.append(&mut analysis_diagnostics); @@ -163,7 +204,7 @@ impl ClarityInterpreter { return Err(diagnostics.to_vec()); } - let mut result = match self.execute(contract, ast, analysis, cost_track, eval_hooks) { + let mut result = match self.execute(contract, &mut ast, analysis, cost_track, eval_hooks) { Ok(result) => result, Err(e) => { diagnostics.push(Diagnostic { @@ -177,11 +218,109 @@ impl ClarityInterpreter { }; result.diagnostics = diagnostics.to_vec(); + Ok(result) + } + + #[cfg(all(feature = "cli", not(feature = "wasm")))] + pub fn run_wasm( + &mut self, + contract: &ClarityContract, + ast: &mut Option, + cost_track: bool, + eval_hooks: Option>, + ) -> Result> { + use clar2wasm::{compile, compile_contract, CompileError, CompileResult}; + + let contract_id = contract.expect_resolved_contract_identifier(Some(&self.tx_sender)); + let source = contract.expect_in_memory_code_source(); + let mut analysis_db = AnalysisDatabase::new(&mut self.datastore); + + let (mut ast, mut diagnostics, analysis, mut module) = match ast.take() { + Some(mut ast) => { + let mut diagnostics = vec![]; + let (annotations, annotation_diagnostics) = + self.collect_annotations(contract.expect_in_memory_code_source()); + diagnostics.extend(annotation_diagnostics); + + let (analysis, analysis_diagnostics) = + match self.run_analysis(contract, &mut ast, &annotations) { + Ok((analysis, diagnostics)) => (analysis, diagnostics), + Err(diagnostic) => { + diagnostics.push(diagnostic); + return Err(diagnostics.to_vec()); + } + }; + diagnostics.extend(analysis_diagnostics); - // todo: instead of just returning the value, we should be returning: - // - value - // - execution cost - // - events emitted + let module = match compile_contract(analysis.clone()) { + Ok(res) => res, + Err(e) => { + diagnostics.push(Diagnostic { + level: Level::Error, + message: format!("Wasm Generator Error: {:?}", e), + spans: vec![], + suggestion: None, + }); + return Err(diagnostics); + } + }; + (ast, diagnostics, analysis, module) + } + None => { + let CompileResult { + mut ast, + mut diagnostics, + module, + contract_analysis: _, + } = match compile( + source, + &contract_id, + LimitedCostTracker::new_free(), + contract.clarity_version, + contract.epoch, + &mut analysis_db, + ) { + Ok(res) => res, + Err(CompileError::Generic { diagnostics, .. }) => return Err(diagnostics), + }; + let (annotations, mut annotation_diagnostics) = + self.collect_annotations(contract.expect_in_memory_code_source()); + diagnostics.append(&mut annotation_diagnostics); + + let (analysis, mut analysis_diagnostics) = + match self.run_analysis(contract, &mut ast, &annotations) { + Ok((analysis, diagnostics)) => (analysis, diagnostics), + Err(diagnostic) => { + diagnostics.push(diagnostic); + return Err(diagnostics); + } + }; + diagnostics.append(&mut analysis_diagnostics); + (ast, diagnostics, analysis, module) + } + }; + + let mut result = match self.execute_wasm( + contract, + &mut ast, + analysis, + &mut module, + cost_track, + eval_hooks, + ) { + Ok(result) => result, + Err(e) => { + diagnostics.push(Diagnostic { + level: Level::Error, + message: format!("Wasm Runtime Error: {}", e), + spans: vec![], + suggestion: None, + }); + return Err(diagnostics.to_vec()); + } + }; + + result.diagnostics = diagnostics; Ok(result) } @@ -275,8 +414,7 @@ impl ClarityInterpreter { contract: &ClarityContract, contract_ast: &mut ContractAST, annotations: &Vec, - ) -> Result<(ContractAnalysis, Vec), (String, Option, Option)> - { + ) -> Result<(ContractAnalysis, Vec), Diagnostic> { let mut analysis_db = AnalysisDatabase::new(&mut self.datastore); // Run standard clarity analyses @@ -289,7 +427,7 @@ impl ClarityInterpreter { contract.epoch, contract.clarity_version, ) - .map_err(|(error, _)| ("Analysis".to_string(), Some(error.diagnostic), None))?; + .map_err(|(error, _)| error.diagnostic)?; // Run REPL-only analyses let diagnostics = analysis::run_analysis( @@ -298,11 +436,7 @@ impl ClarityInterpreter { annotations, &self.repl_settings.analysis, ) - .map_err(|mut diagnostics| { - // The last diagnostic should be the error - let error = diagnostics.pop().unwrap(); - ("Analysis".to_string(), Some(error), None) - })?; + .map_err(|mut diagnostics| diagnostics.pop().unwrap())?; Ok((contract_analysis, diagnostics)) } @@ -363,16 +497,6 @@ impl ClarityInterpreter { analysis_db.commit(); } - pub fn get_block_time(&mut self) -> u64 { - let block_height = self.get_block_height(); - let mut conn = ClarityDatabase::new( - &mut self.datastore, - &self.burn_datastore, - &self.burn_datastore, - ); - conn.get_block_time(block_height) - } - pub fn get_data_var( &mut self, contract_id: &QualifiedContractIdentifier, @@ -394,11 +518,11 @@ impl ClarityInterpreter { Some(format!("0x{value_hex}")) } - pub fn execute( + fn execute( &mut self, contract: &ClarityContract, contract_ast: &mut ContractAST, - contract_analysis: ContractAnalysis, + analysis: ContractAnalysis, cost_track: bool, eval_hooks: Option>, ) -> Result { @@ -454,9 +578,10 @@ impl ClarityInterpreter { None, ); - let result = match contract_ast.expressions[0].expr { - List(ref expression) => match expression[0].expr { - Atom(ref name) if name.to_string() == "contract-call?" => { + // call a function + if let List(expression) = &contract_ast.expressions[0].expr { + if let Atom(name) = &expression[0].expr { + if name.to_string() == "contract-call?" { let contract_id = match expression[1] .match_literal_value() .unwrap() @@ -470,19 +595,32 @@ impl ClarityInterpreter { let mut args = vec![]; for arg in expression[3..].iter() { let evaluated_arg = eval(arg, &mut env, &context)?; - args.push(SymbolicExpression::atom_value(evaluated_arg)); + args.push(evaluated_arg); } + + // INTERPRETER + let start = std::time::Instant::now(); + let args: Vec = args + .iter() + .map(|a| SymbolicExpression::atom_value(a.clone())) + .collect(); let res = env.execute_contract(&contract_id, &method, &args, false)?; - Ok(res) + println!("execute intr: {:?}μs", start.elapsed().as_micros()); + return Ok(Some(res)); } - _ => eval(&contract_ast.expressions[0], &mut env, &context), - }, - _ => eval(&contract_ast.expressions[0], &mut env, &context), + } }; - result.map(Some) - } else { - eval_all(&contract_ast.expressions, &mut contract_context, g, None) + + // INTERPRETER + let start = std::time::Instant::now(); + let result = eval(&contract_ast.expressions[0], &mut env, &context); + println!("execute intr: {:?}μs", start.elapsed().as_micros()); + + return result.map(Some); } + + // deploy a contract + eval_all(&contract_ast.expressions, &mut contract_context, g, None) }); let value = result.map_err(|e| { @@ -531,7 +669,7 @@ impl ClarityInterpreter { code: snippet.to_string(), function_args: functions, ast: contract_ast.clone(), - analysis: contract_analysis.clone(), + analysis: analysis.clone(), }; global_context @@ -585,7 +723,240 @@ impl ClarityInterpreter { if contract_saved { let mut analysis_db = AnalysisDatabase::new(&mut self.datastore); analysis_db - .execute(|db| db.insert_contract(&contract_id, &contract_analysis)) + .execute(|db| db.insert_contract(&contract_id, &analysis)) + .expect("Unable to save data"); + } + + Ok(execution_result) + } + + #[cfg(all(feature = "cli", not(feature = "wasm")))] + fn execute_wasm( + &mut self, + contract: &ClarityContract, + contract_ast: &mut ContractAST, + analysis: ContractAnalysis, + wasm_module: &mut Module, + cost_track: bool, + eval_hooks: Option>, + ) -> Result { + let contract_id = contract.expect_resolved_contract_identifier(Some(&self.tx_sender)); + let snippet = contract.expect_in_memory_code_source(); + let mut contract_context = + ContractContext::new(contract_id.clone(), contract.clarity_version); + + let mut conn = ClarityDatabase::new( + &mut self.datastore, + &self.burn_datastore, + &self.burn_datastore, + ); + let tx_sender: PrincipalData = self.tx_sender.clone().into(); + conn.begin(); + conn.set_clarity_epoch_version(contract.epoch); + conn.commit(); + let cost_tracker = if cost_track { + LimitedCostTracker::new( + false, + CHAIN_ID_TESTNET, + BLOCK_LIMIT_MAINNET.clone(), + &mut conn, + contract.epoch, + ) + .expect("failed to initialize cost tracker") + } else { + LimitedCostTracker::new_free() + }; + let mut global_context = + GlobalContext::new(false, CHAIN_ID_TESTNET, conn, cost_tracker, contract.epoch); + + if let Some(mut in_hooks) = eval_hooks { + let mut hooks: Vec<&mut dyn EvalHook> = Vec::new(); + for hook in in_hooks.drain(..) { + hooks.push(hook); + } + global_context.eval_hooks = Some(hooks); + } + + global_context.begin(); + + let result = global_context.execute(|g| { + if contract_ast.expressions.len() == 1 && !snippet.contains("(define-") { + let context = LocalContext::new(); + let mut call_stack = CallStack::new(); + let mut env = Environment::new( + g, + &contract_context, + &mut call_stack, + Some(tx_sender.clone()), + Some(tx_sender.clone()), + None, + ); + + // call a function + if let List(expression) = &contract_ast.expressions[0].expr { + if let Atom(name) = &expression[0].expr { + if name.to_string() == "contract-call?" { + let contract_id = match expression[1] + .match_literal_value() + .unwrap() + .clone() + .expect_principal() + { + PrincipalData::Contract(contract_id) => contract_id, + _ => unreachable!(), + }; + let method = expression[2].match_atom().unwrap().to_string(); + let mut args = vec![]; + for arg in expression[3..].iter() { + let evaluated_arg = eval(arg, &mut env, &context)?; + args.push(evaluated_arg); + } + + let called_contract = + env.global_context.database.get_contract(&contract_id)?; + + // CLAR2WASM + let start = std::time::Instant::now(); + + let res = match call_function( + &method, + &args, + g, + &called_contract.contract_context, + &mut call_stack, + Some(tx_sender.clone()), + Some(tx_sender), + None, + ) { + Ok(res) => res, + Err(e) => { + println!("Error while calling function: {:?}", e); + return Err(e); + } + }; + println!("execute wasm: {:?}", start.elapsed()); + return Ok(Some(res)); + } + } + }; + + // execute code + // let start = std::time::Instant::now(); + let start = std::time::Instant::now(); + contract_context.set_wasm_module(wasm_module.emit_wasm()); + let result = initialize_contract(g, &mut contract_context, None, &analysis) + .map(|v| v.unwrap_or(Value::none())); + println!("execute wasm: {:?}μs", start.elapsed().as_micros()); + + return result.map(Some); + } + + // deploy a contract + contract_context.set_wasm_module(wasm_module.emit_wasm()); + initialize_contract(g, &mut contract_context, None, &analysis) + }); + + let value = result.map_err(|e| { + let err = format!("Runtime error while interpreting {}: {:?}", contract_id, e); + if let Some(mut eval_hooks) = global_context.eval_hooks.take() { + for hook in eval_hooks.iter_mut() { + hook.did_complete(Err(err.clone())); + } + global_context.eval_hooks = Some(eval_hooks); + } + err + })?; + + let mut cost = None; + if cost_track { + cost = Some(CostSynthesis::from_cost_tracker(&global_context.cost_track)); + } + + let mut emitted_events = global_context + .event_batches + .iter() + .flat_map(|b| b.events.clone()) + .collect::>(); + + let contract_saved = + !contract_context.functions.is_empty() || !contract_context.defined_traits.is_empty(); + + let eval_result = if contract_saved { + let mut functions = BTreeMap::new(); + for (name, defined_func) in contract_context.functions.iter() { + if !defined_func.is_public() { + continue; + } + + let args: Vec<_> = defined_func + .get_arguments() + .iter() + .zip(defined_func.get_arg_types().iter()) + .map(|(n, t)| format!("({} {})", n.as_str(), t)) + .collect(); + + functions.insert(name.to_string(), args); + } + let parsed_contract = ParsedContract { + contract_identifier: contract_id.to_string(), + code: snippet.to_string(), + function_args: functions, + ast: contract_ast.clone(), + analysis: analysis.clone(), + }; + + global_context + .database + .insert_contract_hash(&contract_id, snippet) + .unwrap(); + let contract = Contract { contract_context }; + global_context + .database + .insert_contract(&contract_id, contract); + global_context + .database + .set_contract_data_size(&contract_id, 0) + .unwrap(); + + EvaluationResult::Contract(ContractEvaluationResult { + result: value, + contract: parsed_contract, + }) + } else { + let result = value.unwrap_or(Value::none()); + EvaluationResult::Snippet(SnippetEvaluationResult { result }) + }; + + global_context.commit().unwrap(); + + let (events, mut accounts_to_credit, mut accounts_to_debit) = + Self::process_events(&mut emitted_events); + + let mut execution_result = ExecutionResult { + result: eval_result, + events, + cost, + diagnostics: Vec::new(), + }; + + if let Some(mut eval_hooks) = global_context.eval_hooks { + for hook in eval_hooks.iter_mut() { + hook.did_complete(Ok(&mut execution_result)); + } + } + + for (account, token, value) in accounts_to_credit.drain(..) { + self.credit_token(account, token, value); + } + + for (account, token, value) in accounts_to_debit.drain(..) { + self.debit_token(account, token, value); + } + + if contract_saved { + let mut analysis_db = AnalysisDatabase::new(&mut self.datastore); + analysis_db + .execute(|db| db.insert_contract(&contract_id, &analysis)) .expect("Unable to save data"); } @@ -806,7 +1177,6 @@ impl ClarityInterpreter { #[cfg(test)] mod tests { - use super::*; use crate::test_fixtures::clarity_contract::ClarityContractBuilder; use clarity::{ @@ -823,14 +1193,6 @@ mod tests { assert_eq!(interpreter.get_tx_sender(), tx_sender); } - #[test] - fn test_get_block_time() { - let mut interpreter = - ClarityInterpreter::new(StandardPrincipalData::transient(), Settings::default()); - let bt = interpreter.get_block_time(); - assert_ne!(bt, 0); // TODO placeholder - } - #[test] fn test_set_tx_sender() { let mut interpreter = @@ -944,7 +1306,7 @@ mod tests { let mut interpreter = ClarityInterpreter::new(StandardPrincipalData::transient(), Settings::default()); let contract = ClarityContract::fixture(); - let result = interpreter.run(&contract, false, vec![].into()); + let result = interpreter.run(&contract, &mut None, false, None); assert!(result.is_ok()); assert!(result.unwrap().diagnostics.is_empty()); } @@ -959,7 +1321,7 @@ mod tests { let contract = ClarityContractBuilder::default() .code_source(snippet.into()) .build(); - let result = interpreter.run(&contract, false, vec![].into()); + let result = interpreter.run(&contract, &mut None, false, None); assert!(result.is_err()); let diagnostics = result.unwrap_err(); assert_eq!(diagnostics.len(), 1); @@ -974,7 +1336,7 @@ mod tests { let contract = ClarityContractBuilder::default() .code_source(snippet.into()) .build(); - let result = interpreter.run(&contract, false, vec![].into()); + let result = interpreter.run(&contract, &mut None, false, None); assert!(result.is_err()); let diagnostics = result.unwrap_err(); @@ -1027,6 +1389,20 @@ mod tests { assert!(events.is_empty()); } + #[test] + fn test_run_both() { + let mut interpreter = + ClarityInterpreter::new(StandardPrincipalData::transient(), Settings::default()); + + let contract = ClarityContract::fixture(); + let _ = interpreter.run_both(&contract, &mut None, false, None); + + let call_contract = ClarityContractBuilder::default() + .code_source("(contract-call? .contract incr)".to_owned()) + .build(); + let _ = interpreter.run_both(&call_contract, &mut None, false, None); + } + #[test] fn test_get_data_var() { let mut interpreter = diff --git a/components/clarity-repl/src/repl/mod.rs b/components/clarity-repl/src/repl/mod.rs index 8a8707f4b..c55e49fa1 100644 --- a/components/clarity-repl/src/repl/mod.rs +++ b/components/clarity-repl/src/repl/mod.rs @@ -84,6 +84,12 @@ impl Serialize for ClarityContract { StacksEpochId::Epoch24 => { map.serialize_entry("epoch", &2.4)?; } + StacksEpochId::Epoch25 => { + map.serialize_entry("epoch", &2.5)?; + } + StacksEpochId::Epoch30 => { + map.serialize_entry("epoch", &3.0)?; + } } map.end() } diff --git a/components/clarity-repl/src/repl/session.rs b/components/clarity-repl/src/repl/session.rs index 9c8747c82..9d26734ed 100644 --- a/components/clarity-repl/src/repl/session.rs +++ b/components/clarity-repl/src/repl/session.rs @@ -37,6 +37,7 @@ pub static BOOT_MAINNET_ADDRESS: &str = "SP000000000000000000002Q6VF78"; pub static V1_BOOT_CONTRACTS: &[&str] = &["bns"]; pub static V2_BOOT_CONTRACTS: &[&str] = &["pox-2", "costs-3"]; pub static V3_BOOT_CONTRACTS: &[&str] = &["pox-3"]; +pub static V4_BOOT_CONTRACTS: &[&str] = &["pox-4"]; lazy_static! { static ref BOOT_TESTNET_PRINCIPAL: StandardPrincipalData = @@ -45,7 +46,7 @@ lazy_static! { PrincipalData::parse_standard_principal(BOOT_MAINNET_ADDRESS).unwrap(); pub static ref BOOT_CONTRACTS_DATA: BTreeMap = { let mut result = BTreeMap::new(); - let deploy: [(&StandardPrincipalData, [(&str, &str); 10]); 2] = [ + let deploy: [(&StandardPrincipalData, [(&str, &str); 11]); 2] = [ (&*BOOT_TESTNET_PRINCIPAL, *STACKS_BOOT_CODE_TESTNET), (&*BOOT_MAINNET_PRINCIPAL, *STACKS_BOOT_CODE_MAINNET), ]; @@ -54,7 +55,9 @@ lazy_static! { ClarityInterpreter::new(StandardPrincipalData::transient(), Settings::default()); for (deployer, boot_code) in deploy.iter() { for (name, code) in boot_code.iter() { - let (epoch, clarity_version) = if (*name).eq("pox-3") { + let (epoch, clarity_version) = if (*name).eq("pox-4") { + (StacksEpochId::Epoch25, ClarityVersion::Clarity2) + } else if (*name).eq("pox-3") { (StacksEpochId::Epoch24, ClarityVersion::Clarity2) } else if (*name).eq("pox-2") || (*name).eq("costs-3") { (StacksEpochId::Epoch21, ClarityVersion::Clarity2) @@ -160,7 +163,9 @@ impl Session { .include_boot_contracts .contains(&name.to_string()) { - let (epoch, clarity_version) = if (*name).eq("pox-3") { + let (epoch, clarity_version) = if (*name).eq("pox-4") { + (StacksEpochId::Epoch25, ClarityVersion::Clarity2) + } else if (*name).eq("pox-3") { (StacksEpochId::Epoch24, ClarityVersion::Clarity2) } else if (*name).eq("pox-2") || (*name).eq("costs-3") { (StacksEpochId::Epoch21, ClarityVersion::Clarity2) @@ -508,18 +513,9 @@ impl Session { let contract_id = contract.expect_resolved_contract_identifier(Some(&self.interpreter.get_tx_sender())); - let result = if let Some(mut ast) = ast.take() { - self.interpreter.run_ast( - contract, - &mut ast, - &mut vec![], - true, - cost_track, - Some(hooks), - ) - } else { - self.interpreter.run(contract, cost_track, Some(hooks)) - }; + let result = self + .interpreter + .run_both(contract, ast, cost_track, Some(hooks)); match result { Ok(result) => { @@ -575,13 +571,17 @@ impl Session { }; self.set_tx_sender(sender.into()); - let execution = match self.interpreter.run(&contract_call, true, Some(hooks)) { - Ok(result) => result, - Err(e) => { - self.set_tx_sender(initial_tx_sender); - return Err(e); - } - }; + let execution = + match self + .interpreter + .run_both(&contract_call, &mut None, true, Some(hooks)) + { + Ok(result) => result, + Err(e) => { + self.set_tx_sender(initial_tx_sender); + return Err(e); + } + }; self.set_tx_sender(initial_tx_sender); self.coverage_reports.push(coverage); @@ -615,7 +615,9 @@ impl Session { let contract_identifier = contract.expect_resolved_contract_identifier(Some(&self.interpreter.get_tx_sender())); - let result = self.interpreter.run(&contract, cost_track, eval_hooks); + let result = self + .interpreter + .run_both(&contract, &mut None, cost_track, eval_hooks); match result { Ok(result) => { @@ -856,9 +858,11 @@ impl Session { Some("2.2") => StacksEpochId::Epoch22, Some("2.3") => StacksEpochId::Epoch23, Some("2.4") => StacksEpochId::Epoch24, + Some("2.5") => StacksEpochId::Epoch25, + Some("3.0") => StacksEpochId::Epoch30, _ => { return output.push(red!( - "Usage: ::set_epoch 2.0 | 2.05 | 2.1 | 2.2 | 2.3 | 2.4" + "Usage: ::set_epoch 2.0 | 2.05 | 2.1 | 2.2 | 2.3 | 2.4 | 2.5 | 3.0" )) } }; diff --git a/components/clarity-repl/src/repl/settings.rs b/components/clarity-repl/src/repl/settings.rs index 9d80dcda5..84476a2d1 100644 --- a/components/clarity-repl/src/repl/settings.rs +++ b/components/clarity-repl/src/repl/settings.rs @@ -54,6 +54,21 @@ pub struct SessionSettings { #[derive(Debug, Default, Clone, Deserialize, Serialize)] pub struct Settings { pub analysis: analysis::Settings, + enable_clarity_wasm: bool, +} + +impl Settings { + pub fn enable_clarity_wasm(&mut self) { + self.enable_clarity_wasm = true; + } + + pub fn disable_clarity_wasm(&mut self) { + self.enable_clarity_wasm = false; + } + + pub fn is_clarity_wasm_enabled(&self) -> bool { + self.enable_clarity_wasm + } } #[derive(Debug, Default, Clone, Deserialize, Serialize)] @@ -68,6 +83,9 @@ impl From for Settings { } else { analysis::Settings::default() }; - Self { analysis } + Self { + analysis, + enable_clarity_wasm: true, + } } } diff --git a/components/clarity-vscode/test-data/test-cases/settings/Devnet.toml b/components/clarity-vscode/test-data/test-cases/settings/Devnet.toml index 908d1c361..d41229fa6 100644 --- a/components/clarity-vscode/test-data/test-cases/settings/Devnet.toml +++ b/components/clarity-vscode/test-data/test-cases/settings/Devnet.toml @@ -76,7 +76,6 @@ disable_stacks_api = false # epoch_2_0 = 103 # epoch_2_05 = 104 # epoch_2_1 = 106 -# pox_2_activation = 109 # Send some stacking orders diff --git a/components/hiro-system-kit/Cargo.toml b/components/hiro-system-kit/Cargo.toml index 74bf98ea0..8a5e472a6 100644 --- a/components/hiro-system-kit/Cargo.toml +++ b/components/hiro-system-kit/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tokio = { version = "1.24", optional = true } +tokio = { version = "1.35.1", optional = true } ansi_term = "0.12.1" atty = "0.2.14" lazy_static = "1.4.0" diff --git a/components/stacks-devnet-js/lib/index.ts b/components/stacks-devnet-js/lib/index.ts index 9a92a5cfe..7d0f3ef24 100644 --- a/components/stacks-devnet-js/lib/index.ts +++ b/components/stacks-devnet-js/lib/index.ts @@ -367,11 +367,17 @@ export interface DevnetConfig { */ epoch_2_4?: number; /** - * Bitcoin block height activating switch to POX 2.0 + * Bitcoin block height starting the epoch 2.5 * @type {number} * @memberof DevnetConfig */ - pox_2_activation?: number; + epoch_2_5?: number; + /** + * Bitcoin block height starting the epoch 3.0 + * @type {number} + * @memberof DevnetConfig + */ + epoch_3_0?: number; } /** @@ -411,7 +417,7 @@ export class DevnetNetworkFactory { private static instance: DevnetNetworkFactory | undefined = undefined; private nextNetworkId: number = 0; - private constructor() { } + private constructor() {} static sharedInstance(): DevnetNetworkFactory { if (!DevnetNetworkFactory.instance) { @@ -421,13 +427,19 @@ export class DevnetNetworkFactory { } buildNetwork(manifest: NetworkConfig): DevnetNetworkOrchestrator { - let network = new DevnetNetworkOrchestrator(getIsolatedNetworkConfigUsingNetworkId(this.nextNetworkId, manifest)); + let network = new DevnetNetworkOrchestrator( + getIsolatedNetworkConfigUsingNetworkId(this.nextNetworkId, manifest) + ); this.nextNetworkId += 1; return network; } } -export function getIsolatedNetworkConfigUsingNetworkId(networkId: number, networkConfig: NetworkConfig, interval = 10000) { +export function getIsolatedNetworkConfigUsingNetworkId( + networkId: number, + networkConfig: NetworkConfig, + interval = 10000 +) { const manifestPath = networkConfig.clarinetManifestPath || "./Clarinet.toml"; const logs = networkConfig.logs || false; const accounts = networkConfig.accounts || []; @@ -537,16 +549,21 @@ export class DevnetNetworkOrchestrator { * @summary Wait for the next Stacks block * @memberof DevnetNetworkOrchestrator */ - async waitForNextStacksBlock(maxErrors = 5, emptyQueuedBlocks = false): Promise { + async waitForNextStacksBlock( + maxErrors = 5, + emptyQueuedBlocks = false + ): Promise { let errorCount = 0; while (true) { try { - let chainUpdate = await this.mineBitcoinBlockAndHopeForStacksBlock(emptyQueuedBlocks); + let chainUpdate = await this.mineBitcoinBlockAndHopeForStacksBlock( + emptyQueuedBlocks + ); if (chainUpdate == undefined) { this.currentCooldown += this.defaultCooldown; errorCount += 1; if (errorCount >= maxErrors) { - throw 'waitForNextStacksBlock maxErrors reached' + throw "waitForNextStacksBlock maxErrors reached"; } continue; } @@ -565,19 +582,26 @@ export class DevnetNetworkOrchestrator { * @summary Wait for the next Stacks block * @memberof DevnetNetworkOrchestrator */ - async mineBitcoinBlockAndHopeForStacksBlock(emptyQueuedBlocks = false): Promise { + async mineBitcoinBlockAndHopeForStacksBlock( + emptyQueuedBlocks = false + ): Promise { let now = new Date(); - let ms_elapsed = (now.getTime() - this.lastCooldownEndedAt.getTime()); + let ms_elapsed = now.getTime() - this.lastCooldownEndedAt.getTime(); let cooldown = Math.max(0, this.currentCooldown - ms_elapsed); - let wait = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); + let wait = (ms: number) => + new Promise((resolve) => setTimeout(resolve, ms)); return wait(cooldown) .then(() => { this.lastCooldownEndedAt = new Date(); - return stacksDevnetWaitForStacksBlock.call(this.handle, this.currentCooldown, emptyQueuedBlocks) + return stacksDevnetWaitForStacksBlock.call( + this.handle, + this.currentCooldown, + emptyQueuedBlocks + ); }) - .catch(e => { + .catch((e) => { this.lastCooldownEndedAt = new Date(); - throw e + throw e; }); } @@ -585,11 +609,19 @@ export class DevnetNetworkOrchestrator { * @summary Wait for the next Stacks block * @memberof DevnetNetworkOrchestrator */ - async waitForStacksBlockOfHeight(targetBlockHeight: number, maxErrors = 5, emptyQueuedBlocks = false): Promise { + async waitForStacksBlockOfHeight( + targetBlockHeight: number, + maxErrors = 5, + emptyQueuedBlocks = false + ): Promise { while (true) { try { - let chainUpdate = await this.waitForNextStacksBlock(maxErrors, emptyQueuedBlocks); - let currentBlockHeight = chainUpdate.new_blocks[0].block.block_identifier.index; + let chainUpdate = await this.waitForNextStacksBlock( + maxErrors, + emptyQueuedBlocks + ); + let currentBlockHeight = + chainUpdate.new_blocks[0].block.block_identifier.index; if (currentBlockHeight >= targetBlockHeight) { return chainUpdate; } @@ -603,12 +635,21 @@ export class DevnetNetworkOrchestrator { * @summary Wait for the next Stacks block * @memberof DevnetNetworkOrchestrator */ - async waitForStacksBlockAnchoredOnBitcoinBlockOfHeight(minBitcoinBlockHeight: number, maxErrors = 5, emptyQueuedBlocks = false): Promise { + async waitForStacksBlockAnchoredOnBitcoinBlockOfHeight( + minBitcoinBlockHeight: number, + maxErrors = 5, + emptyQueuedBlocks = false + ): Promise { while (true) { try { - let chainUpdate = await this.waitForNextStacksBlock(maxErrors, emptyQueuedBlocks); - let metadata = chainUpdate.new_blocks[0].block.metadata! as StacksBlockMetadata; - let currentBitcoinBlockHeight = metadata.bitcoin_anchor_block_identifier.index; + let chainUpdate = await this.waitForNextStacksBlock( + maxErrors, + emptyQueuedBlocks + ); + let metadata = chainUpdate.new_blocks[0].block + .metadata! as StacksBlockMetadata; + let currentBitcoinBlockHeight = + metadata.bitcoin_anchor_block_identifier.index; if (currentBitcoinBlockHeight >= minBitcoinBlockHeight) { return chainUpdate; } @@ -624,26 +665,29 @@ export class DevnetNetworkOrchestrator { */ async waitForNextBitcoinBlock(): Promise { let now = new Date(); - let ms_elapsed = (now.getTime() - this.lastCooldownEndedAt.getTime()); + let ms_elapsed = now.getTime() - this.lastCooldownEndedAt.getTime(); let cooldown = Math.max(0, this.currentCooldown - ms_elapsed); - let wait = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); + let wait = (ms: number) => + new Promise((resolve) => setTimeout(resolve, ms)); return wait(cooldown) .then(() => { this.lastCooldownEndedAt = new Date(); - return stacksDevnetWaitForBitcoinBlock.call(this.handle) - }) - .catch(e => { + return stacksDevnetWaitForBitcoinBlock.call(this.handle); + }) + .catch((e) => { this.lastCooldownEndedAt = new Date(); - throw e + throw e; }); } - /** * @summary Wait for the next Bitcoin block * @memberof DevnetNetworkOrchestrator */ - async waitForStacksBlockIncludingTransaction(txid: string, ttl = 5): Promise<{ chainUpdate: StacksChainUpdate, transaction: Transaction }> { + async waitForStacksBlockIncludingTransaction( + txid: string, + ttl = 5 + ): Promise<{ chainUpdate: StacksChainUpdate; transaction: Transaction }> { while (ttl > 0) { let chainUpdate = await this.waitForNextStacksBlock(); for (const transaction of chainUpdate.new_blocks[0].block.transactions) { @@ -656,8 +700,8 @@ export class DevnetNetworkOrchestrator { } ttl -= 1; } - throw 'waitForStacksBlockIncludingTransaction TTL expired' - }; + throw "waitForStacksBlockIncludingTransaction TTL expired"; + } /** * @summary Terminates the containers diff --git a/components/stacks-devnet-js/src/lib.rs b/components/stacks-devnet-js/src/lib.rs index fb9924611..9eda9c385 100644 --- a/components/stacks-devnet-js/src/lib.rs +++ b/components/stacks-devnet-js/src/lib.rs @@ -632,10 +632,17 @@ impl StacksDevnet { } if let Ok(res) = devnet_settings - .get(&mut cx, "pox_2_activation")? + .get(&mut cx, "epoch_2_5")? .downcast::(&mut cx) { - overrides.pox_2_activation = Some(res.value(&mut cx) as u64); + overrides.epoch_2_5 = Some(res.value(&mut cx) as u64); + } + + if let Ok(res) = devnet_settings + .get(&mut cx, "epoch_3_0")? + .downcast::(&mut cx) + { + overrides.epoch_3_0 = Some(res.value(&mut cx) as u64); } // Disable scripts diff --git a/components/stacks-network/Cargo.toml b/components/stacks-network/Cargo.toml index a7011e553..3621e0744 100644 --- a/components/stacks-network/Cargo.toml +++ b/components/stacks-network/Cargo.toml @@ -8,9 +8,8 @@ edition = "2021" [dependencies] atty = "0.2.14" ansi_term = "0.12.1" -bollard = "0.11.0" +bollard = "0.15.0" bytes = "1.4.0" -crossterm = { version = "0.22.1", optional = true } bitcoin = "0.29.2" bitcoincore-rpc = "0.16.0" serde = { version = "1.0.136", features = ["derive"] } @@ -25,15 +24,16 @@ reqwest = { version = "0.11", default-features = false, features = [ "json", "rustls-tls", ] } -tui = { version = "0.18.0", default-features = false, features = ["crossterm"] } crossbeam-channel = "0.5.6" - +crossterm = { version = "0.27.0" } +ratatui = { version = "0.25.0", default-features = false, features = ["crossterm"] } chrono = "0.4.31" futures = "0.3.12" base58 = "0.2.0" +tokio = { version = "1.35.1", features = ["full"] } -# chainhook-sdk = { version = "=0.11", default-features = true, path = "../../../chainhook/components/chainhook-sdk" } -chainhook-sdk = { version = "=0.11", default-features = true } +chainhook-sdk = { default-features = true, git = "https://github.com/hirosystems/chainhook.git", rev = "a938e61846a430750ad31d84b2032efabf6d039f"} +# chainhook-sdk = { version = "=0.11", default-features = true } stacks-rpc-client = { path = "../stacks-rpc-client" } clarinet-files = { path = "../clarinet-files", features = ["cli"] } clarinet-deployments = { path = "../clarinet-deployments", features = ["cli"] } @@ -55,6 +55,3 @@ crate-type = ["cdylib", "rlib"] [[bin]] name = "stacks-network" path = "src/main.rs" - -[features] -default = ["crossterm"] diff --git a/components/stacks-network/src/chains_coordinator.rs b/components/stacks-network/src/chains_coordinator.rs index 995e2149b..8892a57e3 100644 --- a/components/stacks-network/src/chains_coordinator.rs +++ b/components/stacks-network/src/chains_coordinator.rs @@ -1,41 +1,44 @@ use super::ChainsCoordinatorCommand; + use crate::event::DevnetEvent; use crate::event::ServiceStatusData; use crate::event::Status; use crate::orchestrator::ServicesMapHosts; + use base58::FromBase58; use chainhook_sdk::chainhooks::types::ChainhookConfig; +use chainhook_sdk::observer::{ + start_event_observer, EventObserverConfig, ObserverCommand, ObserverEvent, + StacksChainMempoolEvent, +}; use chainhook_sdk::types::BitcoinBlockSignaling; use chainhook_sdk::types::BitcoinChainEvent; use chainhook_sdk::types::BitcoinNetwork; +use chainhook_sdk::types::StacksBlockData; use chainhook_sdk::types::StacksChainEvent; use chainhook_sdk::types::StacksNetwork; use chainhook_sdk::types::StacksNodeConfig; +use chainhook_sdk::types::StacksTransactionKind; use chainhook_sdk::utils::Context; use clarinet_deployments::onchain::TransactionStatus; use clarinet_deployments::onchain::{ apply_on_chain_deployment, DeploymentCommand, DeploymentEvent, }; use clarinet_deployments::types::DeploymentSpecification; +use clarinet_files::PoxStackingOrder; use clarinet_files::{self, AccountConfig, DevnetConfig, NetworkManifest, ProjectManifest}; -use hiro_system_kit; -use hiro_system_kit::slog; - -use chainhook_sdk::observer::{ - start_event_observer, EventObserverConfig, ObserverCommand, ObserverEvent, - StacksChainMempoolEvent, -}; - use clarity_repl::clarity::address::AddressHashMode; use clarity_repl::clarity::util::hash::{hex_bytes, Hash160}; use clarity_repl::clarity::vm::types::{BuffData, SequenceData, TupleData}; use clarity_repl::clarity::vm::ClarityName; use clarity_repl::clarity::vm::Value as ClarityValue; use clarity_repl::codec; +use hiro_system_kit; +use hiro_system_kit::slog; use hiro_system_kit::yellow; -use stacks_rpc_client::{PoxInfo, StacksRpc}; +use stacks_rpc_client::PoxInfo; +use stacks_rpc_client::StacksRpc; use std::convert::TryFrom; - use std::str; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::{channel, Receiver, Sender}; @@ -380,30 +383,39 @@ pub async fn start_chains_coordinator( }; let _ = devnet_event_tx.send(DevnetEvent::info(message)); - let stacks_rpc = StacksRpc::new(&config.consolidated_stacks_rpc_url()); - let _ = stacks_rpc.get_pox_info(); - - let should_submit_pox_orders = known_tip.block.metadata.pox_cycle_position - == (known_tip.block.metadata.pox_cycle_length - 2); - if should_submit_pox_orders { + // only publish stacking order txs in tenure-change blocks + let has_coinbase_tx = known_tip + .block + .transactions + .iter() + .any(|tx| tx.metadata.kind == StacksTransactionKind::Coinbase); + if has_coinbase_tx { let bitcoin_block_height = known_tip .block .metadata .bitcoin_anchor_block_identifier .index; - let res = publish_stacking_orders( - &config.devnet_config, - &config.accounts, - &config.services_map_hosts, - config.deployment_fee_rate, - bitcoin_block_height as u32, - ) - .await; - if let Some(tx_count) = res { - let _ = devnet_event_tx.send(DevnetEvent::success(format!( - "Will broadcast {} stacking orders", - tx_count - ))); + + // stacking early in the cycle to make sure that + // the transactions are included in the next cycle + let should_submit_pox_orders = known_tip.block.metadata.pox_cycle_position == 1; + if should_submit_pox_orders { + let res = publish_stacking_orders( + &known_tip.block, + &config.devnet_config, + &devnet_event_tx, + &config.accounts, + &config.services_map_hosts, + config.deployment_fee_rate, + bitcoin_block_height as u32, + ) + .await; + if let Some(tx_count) = res { + let _ = devnet_event_tx.send(DevnetEvent::success(format!( + "Broadcasted {} stacking orders", + tx_count + ))); + } } } } @@ -530,19 +542,30 @@ pub fn relay_devnet_protocol_deployment( } pub async fn publish_stacking_orders( + block: &StacksBlockData, devnet_config: &DevnetConfig, + devnet_event_tx: &Sender, accounts: &[AccountConfig], services_map_hosts: &ServicesMapHosts, fee_rate: u64, bitcoin_block_height: u32, ) -> Option { - if devnet_config.pox_stacking_orders.is_empty() { + let orders_to_broadcast: Vec<&PoxStackingOrder> = devnet_config + .pox_stacking_orders + .iter() + .filter(|pox_stacking_order| { + pox_stacking_order.start_at_cycle - 1 == block.metadata.pox_cycle_index + }) + .collect(); + + if orders_to_broadcast.is_empty() { return None; } let stacks_node_rpc_url = format!("http://{}", &services_map_hosts.stacks_node_host); let mut transactions = 0; + let pox_info: PoxInfo = reqwest::get(format!("{}/v2/pox", stacks_node_rpc_url)) .await .expect("Unable to retrieve pox info") @@ -550,38 +573,37 @@ pub async fn publish_stacking_orders( .await .expect("Unable to parse contract"); - for pox_stacking_order in devnet_config.pox_stacking_orders.iter() { - if pox_stacking_order.start_at_cycle - 1 == pox_info.reward_cycle_id { - let mut account = None; - let accounts_iter = accounts.iter(); - for e in accounts_iter { - if e.label == pox_stacking_order.wallet { - account = Some(e.clone()); - break; - } - } - let account = match account { - Some(account) => account, - _ => continue, - }; - - transactions += 1; + for (i, pox_stacking_order) in orders_to_broadcast.iter().enumerate() { + let account = accounts + .iter() + .find(|e| e.label == pox_stacking_order.wallet); - let stx_amount = pox_info.next_cycle.min_threshold_ustx * pox_stacking_order.slots; - let addr_bytes = pox_stacking_order - .btc_address - .from_base58() - .expect("Unable to get bytes from btc address"); - let duration = pox_stacking_order.duration.into(); - let node_url = stacks_node_rpc_url.clone(); - let pox_contract_id = pox_info.contract_id.clone(); + let account = match account { + Some(account) => account.clone(), + _ => continue, + }; - let _ = hiro_system_kit::thread_named("Stacking orders handler").spawn(move || { + transactions += 1; + + let stx_amount = pox_info.next_cycle.min_threshold_ustx * pox_stacking_order.slots; + let addr_bytes = pox_stacking_order + .btc_address + .from_base58() + .expect("Unable to get bytes from btc address"); + let duration = pox_stacking_order.duration.into(); + let node_url = stacks_node_rpc_url.clone(); + let pox_contract_id = pox_info.contract_id.clone(); + let pox_version = pox_contract_id + .rsplit('-') + .next() + .and_then(|version| version.parse::().ok()) + .unwrap(); + + let stacking_result = + hiro_system_kit::thread_named("Stacking orders handler").spawn(move || { let default_fee = fee_rate * 1000; let stacks_rpc = StacksRpc::new(&node_url); - let nonce = stacks_rpc - .get_nonce(&account.stx_address) - .expect("Unable to retrieve nonce"); + let nonce = stacks_rpc.get_nonce(&account.stx_address)?; let (_, _, account_secret_key) = clarinet_files::compute_addresses( &account.mnemonic, @@ -591,37 +613,63 @@ pub async fn publish_stacking_orders( let addr_bytes = Hash160::from_bytes(&addr_bytes[1..21]).unwrap(); let addr_version = AddressHashMode::SerializeP2PKH; + + let mut arguments = vec![ + ClarityValue::UInt(stx_amount.into()), + ClarityValue::Tuple( + TupleData::from_data(vec![ + ( + ClarityName::try_from("version".to_owned()).unwrap(), + ClarityValue::buff_from_byte(addr_version as u8), + ), + ( + ClarityName::try_from("hashbytes".to_owned()).unwrap(), + ClarityValue::Sequence(SequenceData::Buffer(BuffData { + data: addr_bytes.as_bytes().to_vec(), + })), + ), + ]) + .unwrap(), + ), + ClarityValue::UInt((bitcoin_block_height - 1).into()), + ClarityValue::UInt(duration), + ]; + if pox_version >= 4 { + let signer_key = vec![i as u8; 33]; + arguments.push(ClarityValue::buff_from(signer_key).unwrap()); + }; + let stack_stx_tx = codec::build_contrat_call_transaction( pox_contract_id, "stack-stx".into(), - vec![ - ClarityValue::UInt(stx_amount.into()), - ClarityValue::Tuple( - TupleData::from_data(vec![ - ( - ClarityName::try_from("version".to_owned()).unwrap(), - ClarityValue::buff_from_byte(addr_version as u8), - ), - ( - ClarityName::try_from("hashbytes".to_owned()).unwrap(), - ClarityValue::Sequence(SequenceData::Buffer(BuffData { - data: addr_bytes.as_bytes().to_vec(), - })), - ), - ]) - .unwrap(), - ), - ClarityValue::UInt((bitcoin_block_height - 1).into()), - ClarityValue::UInt(duration), - ], + arguments, nonce, default_fee, &hex_bytes(&account_secret_key).unwrap(), ); - let _ = stacks_rpc - .post_transaction(&stack_stx_tx) - .expect("Unable to broadcast transaction"); + stacks_rpc.post_transaction(&stack_stx_tx) }); + + match stacking_result { + Ok(result) => { + if let Ok(result) = result.join() { + match result { + Ok(_) => { + let _ = devnet_event_tx.send(DevnetEvent::success(format!( + "Stacking order for {} STX submitted", + stx_amount + ))); + } + Err(e) => { + let _ = devnet_event_tx + .send(DevnetEvent::error(format!("Unable to stack: {}", e))); + } + } + }; + } + Err(e) => { + let _ = devnet_event_tx.send(DevnetEvent::error(format!("Unable to stack: {}", e))); + } } } if transactions > 0 { diff --git a/components/stacks-network/src/orchestrator.rs b/components/stacks-network/src/orchestrator.rs index 2af072224..bdafd37ca 100644 --- a/components/stacks-network/src/orchestrator.rs +++ b/components/stacks-network/src/orchestrator.rs @@ -239,7 +239,7 @@ impl DevnetOrchestrator { .as_ref() .and_then(|ipam| ipam.config.as_ref()) .and_then(|config| config.first()) - .and_then(|map| map.get("Gateway")) + .and_then(|map| map.gateway.clone()) .ok_or("unable to retrieve gateway")?; let services_map_hosts = if devnet_config.use_docker_gateway_routing { @@ -821,6 +821,7 @@ rpcport={bitcoin_node_rpc_port} let container_name = format!("bitcoin-node.{}", self.network_name); let options = CreateContainerOptions { name: container_name.as_str(), + platform: Some(&devnet_config.docker_platform), }; let container = match docker @@ -939,12 +940,15 @@ rpcport={bitcoin_node_rpc_port} working_dir = "/devnet" rpc_bind = "0.0.0.0:{stacks_node_rpc_port}" p2p_bind = "0.0.0.0:{stacks_node_p2p_port}" +data_url = "http://127.0.0.1:{stacks_node_rpc_port}" +p2p_address = "127.0.0.1:{stacks_node_rpc_port}" miner = true seed = "{miner_secret_key_hex}" local_peer_seed = "{miner_secret_key_hex}" pox_sync_sample_secs = 0 wait_time_for_blocks = 0 -wait_time_for_microblocks = {wait_time_for_microblocks} +wait_time_for_microblocks = 0 +mine_microblocks = false microblock_frequency = 1000 [connection_options] @@ -957,15 +961,19 @@ disable_inbound_walks = true public_ip_address = "1.1.1.1:1234" [miner] +min_tx_fee = 1 first_attempt_time_ms = {first_attempt_time_ms} -subsequent_attempt_time_ms = {subsequent_attempt_time_ms} +second_attempt_time_ms = {subsequent_attempt_time_ms} block_reward_recipient = "{miner_coinbase_recipient}" +wait_for_block_download = false +microblock_attempt_time_ms = 10 +self_signing_seed = 1 +mining_key = "19ec1c3e31d139c989a23a27eac60d1abfad5277d3ae9604242514c738258efa01" # microblock_attempt_time_ms = 15000 "#, stacks_node_rpc_port = devnet_config.stacks_node_rpc_port, stacks_node_p2p_port = devnet_config.stacks_node_p2p_port, miner_secret_key_hex = devnet_config.miner_secret_key_hex, - wait_time_for_microblocks = devnet_config.stacks_node_wait_time_for_microblocks, first_attempt_time_ms = devnet_config.stacks_node_first_attempt_time_ms, subsequent_attempt_time_ms = devnet_config.stacks_node_subsequent_attempt_time_ms, miner_coinbase_recipient = devnet_config.miner_coinbase_recipient, @@ -1037,26 +1045,35 @@ events_keys = ["*"] r#" [burnchain] chain = "bitcoin" -mode = "krypton" +mode = "{burnchain_mode}" +magic_bytes = "T3" +pox_prepare_length = 4 +pox_reward_length = 10 +burn_fee_cap = 20_000 poll_time_secs = 1 timeout = 30 peer_host = "host.docker.internal" rpc_ssl = false -wallet_name = "devnet" +wallet_name = "{miner_wallet_name}" username = "{bitcoin_node_username}" password = "{bitcoin_node_password}" rpc_port = {orchestrator_ingestion_port} peer_port = {bitcoin_node_p2p_port} "#, + burnchain_mode = if devnet_config.use_nakamoto { + "nakamoto-neon" + } else { + "krypton" + }, bitcoin_node_username = devnet_config.bitcoin_node_username, bitcoin_node_password = devnet_config.bitcoin_node_password, bitcoin_node_p2p_port = devnet_config.bitcoin_node_p2p_port, orchestrator_ingestion_port = devnet_config.orchestrator_ingestion_port, + miner_wallet_name = devnet_config.miner_wallet_name, )); stacks_conf.push_str(&format!( - r#"pox_2_activation = {pox_2_activation} - + r#" [[burnchain.epochs]] epoch_name = "1.0" start_height = 0 @@ -1091,9 +1108,24 @@ start_height = {epoch_2_4} epoch_2_2 = devnet_config.epoch_2_2, epoch_2_3 = devnet_config.epoch_2_3, epoch_2_4 = devnet_config.epoch_2_4, - pox_2_activation = devnet_config.pox_2_activation, )); + if devnet_config.use_nakamoto { + stacks_conf.push_str(&format!( + r#" +[[burnchain.epochs]] +epoch_name = "2.5" +start_height = {epoch_2_5} + +[[burnchain.epochs]] +epoch_name = "3.0" +start_height = {epoch_3_0} +"#, + epoch_2_5 = devnet_config.epoch_2_5, + epoch_3_0 = devnet_config.epoch_3_0, + )); + } + let mut stacks_conf_path = PathBuf::from(&devnet_config.working_dir); stacks_conf_path.push("conf/Stacks.toml"); let mut file = File::create(stacks_conf_path) @@ -1197,6 +1229,7 @@ start_height = {epoch_2_4} let options = CreateContainerOptions { name: format!("stacks-node.{}", self.network_name), + platform: Some(devnet_config.docker_platform.to_string()), }; let container = docker @@ -1279,8 +1312,11 @@ wait_time_for_microblocks = {wait_time_for_microblocks} wait_before_first_anchored_block = 0 [miner] +min_tx_fee = 1 first_attempt_time_ms = {first_attempt_time_ms} subsequent_attempt_time_ms = {subsequent_attempt_time_ms} +wait_for_block_download = false +self_signing_seed = 1 # microblock_attempt_time_ms = 15_000 [burnchain] @@ -1452,6 +1488,7 @@ events_keys = ["*"] let options = CreateContainerOptions { name: format!("subnet-node.{}", self.network_name), + platform: Some(devnet_config.docker_platform.to_string()), }; let container = docker @@ -1575,6 +1612,7 @@ events_keys = ["*"] let options = CreateContainerOptions { name: format!("stacks-api.{}", self.network_name), + platform: Some(devnet_config.docker_platform.to_string()), }; let container = docker @@ -1698,6 +1736,7 @@ events_keys = ["*"] let options = CreateContainerOptions { name: format!("subnet-api.{}", self.network_name), + platform: Some(devnet_config.docker_platform.to_string()), }; let container = docker @@ -1830,6 +1869,7 @@ events_keys = ["*"] let options = CreateContainerOptions { name: format!("postgres.{}", self.network_name), + platform: Some(devnet_config.docker_platform.to_string()), }; let container = docker @@ -1938,6 +1978,7 @@ events_keys = ["*"] let options = CreateContainerOptions { name: format!("stacks-explorer.{}", self.network_name), + platform: Some(devnet_config.docker_platform.to_string()), }; let container = docker @@ -2057,6 +2098,7 @@ events_keys = ["*"] let options = CreateContainerOptions { name: format!("bitcoin-explorer.{}", self.network_name), + platform: Some(devnet_config.docker_platform.to_string()), }; let container = docker @@ -2190,8 +2232,16 @@ events_keys = ["*"] .await; let bitcoin_node_config = self.prepare_bitcoin_node_config(boot_index)?; + + let platform = self + .network_config + .as_ref() + .and_then(|c| c.devnet.as_ref()) + .map(|c| c.docker_platform.to_string()); + let options = CreateContainerOptions { name: format!("bitcoin-node.{}", self.network_name), + platform: platform.clone(), }; let bitcoin_node_c_id = docker .create_container::(Some(options), bitcoin_node_config) @@ -2200,8 +2250,10 @@ events_keys = ["*"] .id; let stacks_node_config = self.prepare_stacks_node_config(boot_index)?; + let options = CreateContainerOptions { name: format!("stacks-node.{}", self.network_name), + platform, }; let stacks_node_c_id = docker .create_container::(Some(options), stacks_node_config) @@ -2551,7 +2603,7 @@ events_keys = ["*"] "jsonrpc": "1.0", "id": "stacks-network", "method": "createwallet", - "params": json!({ "wallet_name": "", "disable_private_keys": true }) + "params": json!({ "wallet_name": devnet_config.miner_wallet_name, "disable_private_keys": true }) })) .send() .await diff --git a/components/stacks-network/src/ui/app.rs b/components/stacks-network/src/ui/app.rs index 421d2ce2b..13b00a5b1 100644 --- a/components/stacks-network/src/ui/app.rs +++ b/components/stacks-network/src/ui/app.rs @@ -1,11 +1,13 @@ use super::util::{StatefulList, TabsState}; use crate::event::ServiceStatusData; use crate::{LogData, MempoolAdmissionData}; -use chainhook_sdk::types::{StacksBlockData, StacksMicroblockData, StacksTransactionData}; + +use chainhook_sdk::types::{ + StacksBlockData, StacksMicroblockData, StacksTransactionData, StacksTransactionKind, +}; use chainhook_sdk::utils::Context; use hiro_system_kit::slog; -use tui::style::{Color, Style}; -use tui::text::{Span, Spans}; +use ratatui::prelude::*; pub enum BlockData { Block(StacksBlockData), @@ -109,33 +111,50 @@ impl<'a> App<'a> { } else { ("", "") }; - let has_tx = if block.transactions.len() <= 1 { + + let has_tenure_change_tx = block + .transactions + .iter() + .any(|tx| tx.metadata.kind == StacksTransactionKind::TenureChange); + + let has_coinbase_tx = block + .transactions + .iter() + .any(|tx| tx.metadata.kind == StacksTransactionKind::Coinbase); + + let has_tx = if (block.transactions.len() + - has_coinbase_tx as usize + - has_tenure_change_tx as usize) + == 0 + { "" } else { "␂" }; - self.tabs.titles.push_front(Spans::from(Span::styled( + + self.tabs.titles.push_front(Span::styled( format!( "{}[{}{}]{}", end, block.block_identifier.index, has_tx, start ), - if block.metadata.pox_cycle_index % 2 == 1 { - Style::default().fg(Color::Yellow) + if has_tenure_change_tx { + Style::default().fg(Color::LightBlue) } else { - Style::default().fg(Color::LightYellow) + Style::default().fg(Color::Green) }, - ))); + )); + self.blocks.push(BlockData::Block(block)); + if self.tabs.index != 0 { self.tabs.index += 1; } } pub fn display_microblock(&mut self, block: StacksMicroblockData) { - self.tabs.titles.push_front(Spans::from(Span::styled( - "[·]".to_string(), - Style::default().fg(Color::White), - ))); + self.tabs + .titles + .push_front(Span::from("[·]".to_string()).fg(Color::White)); self.blocks.push(BlockData::Microblock(block)); if self.tabs.index != 0 { self.tabs.index += 1; diff --git a/components/stacks-network/src/ui/mod.rs b/components/stacks-network/src/ui/mod.rs index 23a2742a0..811586213 100644 --- a/components/stacks-network/src/ui/mod.rs +++ b/components/stacks-network/src/ui/mod.rs @@ -6,7 +6,9 @@ mod ui; mod util; use super::DevnetEvent; + use crate::{chains_coordinator::BitcoinMiningCommand, ChainsCoordinatorCommand}; + use app::App; use chainhook_sdk::{types::StacksChainEvent, utils::Context}; use crossterm::{ @@ -14,6 +16,7 @@ use crossterm::{ execute, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, }; +use ratatui::{backend::CrosstermBackend, Terminal}; use std::sync::mpsc::{Receiver, Sender}; use std::{ error::Error, @@ -21,7 +24,6 @@ use std::{ thread, time::{Duration, Instant}, }; -use tui::{backend::CrosstermBackend, Terminal}; pub fn start_ui( devnet_events_tx: Sender, @@ -105,9 +107,14 @@ pub fn do_start_ui( terminal .draw(|f| ui::draw(f, &mut app)) .map_err(|e| format!("unable to update ui: {}", e))?; + let event = match devnet_events_rx.recv() { Ok(event) => event, - Err(_e) => { + Err(e) => { + app.display_log( + DevnetEvent::log_error(format!("Error receiving event: {}", e)), + ctx, + ); let _ = terminate( &mut terminal, chains_coordinator_commands_tx, @@ -119,20 +126,33 @@ pub fn do_start_ui( match event { DevnetEvent::KeyEvent(event) => match (event.modifiers, event.code) { (KeyModifiers::CONTROL, KeyCode::Char('c')) => { - app.display_log(DevnetEvent::log_warning("Ctrl+C received, initiating termination sequence.".into()), ctx); + app.display_log( + DevnetEvent::log_warning( + "Ctrl+C received, initiating termination sequence.".into(), + ), + ctx, + ); let _ = terminate( &mut terminal, chains_coordinator_commands_tx, orchestrator_terminated_rx, - ); + ); break; } (KeyModifiers::NONE, KeyCode::Char('n')) => { if let Some(ref tx) = mining_command_tx { let _ = tx.send(BitcoinMiningCommand::Mine); - app.display_log(DevnetEvent::log_success("Bitcoin block mining triggered manually".to_string()), ctx); + app.display_log( + DevnetEvent::log_success( + "Bitcoin block mining triggered manually".to_string(), + ), + ctx, + ); } else { - app.display_log(DevnetEvent::log_error("Manual block mining not ready".to_string()), ctx); + app.display_log( + DevnetEvent::log_error("Manual block mining not ready".to_string()), + ctx, + ); } } (KeyModifiers::NONE, KeyCode::Left) => app.on_left(), @@ -143,10 +163,10 @@ pub fn do_start_ui( }, DevnetEvent::Tick => { app.on_tick(); - }, + } DevnetEvent::Log(log) => { app.display_log(log, ctx); - }, + } DevnetEvent::ServiceStatus(status) => { app.display_service_status_update(status); } @@ -156,7 +176,16 @@ pub fn do_start_ui( let raw_txs = if app.mempool.items.is_empty() { vec![] } else { - update.new_blocks.iter().flat_map(|b| b.block.transactions.iter().map(|tx| tx.metadata.raw_tx.as_str())).collect::>() + update + .new_blocks + .iter() + .flat_map(|b| { + b.block + .transactions + .iter() + .map(|tx| tx.metadata.raw_tx.as_str()) + }) + .collect::>() }; let mut indices_to_remove = vec![]; @@ -178,7 +207,13 @@ pub fn do_start_ui( let raw_txs = if app.mempool.items.is_empty() { vec![] } else { - update.new_microblocks.iter().flat_map(|b| b.transactions.iter().map(|tx| tx.metadata.raw_tx.as_str())).collect::>() + update + .new_microblocks + .iter() + .flat_map(|b| { + b.transactions.iter().map(|tx| tx.metadata.raw_tx.as_str()) + }) + .collect::>() }; let mut indices_to_remove = vec![]; @@ -199,8 +234,7 @@ pub fn do_start_ui( _ => {} // handle display on re-org, theorically unreachable in context of devnet } } - DevnetEvent::BitcoinChainEvent(_chain_event) => { - } + DevnetEvent::BitcoinChainEvent(_chain_event) => {} DevnetEvent::MempoolAdmission(tx) => { app.add_to_mempool(tx); } @@ -213,22 +247,19 @@ pub fn do_start_ui( &mut terminal, chains_coordinator_commands_tx, orchestrator_terminated_rx, - ); - return Err(message) - }, + ); + return Err(message); + } DevnetEvent::BootCompleted(bitcoin_mining_tx) => { - app.display_log(DevnetEvent::log_success("Local Devnet network ready".into()), ctx); + app.display_log( + DevnetEvent::log_success("Local Devnet network ready".into()), + ctx, + ); if automining_enabled { let _ = bitcoin_mining_tx.send(BitcoinMiningCommand::Start); } mining_command_tx = Some(bitcoin_mining_tx); } - // DevnetEvent::Terminate => { - - // }, - // DevnetEvent::Restart => { - - // }, } if app.should_quit { break; @@ -246,12 +277,12 @@ fn terminate( let _ = disable_raw_mode(); let _ = execute!(terminal.backend_mut(), LeaveAlternateScreen); let res = chains_coordinator_commands_tx.send(ChainsCoordinatorCommand::Terminate); - if let Err(_e) = res { - // Display log + if let Err(e) = res { + println!("Error sending terminate command: {}", e); } let res = orchestrator_terminated_rx.recv(); - if let Err(_e) = res { - // Display log + if let Err(e) = res { + println!("Error sending terminate command: {}", e); } let _ = terminal.show_cursor(); Ok(()) diff --git a/components/stacks-network/src/ui/ui.rs b/components/stacks-network/src/ui/ui.rs index 2b7f61a01..c49de6d51 100644 --- a/components/stacks-network/src/ui/ui.rs +++ b/components/stacks-network/src/ui/ui.rs @@ -1,18 +1,11 @@ -use chainhook_sdk::types::{StacksBlockData, StacksMicroblockData, StacksTransactionData}; +use super::{app::BlockData, App}; use crate::{event::Status, log::LogLevel}; -use super::{app::BlockData, App}; -use tui::{ - backend::Backend, - layout::{Constraint, Corner, Direction, Layout, Rect}, - style::{Color, Modifier, Style}, - text::{Span, Spans}, - widgets::{Block, Borders, Cell, List, ListItem, Paragraph, Row, Table, Tabs}, - Frame, -}; - -pub fn draw(f: &mut Frame, app: &mut App) { +use chainhook_sdk::types::{StacksBlockData, StacksMicroblockData, StacksTransactionData}; +use ratatui::{prelude::*, widgets::*}; + +pub fn draw(f: &mut Frame, app: &mut App) { let page_components = Layout::default() .direction(Direction::Vertical) .constraints( @@ -48,10 +41,7 @@ pub fn draw(f: &mut Frame, app: &mut App) { draw_help(f, app, page_components[3]); } -fn draw_services_status(f: &mut Frame, app: &mut App, area: Rect) -where - B: Backend, -{ +fn draw_services_status(f: &mut Frame, app: &mut App, area: Rect) { let rows = app.services.items.iter().map(|service| { let status = match service.status { Status::Green => "🟩", @@ -66,10 +56,10 @@ where ]) }); - let t = Table::new(rows) + let t = Table::new(rows, vec![] as Vec<&Constraint>) .block(Block::default().borders(Borders::ALL).title("Services")) - .style(Style::default().fg(Color::White)) - .widths(&[ + .style(Style::new().fg(Color::White)) + .widths([ Constraint::Length(3), Constraint::Length(20), Constraint::Length(37), @@ -77,32 +67,21 @@ where f.render_widget(t, area); } -fn draw_mempool(f: &mut Frame, app: &mut App, area: Rect) -where - B: Backend, -{ +fn draw_mempool(f: &mut Frame, app: &mut App, area: Rect) { let rows = app.mempool.items.iter().map(|item| { let cells = vec![Cell::from(item.tx_description.clone())]; Row::new(cells).height(1).bottom_margin(0) }); - let t = Table::new(rows) + let t = Table::new(rows, vec![] as Vec<&Constraint>) .block(Block::default().borders(Borders::ALL).title("Mempool")) - .style(Style::default().fg(Color::White)) - .widths(&[Constraint::Percentage(100)]); + .style(Style::new().fg(Color::White)) + .widths([Constraint::Percentage(100)]); f.render_widget(t, area); } -fn draw_devnet_status(f: &mut Frame, app: &mut App, area: Rect) -where - B: Backend, -{ - // let page_components = Layout::default() - // .direction(Direction::Vertical) - // .constraints([Constraint::Length(20), Constraint::Min(1), Constraint::Length(5)].as_ref()) - // .split(f.size()); - +fn draw_devnet_status(f: &mut Frame, app: &mut App, area: Rect) { let logs: Vec = app .logs .items @@ -118,7 +97,7 @@ where LogLevel::Debug => (Style::default().fg(Color::DarkGray), "DEBG"), }; - let log = Spans::from(vec![ + let log = Line::from(vec![ Span::styled(format!("{:<5}", label), style), Span::styled(&log.occurred_at, Style::default().fg(Color::DarkGray)), Span::raw(" "), @@ -136,18 +115,14 @@ where inner_area.height = inner_area.height.saturating_sub(1); f.render_widget(block, area); - let logs_component = List::new(logs).start_corner(Corner::BottomLeft); + let logs_component = List::new(logs).direction(ListDirection::BottomToTop); f.render_widget(logs_component, inner_area); } -fn draw_blocks(f: &mut Frame, app: &mut App, area: Rect) -where - B: Backend, -{ - let t = Table::new(vec![]) +fn draw_blocks(f: &mut Frame, app: &mut App, area: Rect) { + let t = Table::new(vec![], vec![] as Vec<&Constraint>) .block(Block::default().borders(Borders::ALL)) - .style(Style::default().fg(Color::White)) - .widths(&[]); + .style(Style::default().fg(Color::White)); f.render_widget(t, area); let blocks_components = Layout::default() @@ -157,10 +132,10 @@ where let titles = app.tabs.titles.iter().cloned().collect(); let blocks = Tabs::new(titles) - .divider("") + .block(Block::default().borders(Borders::NONE)) + .divider(symbols::line::HORIZONTAL) .style(Style::default().fg(Color::White)) .highlight_style(Style::default().bg(Color::White).fg(Color::Black)) - .block(Block::default().borders(Borders::NONE)) .select(app.tabs.index); let block_details_components = Layout::default() @@ -188,117 +163,85 @@ where draw_transactions(f, block_details_components[1], transactions); } -fn draw_block_details(f: &mut Frame, area: Rect, block: &StacksBlockData) -where - B: Backend, -{ - let paragraph = Paragraph::new(String::new()).block( - Block::default() - .borders(Borders::NONE) - .style(Style::default().fg(Color::White)) - .title("Block Informations"), - ); - f.render_widget(paragraph, area); - +fn draw_block_details(f: &mut Frame, area: Rect, block: &StacksBlockData) { let labels = Layout::default() .direction(Direction::Vertical) .constraints( [ - Constraint::Length(2), - Constraint::Length(1), - Constraint::Length(2), - Constraint::Length(1), - Constraint::Length(2), - Constraint::Length(1), - Constraint::Length(2), - Constraint::Length(1), - Constraint::Length(2), - Constraint::Length(1), - Constraint::Length(2), + Constraint::Length(2), // "Block informations" title + Constraint::Length(2), // Stacks block height + Constraint::Length(2), // Bitcoin block height + Constraint::Length(1), // Stacks block hash label + Constraint::Length(2), // Stacks block hash + Constraint::Length(1), // Bitcoin block hash label + Constraint::Length(2), // Bitcoin block hash + Constraint::Length(2), // "Pox informations" title + Constraint::Length(2), // PoX cycle + Constraint::Length(2), // PoX cycle position ] .as_ref(), ) .split(area); - let label = "Block height:".to_string(); - let paragraph = Paragraph::new(label) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); - f.render_widget(paragraph, labels[1]); - - let value = format!("{}", block.block_identifier.index); - let paragraph = Paragraph::new(value) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); - f.render_widget(paragraph, labels[2]); - - let label = "Block hash:".to_string(); - let paragraph = Paragraph::new(label) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); + let title = + Paragraph::new("Block information").style(Style::default().add_modifier(Modifier::BOLD)); + f.render_widget(title, labels[0]); + + let line = Line::from(vec![ + Span::raw("Stacks block height: "), + Span::styled( + block.block_identifier.index.to_string(), + Style::default().add_modifier(Modifier::BOLD), + ), + ]); + f.render_widget(Paragraph::new(line), labels[1]); + + let line = Line::from(vec![ + Span::raw("Bitcoin block height: "), + Span::styled( + block + .metadata + .bitcoin_anchor_block_identifier + .index + .to_string(), + Style::default().add_modifier(Modifier::BOLD), + ), + ]); + f.render_widget(Paragraph::new(line), labels[2]); + + let paragraph = Paragraph::new("Stacks block hash:"); f.render_widget(paragraph, labels[3]); - let value = block.block_identifier.hash.to_string(); - let paragraph = Paragraph::new(value) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); + let label = block.block_identifier.hash.clone(); + let paragraph = Paragraph::new(label); f.render_widget(paragraph, labels[4]); - let label = "Bitcoin block height:".to_string(); - let paragraph = Paragraph::new(label) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); + let paragraph = Paragraph::new("Bitcoin block hash:"); f.render_widget(paragraph, labels[5]); - let value = format!("{}", block.metadata.bitcoin_anchor_block_identifier.index); - let paragraph = Paragraph::new(value) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); + let label = block.metadata.bitcoin_anchor_block_identifier.hash.clone(); + let paragraph = Paragraph::new(label); f.render_widget(paragraph, labels[6]); - let label = "Bitcoin block hash:".to_string(); - let paragraph = Paragraph::new(label) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); - f.render_widget(paragraph, labels[7]); + let title = + Paragraph::new("PoX informations").style(Style::default().add_modifier(Modifier::BOLD)); + f.render_widget(title, labels[7]); - let value = block - .metadata - .bitcoin_anchor_block_identifier - .hash - .to_string(); - let paragraph = Paragraph::new(value) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); + let label = format!("PoX Cycle: {}", block.metadata.pox_cycle_index); + let paragraph = Paragraph::new(label); f.render_widget(paragraph, labels[8]); - let label = "Pox Cycle:".to_string(); - let paragraph = Paragraph::new(label) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); + let label = format!("PoX Cycle Position: {}", block.metadata.pox_cycle_position); + let paragraph = Paragraph::new(label); f.render_widget(paragraph, labels[9]); - let value = format!("{}", block.metadata.pox_cycle_index); - let paragraph = Paragraph::new(value) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); - f.render_widget(paragraph, labels[10]); - - // TODO(ludo): PoX informations + // TODO: Add more PoX data (from pox_info) // TODO(ludo): Mining informations (miner, VRF) } -fn draw_microblock_details(f: &mut Frame, area: Rect, microblock: &StacksMicroblockData) -where - B: Backend, -{ - let paragraph = Paragraph::new(String::new()).block( - Block::default() - .borders(Borders::NONE) - .style(Style::default().fg(Color::White)) - .title("Microblock Informations"), - ); - f.render_widget(paragraph, area); +fn draw_microblock_details(f: &mut Frame, area: Rect, microblock: &StacksMicroblockData) { + let title = Paragraph::new("Microblock Informations").white().bold(); + f.render_widget(title, area); let labels = Layout::default() .direction(Direction::Vertical) @@ -321,62 +264,43 @@ where .split(area); let label = "Microblock height:".to_string(); - let paragraph = Paragraph::new(label) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); + let paragraph = Paragraph::new(label); f.render_widget(paragraph, labels[1]); let value = format!("{}", microblock.block_identifier.index); - let paragraph = Paragraph::new(value) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); + let paragraph = Paragraph::new(value); f.render_widget(paragraph, labels[2]); let label = "Microblock hash:".to_string(); - let paragraph = Paragraph::new(label) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); + let paragraph = Paragraph::new(label); f.render_widget(paragraph, labels[3]); let value = microblock.block_identifier.hash.to_string(); - let paragraph = Paragraph::new(value) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); + let paragraph = Paragraph::new(value); f.render_widget(paragraph, labels[4]); let label = "Anchor block height:".to_string(); - let paragraph = Paragraph::new(label) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); + let paragraph = Paragraph::new(label); f.render_widget(paragraph, labels[5]); let value = format!("{}", microblock.metadata.anchor_block_identifier.index); - let paragraph = Paragraph::new(value) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); + let paragraph = Paragraph::new(value); f.render_widget(paragraph, labels[6]); let label = "Anchor block hash:".to_string(); - let paragraph = Paragraph::new(label) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); + let paragraph = Paragraph::new(label); f.render_widget(paragraph, labels[7]); let value = microblock.metadata.anchor_block_identifier.hash.to_string(); - let paragraph = Paragraph::new(value) - .style(Style::default().fg(Color::White)) - .block(Block::default().borders(Borders::NONE)); + let paragraph = Paragraph::new(value); f.render_widget(paragraph, labels[8]); } -fn draw_transactions(f: &mut Frame, area: Rect, transactions: &[StacksTransactionData]) -where - B: Backend, -{ +fn draw_transactions(f: &mut Frame, area: Rect, transactions: &[StacksTransactionData]) { let transactions: Vec = transactions .iter() .map(|t| { - let tx_info = Spans::from(vec![ + let tx_info = Line::from(vec![ Span::styled( match t.metadata.success { true => "🟩", @@ -414,10 +338,7 @@ where f.render_widget(list, inner_area); } -fn draw_help(f: &mut Frame, app: &mut App, area: Rect) -where - B: Backend, -{ +fn draw_help(f: &mut Frame, app: &mut App, area: Rect) { // let help = // " ⬅️ ➡️ Explore blocks ⬆️ ⬇️ Explore transactions 0️⃣ Genesis Reset"; let help = format!(" ⬅️ ➡️ Explore blocks Path: {}", app.devnet_path); diff --git a/components/stacks-network/src/ui/util/mod.rs b/components/stacks-network/src/ui/util/mod.rs index 68a553978..9e3602535 100644 --- a/components/stacks-network/src/ui/util/mod.rs +++ b/components/stacks-network/src/ui/util/mod.rs @@ -1,12 +1,11 @@ use std::collections::VecDeque; -use tui::text::Spans; -use tui::widgets::ListState; +use ratatui::text::Span; +use ratatui::widgets::ListState; #[derive(Clone)] - pub struct TabsState<'a> { - pub titles: VecDeque>, + pub titles: VecDeque>, pub index: usize, } diff --git a/components/stacks-rpc-client/src/crypto.rs b/components/stacks-rpc-client/src/crypto.rs index f02a77063..48e9498d3 100644 --- a/components/stacks-rpc-client/src/crypto.rs +++ b/components/stacks-rpc-client/src/crypto.rs @@ -1,13 +1,14 @@ use std::str::FromStr; use crate::clarity::codec::*; -use crate::clarity::stacks_common::codec::StacksMessageCodec; -use crate::clarity::stacks_common::types::chainstate::StacksAddress; + use crate::clarity::vm::types::{PrincipalData, QualifiedContractIdentifier, Value}; use crate::clarity::vm::{ClarityName, ClarityVersion, ContractName}; use clarity_repl::clarity::address::{ AddressHashMode, C32_ADDRESS_VERSION_MAINNET_SINGLESIG, C32_ADDRESS_VERSION_TESTNET_SINGLESIG, }; +use clarity_repl::clarity::chainstate::StacksAddress; +use clarity_repl::clarity::codec::StacksMessageCodec; use clarity_repl::clarity::util::secp256k1::{ MessageSignature, Secp256k1PrivateKey, Secp256k1PublicKey, }; diff --git a/components/stacks-rpc-client/src/lib.rs b/components/stacks-rpc-client/src/lib.rs index ea157502c..d12eab4b4 100644 --- a/components/stacks-rpc-client/src/lib.rs +++ b/components/stacks-rpc-client/src/lib.rs @@ -9,7 +9,6 @@ extern crate serde_derive; extern crate serde_json; pub mod clarity { - pub use clarity_repl::clarity::stacks_common; pub use clarity_repl::clarity::vm; pub use clarity_repl::codec; } diff --git a/components/stacks-rpc-client/src/rpc_client.rs b/components/stacks-rpc-client/src/rpc_client.rs index 434495e65..a6696a7c8 100644 --- a/components/stacks-rpc-client/src/rpc_client.rs +++ b/components/stacks-rpc-client/src/rpc_client.rs @@ -7,6 +7,9 @@ use std::io::Cursor; use clarity_repl::codec::{StacksTransaction, TransactionPayload}; +use std::fs::File; +use std::io::prelude::*; + #[derive(Debug)] pub enum RpcError { Generic, @@ -58,12 +61,14 @@ pub struct PoxInfo { pub contract_id: String, pub pox_activation_threshold_ustx: u64, pub first_burnchain_block_height: u64, + pub current_burnchain_block_height: u64, pub prepare_phase_block_length: u32, pub reward_phase_block_length: u32, pub reward_slots: u32, pub reward_cycle_id: u32, pub total_liquid_supply_ustx: u64, - pub next_cycle: PoxCycle, + pub current_cycle: CurrentPoxCycle, + pub next_cycle: NextPoxCycle, } impl PoxInfo { @@ -84,6 +89,7 @@ impl PoxInfo { PoxInfo { contract_id: "ST000000000000000000002AMW42H.pox-3".into(), pox_activation_threshold_ustx: 0, + current_burnchain_block_height: 2000000, first_burnchain_block_height: 2000000, prepare_phase_block_length: 50, reward_phase_block_length: 1000, @@ -103,20 +109,33 @@ impl Default for PoxInfo { PoxInfo { contract_id: "ST000000000000000000002AMW42H.pox".into(), pox_activation_threshold_ustx: 0, + current_burnchain_block_height: 100, first_burnchain_block_height: 100, prepare_phase_block_length: 4, reward_phase_block_length: 6, - reward_slots: 12, + reward_slots: 10, total_liquid_supply_ustx: 1000000000000000, reward_cycle_id: 0, - next_cycle: PoxCycle::default(), + current_cycle: CurrentPoxCycle::default(), + next_cycle: NextPoxCycle::default(), } } } #[derive(Deserialize, Debug, Clone, Default)] -pub struct PoxCycle { +pub struct CurrentPoxCycle { + pub id: u64, pub min_threshold_ustx: u64, + pub stacked_ustx: u64, + pub is_pox_active: bool, +} + +#[derive(Deserialize, Debug, Clone, Default)] +pub struct NextPoxCycle { + pub min_threshold_ustx: u64, + pub stacked_ustx: u64, + pub blocks_until_prepare_phase: i16, + pub blocks_until_reward_phase: i16, } #[derive(Deserialize, Debug)] @@ -215,27 +234,23 @@ impl StacksRpc { pub fn get_pox_info(&self) -> Result { let request_url = format!("{}/v2/pox", self.url); - let res: PoxInfo = self - .client + self.client .get(request_url) .send() .map_err(|e| RpcError::Message(e.to_string()))? - .json() - .map_err(|e| RpcError::Message(e.to_string()))?; - Ok(res) + .json::() + .map_err(|e| RpcError::Message(e.to_string())) } pub fn get_info(&self) -> Result { let request_url = format!("{}/v2/info", self.url); - let res: NodeInfo = self - .client + self.client .get(request_url) .send() .map_err(|e| RpcError::Message(e.to_string()))? - .json() - .map_err(|e| RpcError::Message(e.to_string()))?; - Ok(res) + .json::() + .map_err(|e| RpcError::Message(e.to_string())) } pub fn get_contract_source( diff --git a/dockerfiles/components/clarinet-dev.dockerfile b/dockerfiles/components/clarinet-dev.dockerfile index 6b668bdc9..0eb3cc4d0 100644 --- a/dockerfiles/components/clarinet-dev.dockerfile +++ b/dockerfiles/components/clarinet-dev.dockerfile @@ -2,9 +2,9 @@ FROM rust:bookworm as build WORKDIR /src -RUN apt update && apt install -y ca-certificates pkg-config libssl-dev +RUN apt update && apt install -y ca-certificates pkg-config libssl-dev libclang-dev -RUN rustup update stable && rustup default stable +RUN rustup update stable && rustup default stable && rustup toolchain install stable --component rustfmt COPY . .