From 38e844d3bb7b671c1ec1c1a42b9e8e0a97322757 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 18:19:02 +0000 Subject: [PATCH 1/5] Weekly `cargo update` (#2453) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Automation to keep dependencies in `Cargo.lock` current. The following is the output from `cargo update`: ```txt info: syncing channel updates for '1.79.0-x86_64-unknown-linux-gnu' info: latest update on 2024-06-13, rust version 1.79.0 (129f3b996 2024-06-10) info: downloading component 'rust-std' for 'wasm32-unknown-unknown' info: installing component 'rust-std' for 'wasm32-unknown-unknown'  Locking 42 packages to latest compatible versions  Updating async-fs v1.6.0 -> v2.1.2  Updating async-net v1.8.0 -> v2.0.0  Updating async-process v1.8.1 -> v2.3.0  Updating const-hex v1.13.1 -> v1.13.2  Updating cpufeatures v0.2.15 -> v0.2.16  Updating cynic-parser v0.8.3 -> v0.8.4  Removing event-listener v3.1.0  Updating hyper v1.5.0 -> v1.5.1  Updating if-watch v3.2.0 -> v3.2.1  Updating impl-trait-for-tuples v0.2.2 -> v0.2.3  Updating itoa v1.0.11 -> v1.0.13  Updating libp2p-identity v0.2.9 -> v0.2.10  Updating litemap v0.7.3 -> v0.7.4  Updating netlink-packet-core v0.4.2 -> v0.7.0  Updating netlink-packet-route v0.12.0 -> v0.17.1 (latest: v0.21.0)  Updating netlink-proto v0.10.0 -> v0.11.3  Removing nix v0.24.3  Updating parity-scale-codec v3.6.12 -> v3.7.0  Updating parity-scale-codec-derive v3.6.12 -> v3.7.0  Updating portable-atomic v1.9.0 -> v1.10.0  Updating proc-macro2 v1.0.89 -> v1.0.92  Updating rtnetlink v0.10.1 -> v0.13.1 (latest: v0.14.1)  Updating rustix v0.38.40 -> v0.38.41  Updating rustls v0.23.17 -> v0.23.18  Updating scale-info v2.11.5 -> v2.11.6  Updating scale-info-derive v2.11.5 -> v2.11.6  Updating schannel v0.1.26 -> v0.1.27  Updating serde_json v1.0.132 -> v1.0.133  Updating smol v1.3.0 -> v2.0.2  Updating syn v2.0.87 -> v2.0.89  Updating sync_wrapper v1.0.1 -> v1.0.2  Adding system-configuration v0.6.1  Adding system-configuration-sys v0.6.0  Updating unicode-ident v1.0.13 -> v1.0.14  Updating url v2.5.3 -> v2.5.4  Updating webpki-roots v0.26.6 -> v0.26.7  Updating windows v0.51.1 -> v0.53.0 (latest: v0.58.0)  Updating windows-core v0.51.1 -> v0.53.0 (latest: v0.58.0)  Adding windows-result v0.1.2 (latest: v0.2.0)  Updating yamux v0.13.3 -> v0.13.4  Updating yoke v0.7.4 -> v0.7.5  Updating yoke-derive v0.7.4 -> v0.7.5  Updating zerofrom v0.1.4 -> v0.1.5  Updating zerofrom-derive v0.1.4 -> v0.1.5 note: pass `--verbose` to see 263 unchanged dependencies behind latest ``` Co-authored-by: github-actions Co-authored-by: Green Baneling --- Cargo.lock | 441 ++++++++++++++++++++++++++++------------------------- 1 file changed, 229 insertions(+), 212 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 77cc703905c..1ed9dd67683 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -230,7 +230,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "synstructure", ] @@ -242,7 +242,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -311,14 +311,13 @@ dependencies = [ [[package]] name = "async-fs" -version = "1.6.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" dependencies = [ - "async-lock 2.8.0", - "autocfg", + "async-lock 3.4.0", "blocking", - "futures-lite 1.13.0", + "futures-lite 2.5.0", ] [[package]] @@ -383,7 +382,7 @@ dependencies = [ "proc-macro2", "quote", "strum 0.26.3", - "syn 2.0.87", + "syn 2.0.89", "thiserror 1.0.69", ] @@ -444,7 +443,7 @@ dependencies = [ "futures-lite 2.5.0", "parking", "polling 3.7.4", - "rustix 0.38.40", + "rustix 0.38.41", "slab", "tracing", "windows-sys 0.59.0", @@ -472,30 +471,32 @@ dependencies = [ [[package]] name = "async-net" -version = "1.8.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0434b1ed18ce1cf5769b8ac540e33f01fa9471058b5e89da9e06f3c882a8c12f" +checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" dependencies = [ - "async-io 1.13.0", + "async-io 2.4.0", "blocking", - "futures-lite 1.13.0", + "futures-lite 2.5.0", ] [[package]] name = "async-process" -version = "1.8.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" dependencies = [ - "async-io 1.13.0", - "async-lock 2.8.0", + "async-channel 2.3.1", + "async-io 2.4.0", + "async-lock 3.4.0", "async-signal", + "async-task", "blocking", "cfg-if", - "event-listener 3.1.0", - "futures-lite 1.13.0", - "rustix 0.38.40", - "windows-sys 0.48.0", + "event-listener 5.3.1", + "futures-lite 2.5.0", + "rustix 0.38.41", + "tracing", ] [[package]] @@ -510,7 +511,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 0.38.40", + "rustix 0.38.41", "signal-hook-registry", "slab", "windows-sys 0.59.0", @@ -561,7 +562,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -578,7 +579,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -663,7 +664,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -1133,7 +1134,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -1514,7 +1515,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -1620,9 +1621,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0121754e84117e65f9d90648ee6aa4882a6e63110307ab73967a4c5e7e69e586" +checksum = "487981fa1af147182687064d0a2c336586d337a606595ced9ffb0c685c250c73" dependencies = [ "cfg-if", "cpufeatures", @@ -1754,9 +1755,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -2087,7 +2088,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2118,15 +2119,15 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.87", + "syn 2.0.89", "thiserror 1.0.69", ] [[package]] name = "cynic-parser" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791001e353ca2b167bd9e3c7c10635440893a6e0fd3c75bd9da700e373c6b0d5" +checksum = "421220154aa57cc1a72c886d6dc068c8fd9fdb81c860cbc299b0a9fce9ce8f08" dependencies = [ "indexmap 2.6.0", "lalrpop-util 0.22.0", @@ -2142,7 +2143,7 @@ dependencies = [ "cynic-codegen", "darling", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2166,7 +2167,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2177,7 +2178,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2270,7 +2271,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2290,7 +2291,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2406,7 +2407,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2575,7 +2576,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2595,7 +2596,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2750,7 +2751,7 @@ dependencies = [ "reqwest 0.11.27", "serde", "serde_json", - "syn 2.0.87", + "syn 2.0.89", "toml 0.8.19", "walkdir", ] @@ -2768,7 +2769,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2794,7 +2795,7 @@ dependencies = [ "serde", "serde_json", "strum 0.26.3", - "syn 2.0.87", + "syn 2.0.89", "tempfile", "thiserror 1.0.69", "tiny-keccak", @@ -2945,17 +2946,6 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" -[[package]] -name = "event-listener" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - [[package]] name = "event-listener" version = "5.3.1" @@ -3894,7 +3884,7 @@ checksum = "3f49fdbfc1615d88d2849650afc2b0ac2fecd69661ebadd31a073d8416747764" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "synstructure", ] @@ -3906,7 +3896,7 @@ checksum = "ab0bc46a3552964bae5169e79b383761a54bd115ea66951a1a7a229edcefa55a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "synstructure", ] @@ -4207,7 +4197,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -4217,7 +4207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" dependencies = [ "futures-io", - "rustls 0.23.17", + "rustls 0.23.18", "rustls-pki-types", ] @@ -4754,9 +4744,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" dependencies = [ "bytes", "futures-channel", @@ -4796,14 +4786,14 @@ checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", "http 1.1.0", - "hyper 1.5.0", + "hyper 1.5.1", "hyper-util", - "rustls 0.23.17", + "rustls 0.23.18", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", "tower-service", - "webpki-roots 0.26.6", + "webpki-roots 0.26.7", ] [[package]] @@ -4829,7 +4819,7 @@ dependencies = [ "futures-util", "http 1.1.0", "http-body 1.0.1", - "hyper 1.5.0", + "hyper 1.5.1", "pin-project-lite", "socket2 0.5.7", "tokio", @@ -4975,7 +4965,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -5033,9 +5023,9 @@ dependencies = [ [[package]] name = "if-watch" -version = "3.2.0" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b0422c86d7ce0e97169cc42e04ae643caf278874a7a3c87b8150a220dc7e1e" +checksum = "cdf9d64cfcf380606e64f9a0bcf493616b65331199f984151a6fa11a7b3cde38" dependencies = [ "async-io 2.4.0", "core-foundation", @@ -5044,9 +5034,13 @@ dependencies = [ "if-addrs", "ipnet", "log", + "netlink-packet-core", + "netlink-packet-route", + "netlink-proto", + "netlink-sys", "rtnetlink", "smol", - "system-configuration", + "system-configuration 0.6.1", "tokio", "windows", ] @@ -5106,7 +5100,7 @@ dependencies = [ "autocfg", "impl-tools-lib", "proc-macro-error2", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -5118,18 +5112,18 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] name = "impl-trait-for-tuples" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.89", ] [[package]] @@ -5290,9 +5284,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" [[package]] name = "jobserver" @@ -5623,9 +5617,9 @@ dependencies = [ [[package]] name = "libp2p-identity" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cca1eb2bc1fd29f099f3daaab7effd01e1a54b7c577d0ed082521034d912e8" +checksum = "257b5621d159b32282eac446bed6670c39c7dc68a200a992d8f056afa0066f6d" dependencies = [ "asn1_der", "bs58", @@ -5787,7 +5781,7 @@ dependencies = [ "quinn", "rand", "ring 0.17.8", - "rustls 0.23.17", + "rustls 0.23.18", "socket2 0.5.7", "thiserror 1.0.69", "tokio", @@ -5848,7 +5842,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -5900,7 +5894,7 @@ dependencies = [ "libp2p-identity", "rcgen", "ring 0.17.8", - "rustls 0.23.17", + "rustls 0.23.18", "rustls-webpki 0.101.7", "thiserror 1.0.69", "x509-parser", @@ -5956,7 +5950,7 @@ dependencies = [ "thiserror 1.0.69", "tracing", "yamux 0.12.1", - "yamux 0.13.3", + "yamux 0.13.4", ] [[package]] @@ -6086,9 +6080,9 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "litemap" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "litrs" @@ -6136,7 +6130,7 @@ dependencies = [ "proc-macro2", "quote", "regex-syntax 0.8.5", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -6228,7 +6222,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "rustix 0.38.40", + "rustix 0.38.41", ] [[package]] @@ -6395,21 +6389,20 @@ dependencies = [ [[package]] name = "netlink-packet-core" -version = "0.4.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345b8ab5bd4e71a2986663e88c56856699d060e78e152e6e9d7966fcd5491297" +checksum = "72724faf704479d67b388da142b186f916188505e7e0b26719019c525882eda4" dependencies = [ "anyhow", "byteorder", - "libc", "netlink-packet-utils", ] [[package]] name = "netlink-packet-route" -version = "0.12.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9ea4302b9759a7a88242299225ea3688e63c85ea136371bb6cf94fd674efaab" +checksum = "053998cea5a306971f88580d0829e90f270f940befd7cf928da179d4187a5a66" dependencies = [ "anyhow", "bitflags 1.3.2", @@ -6433,9 +6426,9 @@ dependencies = [ [[package]] name = "netlink-proto" -version = "0.10.0" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6" +checksum = "86b33524dc0968bfad349684447bfce6db937a9ac3332a1fe60c0c5a5ce63f21" dependencies = [ "bytes", "futures", @@ -6466,17 +6459,6 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" -[[package]] -name = "nix" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", -] - [[package]] name = "nix" version = "0.26.4" @@ -6639,7 +6621,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -6767,7 +6749,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -6796,28 +6778,29 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.12" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +checksum = "8be4817d39f3272f69c59fe05d0535ae6456c2dc2fa1ba02910296c7e0a5c590" dependencies = [ "arrayvec", "bitvec", "byte-slice-cast", "impl-trait-for-tuples", "parity-scale-codec-derive", + "rustversion", "serde", ] [[package]] name = "parity-scale-codec-derive" -version = "3.6.12" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" +checksum = "8781a75c6205af67215f382092b6e0a4ff3734798523e69073d4bcd294ec767b" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.89", ] [[package]] @@ -7039,7 +7022,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -7077,7 +7060,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -7173,7 +7156,7 @@ dependencies = [ "concurrent-queue", "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.40", + "rustix 0.38.41", "tracing", "windows-sys 0.59.0", ] @@ -7203,9 +7186,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "postcard" @@ -7319,7 +7302,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -7401,9 +7384,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -7416,7 +7399,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "version_check", "yansi 1.0.1", ] @@ -7441,7 +7424,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -7622,7 +7605,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash 2.0.0", - "rustls 0.23.17", + "rustls 0.23.18", "socket2 0.5.7", "thiserror 2.0.3", "tokio", @@ -7640,7 +7623,7 @@ dependencies = [ "rand", "ring 0.17.8", "rustc-hash 2.0.0", - "rustls 0.23.17", + "rustls 0.23.18", "rustls-pki-types", "slab", "thiserror 2.0.3", @@ -7810,7 +7793,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -7905,7 +7888,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", - "system-configuration", + "system-configuration 0.5.1", "tokio", "tokio-rustls 0.24.1", "tower-service", @@ -7932,7 +7915,7 @@ dependencies = [ "http 1.1.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.0", + "hyper 1.5.1", "hyper-rustls 0.27.3", "hyper-util", "ipnet", @@ -7943,13 +7926,13 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.17", + "rustls 0.23.18", "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tokio", "tokio-rustls 0.26.0", "tower-service", @@ -7957,7 +7940,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.26.6", + "webpki-roots 0.26.7", "windows-registry", ] @@ -8094,16 +8077,19 @@ dependencies = [ [[package]] name = "rtnetlink" -version = "0.10.1" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322c53fd76a18698f1c27381d58091de3a043d356aa5bd0d510608b565f469a0" +checksum = "7a552eb82d19f38c3beed3f786bd23aa434ceb9ac43ab44419ca6d67a7e186c0" dependencies = [ "async-global-executor", "futures", "log", + "netlink-packet-core", "netlink-packet-route", + "netlink-packet-utils", "netlink-proto", - "nix 0.24.3", + "netlink-sys", + "nix 0.26.4", "thiserror 1.0.69", "tokio", ] @@ -8166,9 +8152,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.40" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.6.0", "errno", @@ -8191,9 +8177,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.17" +version = "0.23.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f1a745511c54ba6d4465e8d5dfbd81b45791756de28d4981af70d6dca128f1e" +checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f" dependencies = [ "once_cell", "ring 0.17.8", @@ -8318,9 +8304,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.11.5" +version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aa7ffc1c0ef49b0452c6e2986abf2b07743320641ffd5fc63d552458e3b779b" +checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" dependencies = [ "cfg-if", "derive_more 1.0.0", @@ -8330,21 +8316,21 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.11.5" +version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46385cc24172cf615450267463f937c10072516359b3ff1cb24228a4a08bf951" +checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] name = "schannel" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ "windows-sys 0.59.0", ] @@ -8512,14 +8498,14 @@ checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -8575,7 +8561,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -8741,19 +8727,19 @@ dependencies = [ [[package]] name = "smol" -version = "1.3.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13f2b548cd8447f8de0fdf1c592929f70f4fc7039a05e47404b0d096ec6987a1" +checksum = "a33bd3e260892199c3ccfc487c88b2da2265080acb316cd920da72fdfd7c599f" dependencies = [ - "async-channel 1.9.0", + "async-channel 2.3.1", "async-executor", "async-fs", - "async-io 1.13.0", - "async-lock 2.8.0", + "async-io 2.4.0", + "async-lock 3.4.0", "async-net", "async-process", "blocking", - "futures-lite 1.13.0", + "futures-lite 2.5.0", ] [[package]] @@ -8905,7 +8891,7 @@ dependencies = [ "proc-macro2", "quote", "structmeta-derive", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -8916,7 +8902,7 @@ checksum = "a60bcaff7397072dca0017d1db428e30d5002e00b6847703e2e42005c95fbe00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -8969,7 +8955,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -8982,7 +8968,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -9047,9 +9033,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.87" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", @@ -9064,9 +9050,9 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "sync_wrapper" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" dependencies = [ "futures-core", ] @@ -9079,7 +9065,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -9090,7 +9076,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation", - "system-configuration-sys", + "system-configuration-sys 0.5.0", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "system-configuration-sys 0.6.0", ] [[package]] @@ -9103,6 +9100,16 @@ dependencies = [ "libc", ] +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tai64" version = "4.1.0" @@ -9133,7 +9140,7 @@ dependencies = [ "cfg-if", "fastrand 2.2.0", "once_cell", - "rustix 0.38.40", + "rustix 0.38.41", "windows-sys 0.59.0", ] @@ -9193,7 +9200,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -9204,7 +9211,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "test-case-core", ] @@ -9241,7 +9248,7 @@ dependencies = [ "proc-macro2", "quote", "structmeta", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -9276,7 +9283,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -9287,7 +9294,7 @@ checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -9451,7 +9458,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -9480,7 +9487,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.17", + "rustls 0.23.18", "rustls-pki-types", "tokio", ] @@ -9668,7 +9675,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -9809,9 +9816,9 @@ checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-normalization" @@ -9886,9 +9893,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.3" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna 1.0.3", @@ -10042,7 +10049,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "wasm-bindgen-shared", ] @@ -10076,7 +10083,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -10145,7 +10152,7 @@ dependencies = [ "postcard", "psm", "rayon", - "rustix 0.38.40", + "rustix 0.38.41", "serde", "serde_derive", "smallvec", @@ -10183,7 +10190,7 @@ dependencies = [ "directories-next", "log", "postcard", - "rustix 0.38.40", + "rustix 0.38.41", "serde", "serde_derive", "sha2 0.10.8", @@ -10201,7 +10208,7 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "wasmtime-component-util", "wasmtime-wit-bindgen", "wit-parser", @@ -10300,7 +10307,7 @@ checksum = "a2bde986038b819bc43a21fef0610aeb47aabfe3ea09ca3533a7b81023b84ec6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -10343,9 +10350,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webpki-roots" -version = "0.26.6" +version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" dependencies = [ "rustls-pki-types", ] @@ -10389,29 +10396,30 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.51.1" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" +checksum = "efc5cf48f83140dcaab716eeaea345f9e93d0018fb81162753a3f76c3397b538" dependencies = [ - "windows-core 0.51.1", - "windows-targets 0.48.5", + "windows-core 0.53.0", + "windows-targets 0.52.6", ] [[package]] name = "windows-core" -version = "0.51.1" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] name = "windows-core" -version = "0.52.0" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "9dcc5b895a6377f1ab9fa55acedab1fd5ac0db66ad1e6c7f47e28a22e446a5dd" dependencies = [ + "windows-result 0.1.2", "windows-targets 0.52.6", ] @@ -10421,11 +10429,20 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" dependencies = [ - "windows-result", + "windows-result 0.2.0", "windows-strings", "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-result" version = "0.2.0" @@ -10441,7 +10458,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows-result", + "windows-result 0.2.0", "windows-targets 0.52.6", ] @@ -10745,9 +10762,9 @@ dependencies = [ [[package]] name = "yamux" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31b5e376a8b012bee9c423acdbb835fc34d45001cfa3106236a624e4b738028" +checksum = "17610762a1207ee816c6fadc29220904753648aba0a9ed61c7b8336e80a559c4" dependencies = [ "futures", "log", @@ -10782,9 +10799,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", @@ -10794,13 +10811,13 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "synstructure", ] @@ -10822,27 +10839,27 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] name = "zerofrom" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "synstructure", ] @@ -10863,7 +10880,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -10885,7 +10902,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] From 000fcb129157dadffffc35148ab109a75da586a7 Mon Sep 17 00:00:00 2001 From: Matt <54373384+matt-user@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:40:01 -0600 Subject: [PATCH 2/5] refactor: remove `Option` and use new enum where applicable (#2033) closes #2005 I replaced `Option` with `BlockHeightQuery` where applicable. IIUC there are `Option` which should remain. ## Checklist - [X] Breaking changes are clearly marked as such in the PR description and changelog - [X] New behavior is reflected in tests - [X] [The specification](https://github.com/FuelLabs/fuel-specs/) matches the implemented behavior (link update PR if changes are needed) ### Before requesting review - [X] I have reviewed the code myself - [ ] I have created follow-up issues caused by this PR and linked them here ### After merging, notify other teams [Add or remove entries as needed] - [ ] [Rust SDK](https://github.com/FuelLabs/fuels-rs/) - [ ] [Sway compiler](https://github.com/FuelLabs/sway/) - [ ] [Platform documentation](https://github.com/FuelLabs/devrel-requests/issues/new?assignees=&labels=new+request&projects=&template=NEW-REQUEST.yml&title=%5BRequest%5D%3A+) (for out-of-organization contributors, the person merging the PR will do this) - [ ] Someone else? --- CHANGELOG.md | 2 +- crates/fuel-core/src/graphql_api/ports.rs | 12 ++- .../src/graphql_api/worker_service.rs | 10 ++- crates/fuel-core/src/schema/block.rs | 6 +- .../src/service/adapters/graphql_api.rs | 3 +- .../adapters/import_result_provider.rs | 76 ++++++++++--------- 6 files changed, 66 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17329a646aa..29d283eac87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [2376](https://github.com/FuelLabs/fuel-core/pull/2376): Add a way to fetch transactions in P2P without specifying a peer. - [2327](https://github.com/FuelLabs/fuel-core/pull/2327): Add more services tests and more checks of the pool. Also add an high level documentation for users of the pool and contributors. - [2416](https://github.com/FuelLabs/fuel-core/issues/2416): Define the `GasPriceServiceV1` task. - +- [2033](https://github.com/FuelLabs/fuel-core/pull/2033): Remove `Option` in favor of `BlockHeightQuery` where applicable. ### Fixed - [2366](https://github.com/FuelLabs/fuel-core/pull/2366): The `importer_gas_price_for_block` metric is properly collected. diff --git a/crates/fuel-core/src/graphql_api/ports.rs b/crates/fuel-core/src/graphql_api/ports.rs index 077a48d1637..307904c9a92 100644 --- a/crates/fuel-core/src/graphql_api/ports.rs +++ b/crates/fuel-core/src/graphql_api/ports.rs @@ -282,6 +282,7 @@ pub mod worker { relayed_transactions::RelayedTransactionStatuses, }, }; + use derive_more::Display; use fuel_core_services::stream::BoxStream; use fuel_core_storage::{ Error as StorageError, @@ -317,6 +318,15 @@ pub mod worker { fn transaction(&mut self) -> Self::Transaction<'_>; } + /// Represents either the Genesis Block or a block at a specific height + #[derive(Copy, Clone, Debug, Display, PartialEq, Eq, Hash, Ord, PartialOrd)] + pub enum BlockAt { + /// Block at a specific height + Specific(BlockHeight), + /// Genesis block + Genesis, + } + pub trait OffChainDatabaseTransaction: StorageMutate + StorageMutate @@ -369,7 +379,7 @@ pub mod worker { /// Return the import result at the given height. fn block_event_at_height( &self, - height: Option, + height: BlockAt, ) -> anyhow::Result; } diff --git a/crates/fuel-core/src/graphql_api/worker_service.rs b/crates/fuel-core/src/graphql_api/worker_service.rs index 8d5b0bc923f..6c29e49e7e4 100644 --- a/crates/fuel-core/src/graphql_api/worker_service.rs +++ b/crates/fuel-core/src/graphql_api/worker_service.rs @@ -10,7 +10,10 @@ use crate::{ fuel_core_graphql_api::{ ports::{ self, - worker::OffChainDatabaseTransaction, + worker::{ + BlockAt, + OffChainDatabaseTransaction, + }, }, storage::{ blocks::FuelBlockIdsToHeights, @@ -537,6 +540,11 @@ where let next_block_height = off_chain_height.map(|height| BlockHeight::new(height.saturating_add(1))); + let next_block_height = match next_block_height { + Some(block_height) => BlockAt::Specific(block_height), + None => BlockAt::Genesis, + }; + let import_result = import_result_provider.block_event_at_height(next_block_height)?; diff --git a/crates/fuel-core/src/schema/block.rs b/crates/fuel-core/src/schema/block.rs index 7cdfeff2d5b..061fcb6e7de 100644 --- a/crates/fuel-core/src/schema/block.rs +++ b/crates/fuel-core/src/schema/block.rs @@ -45,8 +45,10 @@ use fuel_core_types::{ header::BlockHeader, }, fuel_tx::TxId, - fuel_types, - fuel_types::BlockHeight, + fuel_types::{ + self, + BlockHeight, + }, }; use futures::{ Stream, diff --git a/crates/fuel-core/src/service/adapters/graphql_api.rs b/crates/fuel-core/src/service/adapters/graphql_api.rs index ff96e484ed9..43cd0471794 100644 --- a/crates/fuel-core/src/service/adapters/graphql_api.rs +++ b/crates/fuel-core/src/service/adapters/graphql_api.rs @@ -9,6 +9,7 @@ use crate::{ database::OnChainIterableKeyValueView, fuel_core_graphql_api::ports::{ worker, + worker::BlockAt, BlockProducerPort, ConsensusProvider, DatabaseMessageProof, @@ -218,7 +219,7 @@ impl worker::BlockImporter for GraphQLBlockImporter { fn block_event_at_height( &self, - height: Option, + height: BlockAt, ) -> anyhow::Result { self.import_result_provider_adapter.result_at_height(height) } diff --git a/crates/fuel-core/src/service/adapters/import_result_provider.rs b/crates/fuel-core/src/service/adapters/import_result_provider.rs index fb1c699db80..3506ca2bddd 100644 --- a/crates/fuel-core/src/service/adapters/import_result_provider.rs +++ b/crates/fuel-core/src/service/adapters/import_result_provider.rs @@ -1,5 +1,6 @@ use crate::{ database::Database, + fuel_core_graphql_api::ports::worker::BlockAt, service::adapters::ExecutorAdapter, }; use fuel_core_importer::ports::Validator; @@ -7,15 +8,12 @@ use fuel_core_storage::{ not_found, transactional::AtomicView, }; -use fuel_core_types::{ - fuel_types::BlockHeight, - services::{ - block_importer::{ - ImportResult, - SharedImportResult, - }, - executor::ValidationResult, +use fuel_core_types::services::{ + block_importer::{ + ImportResult, + SharedImportResult, }, + executor::ValidationResult, }; use std::sync::Arc; @@ -37,38 +35,42 @@ impl ImportResultProvider { impl ImportResultProvider { pub fn result_at_height( &self, - height: Option, + height: BlockAt, ) -> anyhow::Result { - if let Some(height) = height { - let sealed_block = self - .on_chain_database - .latest_view()? - .get_sealed_block_by_height(&height)? - .ok_or(not_found!("SealedBlock"))?; + match height { + BlockAt::Specific(height) => { + let sealed_block = self + .on_chain_database + .latest_view()? + .get_sealed_block_by_height(&height)? + .ok_or(not_found!("SealedBlock"))?; - let ValidationResult { tx_status, events } = self - .executor_adapter - .validate(&sealed_block.entity)? - .into_result(); - let result = ImportResult::new_from_local(sealed_block, tx_status, events); - Ok(Arc::new(result)) - } else { - let genesis_height = self - .on_chain_database - .latest_view()? - .genesis_height()? - .ok_or(not_found!("Genesis height"))?; - let sealed_block = self - .on_chain_database - .latest_view()? - .get_sealed_block_by_height(&genesis_height)? - .ok_or(not_found!("SealedBlock"))?; + let ValidationResult { tx_status, events } = self + .executor_adapter + .validate(&sealed_block.entity)? + .into_result(); + let result = + ImportResult::new_from_local(sealed_block, tx_status, events); + Ok(Arc::new(result)) + } + BlockAt::Genesis => { + let genesis_height = self + .on_chain_database + .latest_view()? + .genesis_height()? + .ok_or(not_found!("Genesis height"))?; + let sealed_block = self + .on_chain_database + .latest_view()? + .get_sealed_block_by_height(&genesis_height)? + .ok_or(not_found!("SealedBlock"))?; - Ok(Arc::new(ImportResult::new_from_local( - sealed_block, - vec![], - vec![], - ))) + Ok(Arc::new(ImportResult::new_from_local( + sealed_block, + vec![], + vec![], + ))) + } } } } From b6cbb3522f9907f273cec68dd23108e9bd7bc472 Mon Sep 17 00:00:00 2001 From: Green Baneling Date: Tue, 26 Nov 2024 18:24:09 -0500 Subject: [PATCH 3/5] Fixed the error during dry run (#2365) Because of race condition it was possible that dry run will fail. I moved the check to production, where we really need to require this behavior. But in the case of the dry run we only care about previous block existence. ## Checklist - [x] New behavior is reflected in tests ### Before requesting review - [x] I have reviewed the code myself --- CHANGELOG.md | 1 + .../consensus_module/poa/src/service.rs | 2 - .../services/producer/src/block_producer.rs | 81 ++++++++++++------- .../producer/src/block_producer/tests.rs | 44 +++++----- crates/services/producer/src/mocks.rs | 62 +++----------- 5 files changed, 88 insertions(+), 102 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29d283eac87..267d8ea129c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [2033](https://github.com/FuelLabs/fuel-core/pull/2033): Remove `Option` in favor of `BlockHeightQuery` where applicable. ### Fixed +- [2365](https://github.com/FuelLabs/fuel-core/pull/2365): Fixed the error during dry run in the case of race condition. - [2366](https://github.com/FuelLabs/fuel-core/pull/2366): The `importer_gas_price_for_block` metric is properly collected. - [2369](https://github.com/FuelLabs/fuel-core/pull/2369): The `transaction_insertion_time_in_thread_pool_milliseconds` metric is properly collected. - [2413](https://github.com/FuelLabs/fuel-core/issues/2413): block production immediately errors if unable to lock the mutex. diff --git a/crates/services/consensus_module/poa/src/service.rs b/crates/services/consensus_module/poa/src/service.rs index 795f4ced784..dc09c2d4dc2 100644 --- a/crates/services/consensus_module/poa/src/service.rs +++ b/crates/services/consensus_module/poa/src/service.rs @@ -360,8 +360,6 @@ where consensus: seal, }; - block.entity.header().time(); - // Import the sealed block self.block_importer .commit_result(Uncommitted::new( diff --git a/crates/services/producer/src/block_producer.rs b/crates/services/producer/src/block_producer.rs index ef8747b9a33..f5ad44be901 100644 --- a/crates/services/producer/src/block_producer.rs +++ b/crates/services/producer/src/block_producer.rs @@ -127,8 +127,20 @@ where let da_height = predefined_block.header().application().da_height; + let view = self.view_provider.latest_view()?; + let header_to_produce = - self.new_header_with_da_height(height, block_time, da_height)?; + self.new_header_with_da_height(height, block_time, da_height, &view)?; + + let latest_height = view.latest_height().ok_or(Error::NoGenesisBlock)?; + + if header_to_produce.height() <= &latest_height { + return Err(Error::BlockHeightShouldBeHigherThanPrevious { + height, + previous_block: latest_height, + } + .into()) + } let maybe_mint_tx = transactions_source.pop(); let mint_tx = @@ -196,10 +208,22 @@ where let source = tx_source(gas_price, height).await?; + let view = self.view_provider.latest_view()?; + let header = self - .new_header_with_new_da_height(height, block_time) + .new_header_with_new_da_height(height, block_time, &view) .await?; + let latest_height = view.latest_height().ok_or(Error::NoGenesisBlock)?; + + if header.height() <= &latest_height { + return Err(Error::BlockHeightShouldBeHigherThanPrevious { + height, + previous_block: latest_height, + } + .into()) + } + let component = Components { header_to_produce: header, transactions_source: source, @@ -309,7 +333,7 @@ where .unwrap_or(Tai64::UNIX_EPOCH) }); - let header = self.new_header(simulated_height, simulated_time)?; + let header = self.new_header(simulated_height, simulated_time, &view)?; let gas_price = if let Some(inner) = gas_price { inner @@ -367,8 +391,9 @@ where &self, height: BlockHeight, block_time: Tai64, + view: &ViewProvider::LatestView, ) -> anyhow::Result { - let mut block_header = self.new_header(height, block_time)?; + let mut block_header = self.new_header(height, block_time, view)?; let previous_da_height = block_header.da_height; let gas_limit = self .consensus_parameters_provider @@ -390,11 +415,13 @@ where height: BlockHeight, block_time: Tai64, da_height: DaBlockHeight, + view: &ViewProvider::LatestView, ) -> anyhow::Result { - let mut block_header = self.new_header(height, block_time)?; + let mut block_header = self.new_header(height, block_time, view)?; block_header.application.da_height = da_height; Ok(block_header) } + async fn select_new_da_height( &self, gas_limit: u64, @@ -447,9 +474,9 @@ where &self, height: BlockHeight, block_time: Tai64, + view: &ViewProvider::LatestView, ) -> anyhow::Result { - let view = self.view_provider.latest_view()?; - let previous_block_info = self.previous_block_info(height, &view)?; + let previous_block_info = self.previous_block_info(height, view)?; let consensus_parameters_version = view.latest_consensus_parameters_version()?; let state_transition_bytecode_version = view.latest_state_transition_bytecode_version()?; @@ -475,29 +502,23 @@ where height: BlockHeight, view: &ViewProvider::LatestView, ) -> anyhow::Result { - let latest_height = self - .view_provider - .latest_view()? - .latest_height() - .ok_or(Error::NoGenesisBlock)?; - // block 0 is reserved for genesis - if height <= latest_height { - Err(Error::BlockHeightShouldBeHigherThanPrevious { - height, - previous_block: latest_height, - } - .into()) - } else { - // get info from previous block height - let prev_height = height.pred().expect("We checked the height above"); - let previous_block = view.get_block(&prev_height)?; - let prev_root = view.block_header_merkle_root(&prev_height)?; - - Ok(PreviousBlockInfo { - prev_root, - da_height: previous_block.header().da_height, - }) - } + let latest_height = view.latest_height().ok_or(Error::NoGenesisBlock)?; + + // get info from previous block height + let prev_height = + height + .pred() + .ok_or(Error::BlockHeightShouldBeHigherThanPrevious { + height: 0u32.into(), + previous_block: latest_height, + })?; + let previous_block = view.get_block(&prev_height)?; + let prev_root = view.block_header_merkle_root(&prev_height)?; + + Ok(PreviousBlockInfo { + prev_root, + da_height: previous_block.header().da_height, + }) } } diff --git a/crates/services/producer/src/block_producer/tests.rs b/crates/services/producer/src/block_producer/tests.rs index 8a532361ede..f8b18b549d5 100644 --- a/crates/services/producer/src/block_producer/tests.rs +++ b/crates/services/producer/src/block_producer/tests.rs @@ -649,27 +649,33 @@ mod dry_run { } #[tokio::test] - async fn dry_run__errors_early_if_height_is_lower_than_chain_tip() { - // Given - let last_block_height = BlockHeight::new(42); - + async fn dry_run__success_when_height_is_the_same_as_chain_height() { let executor = MockExecutorWithCapture::default(); - let ctx = TestContextBuilder::new() - .with_prev_height(last_block_height) - .build_with_executor(executor.clone()); + let ctx = TestContext::default_from_executor(executor); + let producer = ctx.producer(); - // When - let _ = ctx - .producer() - .dry_run(vec![], last_block_height.pred(), None, None, None) + const SAME_HEIGHT: u32 = 1; + + // Given + let block = producer + .produce_and_execute_block_txpool(SAME_HEIGHT.into(), Tai64::now()) .await - .expect_err("expected failure"); + .unwrap(); + producer.view_provider.blocks.lock().unwrap().insert( + SAME_HEIGHT.into(), + block.result().block.clone().compress(&Default::default()), + ); + + // When + let result = producer + .dry_run(vec![], Some(SAME_HEIGHT.into()), None, None, None) + .await; // Then - assert!(executor.has_no_captured_block_timestamp()); + assert!(result.is_ok(), "{:?}", result); } - impl MockExecutorWithCapture { + impl MockExecutorWithCapture { fn captured_block_timestamp(&self) -> Tai64 { *self .captured @@ -680,10 +686,6 @@ mod dry_run { .header_to_produce .time() } - - fn has_no_captured_block_timestamp(&self) -> bool { - self.captured.lock().unwrap().is_none() - } } } @@ -722,10 +724,10 @@ prop_compose! { } #[allow(clippy::arithmetic_side_effects)] -fn ctx_for_block( +fn ctx_for_block( block: &Block, - executor: MockExecutorWithCapture, -) -> TestContext> { + executor: MockExecutorWithCapture, +) -> TestContext { let prev_height = block.header().height().pred().unwrap(); let prev_da_height = block.header().da_height.as_u64() - 1; TestContextBuilder::new() diff --git a/crates/services/producer/src/mocks.rs b/crates/services/producer/src/mocks.rs index f261fd675bd..797035866af 100644 --- a/crates/services/producer/src/mocks.rs +++ b/crates/services/producer/src/mocks.rs @@ -42,7 +42,6 @@ use fuel_core_types::{ TransactionExecutionStatus, UncommittedResult, }, - txpool::ArcPoolTx, }, }; use std::{ @@ -88,10 +87,10 @@ impl Relayer for MockRelayer { } #[derive(Default)] -pub struct MockTxPool(pub Vec); +pub struct MockTxPool(pub Vec); impl TxPool for MockTxPool { - type TxSource = Vec; + type TxSource = Vec; async fn get_source(&self, _: u64, _: BlockHeight) -> anyhow::Result { Ok(self.0.clone()) @@ -113,23 +112,7 @@ impl AsRef for MockDb { } } -fn arc_pool_tx_comp_to_block(component: &Components>) -> Block { - let transactions = component - .transactions_source - .clone() - .into_iter() - .map(|tx| tx.as_ref().into()) - .collect(); - Block::new( - component.header_to_produce, - transactions, - &[], - Default::default(), - ) - .unwrap() -} - -fn tx_comp_to_block(component: &Components>) -> Block { +fn arc_pool_tx_comp_to_block(component: &Components>) -> Block { let transactions = component.transactions_source.clone(); Block::new( component.header_to_produce, @@ -140,10 +123,10 @@ fn tx_comp_to_block(component: &Components>) -> Block { .unwrap() } -impl BlockProducer> for MockExecutor { +impl BlockProducer> for MockExecutor { fn produce_without_commit( &self, - component: Components>, + component: Components>, ) -> ExecutorResult> { let block = arc_pool_tx_comp_to_block(&component); // simulate executor inserting a block @@ -166,10 +149,10 @@ impl BlockProducer> for MockExecutor { pub struct FailingMockExecutor(pub Mutex>); -impl BlockProducer> for FailingMockExecutor { +impl BlockProducer> for FailingMockExecutor { fn produce_without_commit( &self, - component: Components>, + component: Components>, ) -> ExecutorResult> { // simulate an execution failure let mut err = self.0.lock().unwrap(); @@ -191,35 +174,16 @@ impl BlockProducer> for FailingMockExecutor { } #[derive(Clone)] -pub struct MockExecutorWithCapture { - pub captured: Arc>>>>, +pub struct MockExecutorWithCapture { + pub captured: Arc>>>>, } -impl BlockProducer> for MockExecutorWithCapture { - fn produce_without_commit( - &self, - component: Components>, - ) -> ExecutorResult> { - let block = arc_pool_tx_comp_to_block(&component); - *self.captured.lock().unwrap() = Some(component); - Ok(UncommittedResult::new( - ExecutionResult { - block, - skipped_transactions: vec![], - tx_status: vec![], - events: vec![], - }, - Default::default(), - )) - } -} - -impl BlockProducer> for MockExecutorWithCapture { +impl BlockProducer> for MockExecutorWithCapture { fn produce_without_commit( &self, component: Components>, ) -> ExecutorResult> { - let block = tx_comp_to_block(&component); + let block = arc_pool_tx_comp_to_block(&component); *self.captured.lock().unwrap() = Some(component); Ok(UncommittedResult::new( ExecutionResult { @@ -233,7 +197,7 @@ impl BlockProducer> for MockExecutorWithCapture { } } -impl DryRunner for MockExecutorWithCapture { +impl DryRunner for MockExecutorWithCapture { fn dry_run( &self, block: Components>, @@ -245,7 +209,7 @@ impl DryRunner for MockExecutorWithCapture { } } -impl Default for MockExecutorWithCapture { +impl Default for MockExecutorWithCapture { fn default() -> Self { Self { captured: Arc::new(Mutex::new(None)), From 9af3ad26632c9b6290d9ace54ed0345ac2d40224 Mon Sep 17 00:00:00 2001 From: Hannes Karppila <2204863+Dentosal@users.noreply.github.com> Date: Wed, 27 Nov 2024 15:42:39 +0200 Subject: [PATCH 4/5] Add decompression traits and a test case (#2295) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/FuelLabs/fuel-core/pull/1609#discussion_r1783545359 Add a test case for decompressing DA-compressed blocks. FIx `CombinedDb::from_config` to respects `state_rewind_policy` with tmp RocksDB. --------- Co-authored-by: RafaƂ Chabowski <88321181+rafal-ch@users.noreply.github.com> Co-authored-by: Green Baneling --- CHANGELOG.md | 1 + benches/benches/block_target_gas.rs | 4 +- crates/compression/src/lib.rs | 10 + crates/compression/src/registry.rs | 2 +- crates/fuel-core/src/combined_database.rs | 17 +- crates/fuel-core/src/database.rs | 14 +- crates/fuel-core/src/graphql_api.rs | 2 +- .../src/graphql_api/da_compression.rs | 181 +++++++++++++++++- .../fuel-core/src/state/generic_database.rs | 2 +- crates/storage/src/structured_storage.rs | 2 +- crates/storage/src/transactional.rs | 12 +- tests/tests/da_compression.rs | 80 ++++++-- 12 files changed, 290 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 267d8ea129c..af894952c11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [2389](https://github.com/FuelLabs/fuel-core/pull/2389): Fix construction of reverse iterator in RocksDB. ### Changed +- [2295](https://github.com/FuelLabs/fuel-core/pull/2295): `CombinedDb::from_config` now respects `state_rewind_policy` with tmp RocksDB. - [2378](https://github.com/FuelLabs/fuel-core/pull/2378): Use cached hash of the topic instead of calculating it on each publishing gossip message. - [2429](https://github.com/FuelLabs/fuel-core/pull/2429): Introduce custom enum for representing result of running service tasks - [2377](https://github.com/FuelLabs/fuel-core/pull/2377): Add more errors that can be returned as responses when using protocol `/fuel/req_res/0.0.2`. The errors supported are `ProtocolV1EmptyResponse` (status code `0`) for converting empty responses sent via protocol `/fuel/req_res/0.0.1`, `RequestedRangeTooLarge`(status code `1`) if the client requests a range of objects such as sealed block headers or transactions too large, `Timeout` (status code `2`) if the remote peer takes too long to fulfill a request, or `SyncProcessorOutOfCapacity` if the remote peer is fulfilling too many requests concurrently. diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 9574720a3df..fddd14a24c9 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -27,6 +27,7 @@ use fuel_core::{ Config, FuelService, }, + state::historical_rocksdb::StateRewindPolicy, }; use fuel_core_benches::{ default_gas_costs::default_gas_costs, @@ -265,7 +266,8 @@ fn service_with_many_contracts( .build() .unwrap(); let _drop = rt.enter(); - let mut database = Database::rocksdb_temp(); + let mut database = Database::rocksdb_temp(StateRewindPolicy::NoRewind) + .expect("Failed to create database"); let mut chain_config = ChainConfig::local_testnet(); diff --git a/crates/compression/src/lib.rs b/crates/compression/src/lib.rs index bd4b0fdcbba..d41deccefa1 100644 --- a/crates/compression/src/lib.rs +++ b/crates/compression/src/lib.rs @@ -16,6 +16,7 @@ pub use registry::RegistryKeyspace; use fuel_core_types::{ blockchain::header::PartialBlockHeader, fuel_tx::CompressedTransaction, + fuel_types::BlockHeight, }; use registry::RegistrationsPerTable; @@ -42,6 +43,15 @@ impl Default for VersionedCompressedBlock { } } +impl VersionedCompressedBlock { + /// Returns the height of the compressed block. + pub fn height(&self) -> &BlockHeight { + match self { + VersionedCompressedBlock::V0(block) => block.header.height(), + } + } +} + #[cfg(test)] mod tests { use fuel_core_compression as _; diff --git a/crates/compression/src/registry.rs b/crates/compression/src/registry.rs index 0bf1e3a5967..1fd20365d1a 100644 --- a/crates/compression/src/registry.rs +++ b/crates/compression/src/registry.rs @@ -78,7 +78,7 @@ macro_rules! tables { impl RegistrationsPerTable { - pub(crate) fn write_to_registry(&self, registry: &mut R, timestamp: Tai64) -> anyhow::Result<()> + pub fn write_to_registry(&self, registry: &mut R, timestamp: Tai64) -> anyhow::Result<()> where R: TemporalRegistryAll { diff --git a/crates/fuel-core/src/combined_database.rs b/crates/fuel-core/src/combined_database.rs index 8696a8b3969..c0b6d291af1 100644 --- a/crates/fuel-core/src/combined_database.rs +++ b/crates/fuel-core/src/combined_database.rs @@ -105,6 +105,19 @@ impl CombinedDatabase { }) } + /// A test-only temporary rocksdb database with given rewind policy. + #[cfg(feature = "rocksdb")] + pub fn temp_database_with_state_rewind_policy( + state_rewind_policy: StateRewindPolicy, + ) -> DatabaseResult { + Ok(Self { + on_chain: Database::rocksdb_temp(state_rewind_policy)?, + off_chain: Database::rocksdb_temp(state_rewind_policy)?, + relayer: Default::default(), + gas_price: Default::default(), + }) + } + pub fn from_config(config: &CombinedDatabaseConfig) -> DatabaseResult { let combined_database = match config.database_type { #[cfg(feature = "rocksdb")] @@ -114,7 +127,9 @@ impl CombinedDatabase { tracing::warn!( "No RocksDB path configured, initializing database with a tmp directory" ); - CombinedDatabase::default() + CombinedDatabase::temp_database_with_state_rewind_policy( + config.state_rewind_policy, + )? } else { tracing::info!( "Opening database {:?} with cache size \"{}\" and state rewind policy \"{:?}\"", diff --git a/crates/fuel-core/src/database.rs b/crates/fuel-core/src/database.rs index 5061692ed92..50c286ea85b 100644 --- a/crates/fuel-core/src/database.rs +++ b/crates/fuel-core/src/database.rs @@ -251,12 +251,11 @@ where } #[cfg(feature = "rocksdb")] - pub fn rocksdb_temp() -> Self { - let db = RocksDb::>::default_open_temp(None).unwrap(); - let historical_db = - HistoricalRocksDB::new(db, StateRewindPolicy::NoRewind).unwrap(); + pub fn rocksdb_temp(rewind_policy: StateRewindPolicy) -> Result { + let db = RocksDb::>::default_open_temp(None)?; + let historical_db = HistoricalRocksDB::new(db, rewind_policy)?; let data = Arc::new(historical_db); - Self::from_storage(DataSource::new(data, Stage::default())) + Ok(Self::from_storage(DataSource::new(data, Stage::default()))) } } @@ -275,7 +274,8 @@ where } #[cfg(feature = "rocksdb")] { - Self::rocksdb_temp() + Self::rocksdb_temp(StateRewindPolicy::NoRewind) + .expect("Failed to create a temporary database") } } } @@ -408,7 +408,7 @@ impl Modifiable for GenesisDatabase { } } -fn commit_changes_with_height_update( +pub fn commit_changes_with_height_update( database: &mut Database, changes: Changes, heights_lookup: impl Fn( diff --git a/crates/fuel-core/src/graphql_api.rs b/crates/fuel-core/src/graphql_api.rs index 772bbc815ea..4e469a205d7 100644 --- a/crates/fuel-core/src/graphql_api.rs +++ b/crates/fuel-core/src/graphql_api.rs @@ -9,7 +9,7 @@ use std::{ }; pub mod api_service; -mod da_compression; +pub mod da_compression; pub mod database; pub(crate) mod metrics_extension; pub mod ports; diff --git a/crates/fuel-core/src/graphql_api/da_compression.rs b/crates/fuel-core/src/graphql_api/da_compression.rs index e9d11d1c22e..722f63b5080 100644 --- a/crates/fuel-core/src/graphql_api/da_compression.rs +++ b/crates/fuel-core/src/graphql_api/da_compression.rs @@ -14,14 +14,21 @@ use fuel_core_compression::{ config::Config, ports::{ EvictorDb, + HistoryLookup, TemporalRegistry, UtxoIdToPointer, }, }; use fuel_core_storage::{ not_found, + tables::{ + Coins, + FuelBlocks, + Messages, + }, StorageAsMut, StorageAsRef, + StorageInspect, }; use fuel_core_types::{ blockchain::block::Block, @@ -49,8 +56,8 @@ where { let compressed = compress( config, - CompressTx { - db_tx, + CompressDbTx { + db_tx: DbTx { db_tx }, block_events, }, block, @@ -65,14 +72,23 @@ where Ok(()) } -struct CompressTx<'a, Tx> { - db_tx: &'a mut Tx, +pub struct DbTx<'a, Tx> { + pub db_tx: &'a mut Tx, +} + +struct CompressDbTx<'a, Tx> { + db_tx: DbTx<'a, Tx>, block_events: &'a [Event], } +pub struct DecompressDbTx<'a, Tx, Onchain> { + pub db_tx: DbTx<'a, Tx>, + pub onchain_db: Onchain, +} + macro_rules! impl_temporal_registry { ($type:ty) => { paste::paste! { - impl<'a, Tx> TemporalRegistry<$type> for CompressTx<'a, Tx> + impl<'a, Tx> TemporalRegistry<$type> for DbTx<'a, Tx> where Tx: OffChainDatabaseTransaction, { @@ -150,7 +166,79 @@ macro_rules! impl_temporal_registry { } } - impl<'a, Tx> EvictorDb<$type> for CompressTx<'a, Tx> + impl<'a, Tx> TemporalRegistry<$type> for CompressDbTx<'a, Tx> + where + Tx: OffChainDatabaseTransaction, + { + fn read_registry( + &self, + key: &fuel_core_types::fuel_compression::RegistryKey, + ) -> anyhow::Result<$type> { + self.db_tx.read_registry(key) + } + + fn read_timestamp( + &self, + key: &fuel_core_types::fuel_compression::RegistryKey, + ) -> anyhow::Result { + <_ as TemporalRegistry<$type>>::read_timestamp(&self.db_tx, key) + } + + fn write_registry( + &mut self, + key: &fuel_core_types::fuel_compression::RegistryKey, + value: &$type, + timestamp: Tai64, + ) -> anyhow::Result<()> { + self.db_tx.write_registry(key, value, timestamp) + } + + fn registry_index_lookup( + &self, + value: &$type, + ) -> anyhow::Result> + { + self.db_tx.registry_index_lookup(value) + } + } + + impl<'a, Tx, Offchain> TemporalRegistry<$type> for DecompressDbTx<'a, Tx, Offchain> + where + Tx: OffChainDatabaseTransaction, + { + fn read_registry( + &self, + key: &fuel_core_types::fuel_compression::RegistryKey, + ) -> anyhow::Result<$type> { + self.db_tx.read_registry(key) + } + + fn read_timestamp( + &self, + key: &fuel_core_types::fuel_compression::RegistryKey, + ) -> anyhow::Result { + <_ as TemporalRegistry<$type>>::read_timestamp(&self.db_tx, key) + } + + fn write_registry( + &mut self, + key: &fuel_core_types::fuel_compression::RegistryKey, + value: &$type, + timestamp: Tai64, + ) -> anyhow::Result<()> { + self.db_tx.write_registry(key, value, timestamp) + } + + fn registry_index_lookup( + &self, + value: &$type, + ) -> anyhow::Result> + { + self.db_tx.registry_index_lookup(value) + } + } + + impl<'a, Tx> EvictorDb<$type> for CompressDbTx<'a, Tx> where Tx: OffChainDatabaseTransaction, { @@ -158,7 +246,7 @@ macro_rules! impl_temporal_registry { &mut self, key: fuel_core_types::fuel_compression::RegistryKey, ) -> anyhow::Result<()> { - self.db_tx + self.db_tx.db_tx .storage_as_mut::() .insert(&MetadataKey::$type, &key)?; Ok(()) @@ -168,7 +256,7 @@ macro_rules! impl_temporal_registry { &self, ) -> anyhow::Result> { Ok(self - .db_tx + .db_tx.db_tx .storage_as_ref::() .get(&MetadataKey::$type)? .map(|v| v.into_owned()) @@ -185,7 +273,7 @@ impl_temporal_registry!(ContractId); impl_temporal_registry!(ScriptCode); impl_temporal_registry!(PredicateCode); -impl<'a, Tx> UtxoIdToPointer for CompressTx<'a, Tx> +impl<'a, Tx> UtxoIdToPointer for CompressDbTx<'a, Tx> where Tx: OffChainDatabaseTransaction, { @@ -210,3 +298,78 @@ where anyhow::bail!("UtxoId not found in the block events"); } } + +impl<'a, Tx, Onchain> HistoryLookup for DecompressDbTx<'a, Tx, Onchain> +where + Tx: OffChainDatabaseTransaction, + Onchain: StorageInspect + + StorageInspect + + StorageInspect, +{ + fn utxo_id( + &self, + c: fuel_core_types::fuel_tx::CompressedUtxoId, + ) -> anyhow::Result { + if c.tx_pointer.block_height() == 0u32.into() { + // This is a genesis coin, which is handled differently. + // See CoinConfigGenerator::generate which generates the genesis coins. + let mut bytes = [0u8; 32]; + let tx_index = c.tx_pointer.tx_index(); + bytes[..std::mem::size_of_val(&tx_index)] + .copy_from_slice(&tx_index.to_be_bytes()); + return Ok(fuel_core_types::fuel_tx::UtxoId::new( + fuel_core_types::fuel_tx::TxId::from(bytes), + 0, + )); + } + + let block_info = self + .onchain_db + .storage_as_ref::() + .get(&c.tx_pointer.block_height())? + .ok_or(not_found!(FuelBlocks))?; + + let tx_id = *block_info + .transactions() + .get(c.tx_pointer.tx_index() as usize) + .ok_or(anyhow::anyhow!( + "Transaction not found in the block: {:?}", + c.tx_pointer + ))?; + + Ok(fuel_core_types::fuel_tx::UtxoId::new(tx_id, c.output_index)) + } + + fn coin( + &self, + utxo_id: fuel_core_types::fuel_tx::UtxoId, + ) -> anyhow::Result { + let coin = self + .onchain_db + .storage_as_ref::() + .get(&utxo_id)? + .ok_or(not_found!(fuel_core_storage::tables::Coins))?; + Ok(fuel_core_compression::ports::CoinInfo { + owner: *coin.owner(), + asset_id: *coin.asset_id(), + amount: *coin.amount(), + }) + } + + fn message( + &self, + nonce: fuel_core_types::fuel_types::Nonce, + ) -> anyhow::Result { + let message = self + .onchain_db + .storage_as_ref::() + .get(&nonce)? + .ok_or(not_found!(fuel_core_storage::tables::Messages))?; + Ok(fuel_core_compression::ports::MessageInfo { + sender: *message.sender(), + recipient: *message.recipient(), + amount: message.amount(), + data: message.data().clone(), + }) + } +} diff --git a/crates/fuel-core/src/state/generic_database.rs b/crates/fuel-core/src/state/generic_database.rs index 8306df1b1fb..b6f5f2ea464 100644 --- a/crates/fuel-core/src/state/generic_database.rs +++ b/crates/fuel-core/src/state/generic_database.rs @@ -44,7 +44,7 @@ impl GenericDatabase { } pub fn into_inner(self) -> Storage { - self.storage.into_inner() + self.storage.into_storage() } } diff --git a/crates/storage/src/structured_storage.rs b/crates/storage/src/structured_storage.rs index e78e9637484..9a76595bdf8 100644 --- a/crates/storage/src/structured_storage.rs +++ b/crates/storage/src/structured_storage.rs @@ -105,7 +105,7 @@ impl StructuredStorage { } /// Returns the inner storage. - pub fn into_inner(self) -> S { + pub fn into_storage(self) -> S { self.inner } } diff --git a/crates/storage/src/transactional.rs b/crates/storage/src/transactional.rs index 14ec74159ed..34fd040f512 100644 --- a/crates/storage/src/transactional.rs +++ b/crates/storage/src/transactional.rs @@ -112,6 +112,13 @@ impl StorageTransaction { self.inner.changes } + /// Returns the storage and changes to it. + pub fn into_inner(self) -> (S, Changes) { + let storage = self.inner.storage; + let changes = self.inner.changes; + (storage, changes) + } + /// Resets the changes to the storage. pub fn reset_changes(&mut self) { self.inner.changes = Default::default(); @@ -259,10 +266,7 @@ pub trait WriteTransaction { fn write_transaction(&mut self) -> StorageTransaction<&mut Self>; } -impl WriteTransaction for S -where - S: Modifiable, -{ +impl WriteTransaction for S { fn write_transaction(&mut self) -> StorageTransaction<&mut Self> { StorageTransaction::transaction( self, diff --git a/tests/tests/da_compression.rs b/tests/tests/da_compression.rs index 43fce2a27e6..b4f82b39a53 100644 --- a/tests/tests/da_compression.rs +++ b/tests/tests/da_compression.rs @@ -1,7 +1,13 @@ use core::time::Duration; use fuel_core::{ - combined_database::CombinedDatabase, - fuel_core_graphql_api::worker_service::DaCompressionConfig, + chain_config::TESTNET_WALLET_SECRETS, + fuel_core_graphql_api::{ + da_compression::{ + DbTx, + DecompressDbTx, + }, + worker_service::DaCompressionConfig, + }, p2p_test_helpers::*, service::{ Config, @@ -9,11 +15,19 @@ use fuel_core::{ }, }; use fuel_core_client::client::{ + pagination::PaginationRequest, types::TransactionStatus, FuelClient, }; -use fuel_core_compression::VersionedCompressedBlock; +use fuel_core_compression::{ + decompress::decompress, + VersionedCompressedBlock, +}; use fuel_core_poa::signer::SignMode; +use fuel_core_storage::transactional::{ + HistoricalView, + IntoTransaction, +}; use fuel_core_types::{ fuel_asm::{ op, @@ -21,9 +35,11 @@ use fuel_core_types::{ }, fuel_crypto::SecretKey, fuel_tx::{ + Address, GasCosts, Input, TransactionBuilder, + TxPointer, }, secrecy::Secret, }; @@ -31,30 +47,56 @@ use rand::{ rngs::StdRng, SeedableRng, }; +use std::str::FromStr; #[tokio::test] async fn can_fetch_da_compressed_block_from_graphql() { let mut rng = StdRng::seed_from_u64(10); let poa_secret = SecretKey::random(&mut rng); - let db = CombinedDatabase::default(); let mut config = Config::local_node(); config.consensus_signer = SignMode::Key(Secret::new(poa_secret.into())); + config.utxo_validation = true; let compression_config = fuel_core_compression::Config { temporal_registry_retention: Duration::from_secs(3600), }; config.da_compression = DaCompressionConfig::Enabled(compression_config); - let srv = FuelService::from_combined_database(db.clone(), config) - .await - .unwrap(); + let srv = FuelService::new_node(config).await.unwrap(); let client = FuelClient::from(srv.bound_address); + let wallet_secret = + SecretKey::from_str(TESTNET_WALLET_SECRETS[1]).expect("Expected valid secret"); + let wallet_address = Address::from(*wallet_secret.public_key().hash()); + + let coin = client + .coins( + &wallet_address, + None, + PaginationRequest { + cursor: None, + results: 1, + direction: fuel_core_client::client::pagination::PageDirection::Forward, + }, + ) + .await + .expect("Unable to get coins") + .results + .into_iter() + .next() + .expect("Expected at least one coin"); + let tx = TransactionBuilder::script([op::ret(RegId::ONE)].into_iter().collect(), vec![]) .max_fee_limit(0) .script_gas_limit(1_000_000) .with_gas_costs(GasCosts::free()) - .add_fee_input() + .add_unsigned_coin_input( + wallet_secret, + coin.utxo_id, + coin.amount, + coin.asset_id, + TxPointer::new(coin.block_created.into(), coin.tx_created_idx), + ) .finalize_as_transaction(); let status = client.submit_and_await_commit(&tx).await.unwrap(); @@ -66,9 +108,25 @@ async fn can_fetch_da_compressed_block_from_graphql() { } }; - let block = client.da_compressed_block(block_height).await.unwrap(); - let block = block.expect("Unable to get compressed block"); - let _: VersionedCompressedBlock = postcard::from_bytes(&block).unwrap(); + let block = client + .da_compressed_block(block_height) + .await + .unwrap() + .expect("Unable to get compressed block"); + let block: VersionedCompressedBlock = postcard::from_bytes(&block).unwrap(); + + // Reuse the existing offchain db to decompress the block + let db = &srv.shared.database; + let mut tx_inner = db.off_chain().clone().into_transaction(); + let db_tx = DecompressDbTx { + db_tx: DbTx { + db_tx: &mut tx_inner, + }, + onchain_db: db.on_chain().view_at(&0u32.into()).unwrap(), + }; + let decompressed = decompress(compression_config, db_tx, block).await.unwrap(); + + assert!(decompressed.transactions.len() == 2); } #[tokio::test(flavor = "multi_thread")] From 90b72a09f5b4d3f24a0a1c6b0fed59ef511e6cc9 Mon Sep 17 00:00:00 2001 From: Andrea Cerone <22031682+acerone85@users.noreply.github.com> Date: Wed, 27 Nov 2024 15:35:51 +0100 Subject: [PATCH 5/5] Versioned Storage for Modifications History (#2233) ## Linked Issues/PRs Related to https://github.com/FuelLabs/fuel-core/issues/2095 ## Description - [ ] Adds a ModificationsHistoryV2 column in the Historical RocksDB, with keys encoded in big endian - [ ] Adds a flag to the historical RocksDB that keeps track whether the migration is still in progress - [ ] Change HistoricalRocksDB to alway insert historical changes from V2 table. When the migration is in progress, delete key-value pairs from both V2 and V2, read key-value pairs from V2 falling back to V1 if no value in V2 is found #TODO (either this or next MR): - [x] Small task that performs the migration of key-value pairs from V1 to V2 (Done in #2260) ## Checklist - [ ] Breaking changes are clearly marked as such in the PR description and changelog - [x] New behavior is reflected in tests - [ ] [The specification](https://github.com/FuelLabs/fuel-specs/) matches the implemented behavior (link update PR if changes are needed) ### Before requesting review - [ ] I have reviewed the code myself - [ ] I have created follow-up issues caused by this PR and linked them here ### After merging, notify other teams [Add or remove entries as needed] - [ ] [Rust SDK](https://github.com/FuelLabs/fuels-rs/) - [ ] [Sway compiler](https://github.com/FuelLabs/sway/) - [ ] [Platform documentation](https://github.com/FuelLabs/devrel-requests/issues/new?assignees=&labels=new+request&projects=&template=NEW-REQUEST.yml&title=%5BRequest%5D%3A+) (for out-of-organization contributors, the person merging the PR will do this) - [ ] Someone else? --------- Co-authored-by: Green Baneling --- CHANGELOG.md | 2 +- .../fuel-core/src/state/historical_rocksdb.rs | 360 ++++++++++++++++-- .../state/historical_rocksdb/description.rs | 24 +- .../modifications_history.rs | 43 ++- 4 files changed, 374 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af894952c11..3870ca84e02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [2378](https://github.com/FuelLabs/fuel-core/pull/2378): Use cached hash of the topic instead of calculating it on each publishing gossip message. - [2429](https://github.com/FuelLabs/fuel-core/pull/2429): Introduce custom enum for representing result of running service tasks - [2377](https://github.com/FuelLabs/fuel-core/pull/2377): Add more errors that can be returned as responses when using protocol `/fuel/req_res/0.0.2`. The errors supported are `ProtocolV1EmptyResponse` (status code `0`) for converting empty responses sent via protocol `/fuel/req_res/0.0.1`, `RequestedRangeTooLarge`(status code `1`) if the client requests a range of objects such as sealed block headers or transactions too large, `Timeout` (status code `2`) if the remote peer takes too long to fulfill a request, or `SyncProcessorOutOfCapacity` if the remote peer is fulfilling too many requests concurrently. +- [2233](https://github.com/FuelLabs/fuel-core/pull/2233): Introduce a new column `modification_history_v2` for storing the modification history in the historical rocksDB. Keys in this column are stored in big endian order. Changed the behaviour of the historical rocksDB to write changes for new block heights to the new column, and to perform lookup of values from the `modification_history_v2` table first, and then from the `modification_history` table, performing a migration upon access if necessary. #### Breaking - [2389](https://github.com/FuelLabs/fuel-core/pull/2258): Updated the `messageProof` GraphQL schema to return a non-nullable `MessageProof`. @@ -90,7 +91,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). #### Breaking - [2311](https://github.com/FuelLabs/fuel-core/pull/2311): Changed the text of the error returned by the executor if gas overflows. - ## [Version 0.38.0] ### Added diff --git a/crates/fuel-core/src/state/historical_rocksdb.rs b/crates/fuel-core/src/state/historical_rocksdb.rs index 52887fdaf2e..48335ed9a39 100644 --- a/crates/fuel-core/src/state/historical_rocksdb.rs +++ b/crates/fuel-core/src/state/historical_rocksdb.rs @@ -14,7 +14,6 @@ use crate::{ Column, Historical, }, - modifications_history::ModificationsHistory, view_at_height::ViewAtHeight, }, iterable_key_value_view::IterableKeyValueViewWrapper, @@ -49,8 +48,13 @@ use fuel_core_storage::{ Error as StorageError, Result as StorageResult, StorageAsMut, + StorageMut, }; use itertools::Itertools; +use modifications_history::{ + ModificationsHistoryV1, + ModificationsHistoryV2, +}; use serde::{ Deserialize, Serialize, @@ -77,9 +81,12 @@ pub enum StateRewindPolicy { RewindRange { size: NonZeroU64 }, } +/// Implementation of a database #[derive(Debug)] pub struct HistoricalRocksDB { + /// The [`StateRewindPolicy`] used by the historical rocksdb state_rewind_policy: StateRewindPolicy, + /// The Description of the database. db: RocksDb>, } @@ -167,7 +174,6 @@ where // we need to apply all modifications up to `X + 1`. let rollback_height = height.as_u64().saturating_add(1); - // TODO: May fail incorrectly because of https://github.com/FuelLabs/fuel-core/issues/2095 let Some(oldest_height) = self.oldest_changes_height()? else { return Err(DatabaseError::NoHistoryIsAvailable.into()); }; @@ -183,11 +189,16 @@ where Ok(ViewAtHeight::new(rollback_height, latest_view)) } - fn store_modifications_history( + fn store_modifications_history( &self, - storage_transaction: &mut StorageTransaction<&RocksDb>>, + storage_transaction: &mut StorageTransaction, height: &Description::Height, - ) -> StorageResult<()> { + ) -> StorageResult<()> + where + T: KeyValueInspect>, + { + let modifications_history_migration_in_progress = self.is_migration_in_progress(); + if self.state_rewind_policy == StateRewindPolicy::NoRewind { return Ok(()); } @@ -196,11 +207,22 @@ where let reverse_changes = self.reverse_history_changes(storage_transaction.changes())?; - cleanup_old_changes(&height_u64, storage_transaction, &self.state_rewind_policy)?; + cleanup_old_changes( + &height_u64, + storage_transaction, + &self.state_rewind_policy, + modifications_history_migration_in_progress, + )?; - let old_changes = storage_transaction - .storage_as_mut::>() - .replace(&height_u64, &reverse_changes)?; + // We write directly to `ModificationsHistoryV2`. + // If the migration is in progress, we fallback to taking from + // `ModificationsHistoryV1` when no old_changes for `ModificationsHistoryV2` are found. + let old_changes = multiversion_replace( + storage_transaction, + height_u64, + &reverse_changes, + modifications_history_migration_in_progress, + )?; if let Some(old_changes) = old_changes { tracing::warn!( @@ -248,28 +270,60 @@ where Ok(()) } - fn oldest_changes_height(&self) -> StorageResult> { - let oldest_height = self + fn multiversion_changes_heights( + &self, + direction: IterDirection, + check_v1: bool, + ) -> (Option>, Option>) { + let v2_changes = self .db - .iter_all_keys::>(Some( - IterDirection::Forward, - )) - .next() - .transpose()?; + .iter_all_keys::>(Some(direction)) + .next(); + let v1_changes = check_v1 + .then(|| { + self.db + .iter_all_keys::>(Some(direction)) + .next() + }) + .flatten(); + + (v2_changes, v1_changes) + } + + fn oldest_changes_height(&self) -> StorageResult> { + let modifications_history_migration_in_progress = self.is_migration_in_progress(); + + let (v2_oldest_height, v1_oldest_height) = self.multiversion_changes_heights( + IterDirection::Forward, + modifications_history_migration_in_progress, + ); + + let v2_oldest_height = v2_oldest_height.transpose()?; + let v1_oldest_height = v1_oldest_height.transpose()?; + + let oldest_height = match (v1_oldest_height, v2_oldest_height) { + (None, v2) => v2, + (v1, None) => v1, + (Some(v1), Some(v2)) => Some(v1.min(v2)), + }; Ok(oldest_height) } #[cfg(test)] - // TODO: This method doesn't work properly because of - // https://github.com/FuelLabs/fuel-core/issues/2095 fn rollback_last_block(&self) -> StorageResult { - let latest_height = self - .db - .iter_all_keys::>(Some( - IterDirection::Reverse, - )) - .next() - .ok_or(DatabaseError::ReachedEndOfHistory)??; + let modifications_history_migration_in_progress = self.is_migration_in_progress(); + + let (v2_latest_height, v1_latest_height) = self.multiversion_changes_heights( + IterDirection::Reverse, + modifications_history_migration_in_progress, + ); + + let latest_height = match (v2_latest_height, v1_latest_height) { + (None, None) => Err(DatabaseError::ReachedEndOfHistory)?, + (Some(Ok(v1)), Some(Ok(v2))) => v1.max(v2), + (_, Some(v1_res)) => v1_res?, + (Some(v2_res), _) => v2_res?, + }; self.rollback_block_to(latest_height)?; @@ -279,10 +333,12 @@ where fn rollback_block_to(&self, height_to_rollback: u64) -> StorageResult<()> { let mut storage_transaction = self.db.read_transaction(); - let last_changes = storage_transaction - .storage_as_mut::>() - .take(&height_to_rollback)? - .ok_or(not_found!(ModificationsHistory))?; + let last_changes = multiversion_take( + &mut storage_transaction, + height_to_rollback, + self.is_migration_in_progress(), + )? + .ok_or(not_found!(ModificationsHistoryV1))?; remove_historical_modifications( &height_to_rollback, @@ -302,15 +358,92 @@ where Ok(()) } + + fn v1_entries(&self) -> BoxedIter> { + self.db + .iter_all::>(None) + } + + fn is_migration_in_progress(&self) -> bool { + self.v1_entries().next().is_some() + } +} + +// Try to take the value from `ModificationsHistoryV2` first. +// If the migration is still in progress, remove the value from +// `ModificationsHistoryV1` and return it if no value for `ModificationsHistoryV2` +// was found. This is necessary to avoid scenarios where it is possible to +// roll back twice to the same block height +fn multiversion_op( + storage_transaction: &mut StorageTransaction, + height: u64, + modifications_history_migration_in_progress: bool, + f: F, +) -> StorageResult> +where + Description: DatabaseDescription, + T: KeyValueInspect>, + F: FnOnce( + StorageMut<'_, StorageTransaction, ModificationsHistoryV2>, + ) -> StorageResult>, +{ + let v2_last_changes = + f(storage_transaction.storage_as_mut::>())?; + + if modifications_history_migration_in_progress { + let v1_last_changes = storage_transaction + .storage_as_mut::>() + .take(&height)?; + Ok(v2_last_changes.or(v1_last_changes)) + } else { + Ok(v2_last_changes) + } +} + +fn multiversion_take( + storage_transaction: &mut StorageTransaction, + height: u64, + modifications_history_migration_in_progress: bool, +) -> StorageResult> +where + Description: DatabaseDescription, + T: KeyValueInspect>, +{ + multiversion_op( + storage_transaction, + height, + modifications_history_migration_in_progress, + |storage| storage.take(&height), + ) } -fn cleanup_old_changes( +fn multiversion_replace( + storage_transaction: &mut StorageTransaction, + height: u64, + changes: &Changes, + modifications_history_migration_in_progress: bool, +) -> StorageResult> +where + Description: DatabaseDescription, + T: KeyValueInspect>, +{ + multiversion_op( + storage_transaction, + height, + modifications_history_migration_in_progress, + |storage| storage.replace(&height, changes), + ) +} + +fn cleanup_old_changes( height: &u64, - storage_transaction: &mut StorageTransaction<&RocksDb>>, + storage_transaction: &mut StorageTransaction, state_rewind_policy: &StateRewindPolicy, + modifications_history_migration_in_progress: bool, ) -> StorageResult<()> where Description: DatabaseDescription, + T: KeyValueInspect>, { match state_rewind_policy { StateRewindPolicy::NoRewind => { @@ -322,9 +455,11 @@ where StateRewindPolicy::RewindRange { size } => { let old_height = height.saturating_sub(size.get()); - let old_changes = storage_transaction - .storage_as_mut::>() - .take(&old_height)?; + let old_changes = multiversion_take( + storage_transaction, + old_height, + modifications_history_migration_in_progress, + )?; if let Some(old_changes) = old_changes { remove_historical_modifications( @@ -338,13 +473,14 @@ where Ok(()) } -fn remove_historical_modifications( +fn remove_historical_modifications( old_height: &u64, - storage_transaction: &mut StorageTransaction<&RocksDb>>, + storage_transaction: &mut StorageTransaction, reverse_changes: &Changes, ) -> StorageResult<()> where Description: DatabaseDescription, + T: KeyValueInspect>, { let changes = reverse_changes .iter() @@ -443,12 +579,14 @@ where ) -> StorageResult<()> { let mut storage_transaction = StorageTransaction::transaction(&self.db, ConflictPolicy::Overwrite, changes); + if let Some(height) = height { self.store_modifications_history(&mut storage_transaction, &height)?; } self.db .commit_changes(&storage_transaction.into_changes())?; + Ok(()) } @@ -726,7 +864,7 @@ mod tests { .unwrap(); let entries = historical_rocks_db .db - .iter_all::>(None) + .iter_all::>(None) .collect::>(); assert_eq!(entries.len(), 1); @@ -737,11 +875,153 @@ mod tests { assert_eq!(result, Ok(1)); let entries = historical_rocks_db .db - .iter_all::>(None) + .iter_all::>(None) .collect::>(); assert_eq!(entries.len(), 0); } + #[test] + fn state_rewind_policy__rewind_range_1__rollback_uses_v2() { + // Given + let rocks_db = RocksDb::>::default_open_temp(None).unwrap(); + let historical_rocks_db = HistoricalRocksDB::new( + rocks_db, + StateRewindPolicy::RewindRange { + size: NonZeroU64::new(1).unwrap(), + }, + ) + .unwrap(); + + // When + let mut transaction = historical_rocks_db.read_transaction(); + transaction + .storage_as_mut::() + .insert(&key(), &123) + .unwrap(); + historical_rocks_db + .commit_changes(Some(1u32.into()), transaction.into_changes()) + .unwrap(); + let v2_entries = historical_rocks_db + .db + .iter_all::>(None) + .collect::>(); + let v1_entries = historical_rocks_db + .db + .iter_all::>(None) + .collect::>(); + + // Then + assert_eq!(v2_entries.len(), 1); + assert_eq!(v1_entries.len(), 0); + } + + #[test] + fn state_rewind_policy__rewind_range_1__rollback_during_migration_works() { + // Given + let rocks_db = RocksDb::>::default_open_temp(None).unwrap(); + let historical_rocks_db = HistoricalRocksDB::new( + rocks_db, + StateRewindPolicy::RewindRange { + size: NonZeroU64::new(1).unwrap(), + }, + ) + .unwrap(); + + // When + let mut transaction = historical_rocks_db.read_transaction(); + transaction + .storage_as_mut::() + .insert(&key(), &123) + .unwrap(); + historical_rocks_db + .commit_changes(Some(1u32.into()), transaction.into_changes()) + .unwrap(); + + // Migrate the changes from V2 to V1. + + let mut migration_transaction = StorageTransaction::transaction( + &historical_rocks_db.db, + ConflictPolicy::Overwrite, + Changes::default(), + ); + + let v2_changes = migration_transaction + .storage_as_mut::>() + .take(&1u64) + .unwrap() + .unwrap(); + migration_transaction + .storage_as_mut::>() + .insert(&1u64, &v2_changes) + .unwrap(); + + historical_rocks_db + .db + .commit_changes(&migration_transaction.into_changes()) + .unwrap(); + + // Check that the history has indeed been written to V1 + let v2_entries = historical_rocks_db + .db + .iter_all::>(None) + .collect::>(); + let v1_entries = historical_rocks_db + .db + .iter_all::>(None) + .collect::>(); + + assert_eq!(v2_entries.len(), 0); + assert_eq!(v1_entries.len(), 1); + + let result = historical_rocks_db.rollback_last_block(); + + // Then + assert_eq!(result, Ok(1)); + let v2_entries = historical_rocks_db + .db + .iter_all::>(None) + .collect::>(); + let v1_entries = historical_rocks_db + .db + .iter_all::>(None) + .collect::>(); + assert_eq!(v2_entries.len(), 0); + assert_eq!(v1_entries.len(), 0); + } + + #[test] + fn rollback_last_block_works_with_v2() { + // Given + let rocks_db = RocksDb::>::default_open_temp(None).unwrap(); + + let historical_rocks_db = + HistoricalRocksDB::new(rocks_db, StateRewindPolicy::RewindFullRange).unwrap(); + + // When + // Commit 1000 blocks + for i in 1..=1000u32 { + let mut transaction = historical_rocks_db.read_transaction(); + transaction + .storage_as_mut::() + .insert(&key(), &(123 + i as u64)) + .unwrap(); + historical_rocks_db + .commit_changes(Some(i.into()), transaction.into_changes()) + .unwrap(); + } + // We can now rollback the last block 1000 times. + let results: Vec> = (0..1000u32) + .map(|_| historical_rocks_db.rollback_last_block()) + .collect(); + + // Then + // If the rollback fails at some point, then we have unintentionally rollbacked to + // a block that was not the last. + for (i, result) in results.iter().enumerate() { + assert_eq!(result, &Ok(1000 - i as u64)); + } + } + #[test] fn state_rewind_policy__rewind_range_1__second_rollback_fails() { // Given @@ -806,7 +1086,7 @@ mod tests { // Given let entries = historical_rocks_db .db - .iter_all::>(None) + .iter_all::>(None) .collect::>(); assert_eq!(entries.len(), height); @@ -817,7 +1097,7 @@ mod tests { assert_eq!(result, Ok(height as u64)); let entries = historical_rocks_db .db - .iter_all::>(None) + .iter_all::>(None) .collect::>(); assert_eq!(entries.len(), height - 1); } diff --git a/crates/fuel-core/src/state/historical_rocksdb/description.rs b/crates/fuel-core/src/state/historical_rocksdb/description.rs index 03283967f06..ab46a400936 100644 --- a/crates/fuel-core/src/state/historical_rocksdb/description.rs +++ b/crates/fuel-core/src/state/historical_rocksdb/description.rs @@ -2,6 +2,9 @@ use crate::database::database_description::DatabaseDescription; use fuel_core_storage::kv_store::StorageColumn; pub const HISTORY_COLUMN_ID: u32 = u32::MAX / 2; +// Avoid conflicts with HistoricalDuplicateColumn indexes, which are +// in decreasing order starting from HISTORY_COLUMN_ID - 1. +pub const HISTORY_V2_COLUMN_ID: u32 = HISTORY_COLUMN_ID + 1; #[derive(Debug, Copy, Clone, enum_iterator::Sequence)] pub enum Column @@ -10,7 +13,10 @@ where { OriginalColumn(Description::Column), HistoricalDuplicateColumn(Description::Column), + /// Original history column HistoryColumn, + /// Migrated history column + HistoryV2Column, } impl strum::EnumCount for Column @@ -19,7 +25,7 @@ where { const COUNT: usize = Description::Column::COUNT /* original columns */ + Description::Column::COUNT /* duplicated columns */ - + 1 /* history column */; + + 2 /* history column, history V2 column */; } impl StorageColumn for Column @@ -33,6 +39,7 @@ where format!("history_{}", c.name()) } Column::HistoryColumn => "modifications_history".to_string(), + Column::HistoryV2Column => "modifications_history_v2".to_string(), } } @@ -43,6 +50,7 @@ where historical_duplicate_column_id(c.id()) } Column::HistoryColumn => HISTORY_COLUMN_ID, + Column::HistoryV2Column => HISTORY_V2_COLUMN_ID, } } } @@ -81,7 +89,7 @@ where Column::HistoricalDuplicateColumn(c) => { Some(Description::prefix(c).unwrap_or(0).saturating_add(8)) // `u64::to_be_bytes` } - Column::HistoryColumn => Some(8), + Column::HistoryColumn | Column::HistoryV2Column => Some(8), } } } @@ -102,8 +110,8 @@ mod tests { let variants = enum_iterator::all::>().collect::>(); let original = ::Column::COUNT; let duplicated = ::Column::COUNT; - let history_modification = 1; - let expected_count = original + duplicated + history_modification; + let history_modification_versions = 2; + let expected_count = original + duplicated + history_modification_versions; assert_eq!(variants.len(), expected_count); assert_eq!( as EnumCount>::COUNT, expected_count); } @@ -113,8 +121,8 @@ mod tests { let variants = enum_iterator::all::>().collect::>(); let original = ::Column::COUNT; let duplicated = ::Column::COUNT; - let history_modification = 1; - let expected_count = original + duplicated + history_modification; + let history_modification_versions = 2; + let expected_count = original + duplicated + history_modification_versions; assert_eq!(variants.len(), expected_count); assert_eq!( as EnumCount>::COUNT, expected_count); } @@ -124,8 +132,8 @@ mod tests { let variants = enum_iterator::all::>().collect::>(); let original = ::Column::COUNT; let duplicated = ::Column::COUNT; - let history_modification = 1; - let expected_count = original + duplicated + history_modification; + let history_modification_versions = 2; + let expected_count = original + duplicated + history_modification_versions; assert_eq!(variants.len(), expected_count); assert_eq!( as EnumCount>::COUNT, expected_count); } diff --git a/crates/fuel-core/src/state/historical_rocksdb/modifications_history.rs b/crates/fuel-core/src/state/historical_rocksdb/modifications_history.rs index f5cfecb4b30..fada2e13ed5 100644 --- a/crates/fuel-core/src/state/historical_rocksdb/modifications_history.rs +++ b/crates/fuel-core/src/state/historical_rocksdb/modifications_history.rs @@ -3,18 +3,30 @@ use crate::{ state::historical_rocksdb::description::Column, }; use fuel_core_storage::{ + self, blueprint::plain::Plain, - codec::postcard::Postcard, + codec::{ + postcard::Postcard, + primitive::Primitive, + }, structured_storage::TableWithBlueprint, transactional::Changes, Mappable, }; -pub struct ModificationsHistory(core::marker::PhantomData) +/// Versioned modification history. The `const VERSION: usize` generic parameter +/// is used to specify the version. +/// This allows to define different [`TableWithBlueprint`] +/// implementations for V1 and V2 of the modification history. +pub struct ModificationsHistoryVersion( + core::marker::PhantomData, +) where Description: DatabaseDescription; -impl Mappable for ModificationsHistory +/// [`ModificationsHistoryVersion`] keys and values for all versions. +impl Mappable + for ModificationsHistoryVersion where Description: DatabaseDescription, { @@ -26,12 +38,17 @@ where type OwnedValue = Self::Value; } -impl TableWithBlueprint for ModificationsHistory +pub type ModificationsHistoryV1 = + ModificationsHistoryVersion; +pub type ModificationsHistoryV2 = + ModificationsHistoryVersion; + +/// Blueprint for Modifications History V1. Keys are stored in little endian order +/// using the `Column::HistoryColumn` column family. +impl TableWithBlueprint for ModificationsHistoryV1 where Description: DatabaseDescription, { - // TODO: The Blueprint should be `Plain, Postcard>` to sort - // the keys in the database. https://github.com/FuelLabs/fuel-core/issues/2095 type Blueprint = Plain; type Column = Column; @@ -39,3 +56,17 @@ where Column::HistoryColumn } } + +/// Blueprint for Modifications History V2. Keys are stored in big endian order +/// using the `Column::HistoryColumnV2` column family. +impl TableWithBlueprint for ModificationsHistoryV2 +where + Description: DatabaseDescription, +{ + type Blueprint = Plain, Postcard>; + type Column = Column; + + fn column() -> Self::Column { + Column::HistoryV2Column + } +}