diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 543bae1dc..3cfb6c9d0 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -915,9 +915,22 @@ jobs: permissions: contents: read actions: write - name: Startup E2E in dev mode + # One leg per genesis ledger version, in parallel. Each leg is its own + # required status check ("Startup E2E in dev mode (ledger-N)"); the + # main-protection ruleset must require both. + name: Startup E2E in dev mode (${{ matrix.ledger }}) needs: run runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - ledger: ledger-9 + genesis: ledger9 + - ledger: ledger-8 + genesis: ledger8 + env: + STARTUP_GENESIS: ${{ matrix.genesis }} steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0 @@ -925,6 +938,8 @@ jobs: submodules: true - id: guard uses: ./.github/actions/tree-cache-guard + with: + matrix-key: ${{ matrix.ledger }} - uses: ./.github/actions/reusable-e2e-tests if: steps.guard.outputs.hit != 'true' with: diff --git a/Cargo.lock b/Cargo.lock index d2451ef4f..732fa8b86 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3382,6 +3382,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "dispatch2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags 2.11.0", + "objc2", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -7569,6 +7579,38 @@ dependencies = [ "zeroize", ] +[[package]] +name = "midnight-base-crypto" +version = "1.0.0" +source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1#4a5e2c862d03c2c4689dcbd32812edfaab30d20c" +dependencies = [ + "anyhow", + "atomic-write-file", + "const-hex", + "ethnum", + "fake", + "ff", + "flate2", + "futures", + "group", + "indicatif 0.18.4", + "k256", + "lazy_static", + "midnight-base-crypto-derive 1.0.0", + "midnight-serialize 1.1.0", + "pastey", + "rand 0.8.5", + "reqwest 0.13.3", + "serde", + "serde_bytes", + "serde_json", + "sha2 0.11.0", + "signature", + "subtle 2.6.1", + "tracing", + "zeroize", +] + [[package]] name = "midnight-base-crypto" version = "1.1.0" @@ -7586,8 +7628,8 @@ dependencies = [ "indicatif 0.18.4", "k256", "lazy_static", - "midnight-base-crypto-derive", - "midnight-serialize", + "midnight-base-crypto-derive 1.1.0", + "midnight-serialize 1.2.0", "pastey", "rand 0.8.5", "reqwest 0.13.3", @@ -7601,6 +7643,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "midnight-base-crypto-derive" +version = "1.0.0" +source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1#4a5e2c862d03c2c4689dcbd32812edfaab30d20c" +dependencies = [ + "proc-macro2", + "quote 1.0.45", + "syn 2.0.117", +] + [[package]] name = "midnight-base-crypto-derive" version = "1.1.0" @@ -7690,15 +7742,31 @@ checksum = "295ff7814b0288a9f0cbfea0cf13e5bfaa9a631f0525fd43175d572ca9af03ce" dependencies = [ "fake", "lazy_static", - "midnight-base-crypto", - "midnight-serialize", - "midnight-storage-core", + "midnight-base-crypto 1.1.0", + "midnight-serialize 1.2.0", + "midnight-storage-core 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "midnight-transient-crypto 2.2.0", "rand 0.8.5", "serde", "zeroize", ] +[[package]] +name = "midnight-coin-structure" +version = "2.0.1" +source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1#4a5e2c862d03c2c4689dcbd32812edfaab30d20c" +dependencies = [ + "fake", + "lazy_static", + "midnight-base-crypto 1.0.0", + "midnight-serialize 1.1.0", + "midnight-storage-core 1.2.0 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", + "midnight-transient-crypto 2.1.0", + "rand 0.8.5", + "serde", + "zeroize", +] + [[package]] name = "midnight-coin-structure" version = "3.0.0" @@ -7706,9 +7774,9 @@ source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=coin-structur dependencies = [ "fake", "lazy_static", - "midnight-base-crypto", - "midnight-serialize", - "midnight-storage-core", + "midnight-base-crypto 1.1.0", + "midnight-serialize 1.2.0", + "midnight-storage-core 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "midnight-transient-crypto 3.0.0", "rand 0.8.5", "serde", @@ -7787,11 +7855,11 @@ dependencies = [ "is_sorted", "itertools 0.14.0", "lazy_static", - "midnight-base-crypto", - "midnight-coin-structure 2.0.1", - "midnight-ledger-static", + "midnight-base-crypto 1.1.0", + "midnight-coin-structure 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "midnight-ledger-static 9.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "midnight-onchain-runtime 2.0.1", - "midnight-serialize", + "midnight-serialize 1.2.0", "midnight-storage 1.1.1", "midnight-transient-crypto 2.2.0", "midnight-zswap 7.0.3", @@ -7807,12 +7875,12 @@ dependencies = [ [[package]] name = "midnight-ledger" -version = "8.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2182054f3a43ccabac514448fff2487437be293f517a01afc23905df701e8548" +version = "8.2.0-rc.1" +source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1#4a5e2c862d03c2c4689dcbd32812edfaab30d20c" dependencies = [ "anyhow", "derive-where", + "digest-io", "fake", "futures", "introspection", @@ -7820,18 +7888,18 @@ dependencies = [ "is_sorted", "itertools 0.14.0", "lazy_static", - "midnight-base-crypto", - "midnight-coin-structure 2.0.1", - "midnight-ledger-static", + "midnight-base-crypto 1.0.0", + "midnight-coin-structure 2.0.1 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", + "midnight-ledger-static 9.0.0 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", "midnight-onchain-runtime 3.1.0", - "midnight-serialize", - "midnight-storage 2.0.1", - "midnight-transient-crypto 2.2.0", - "midnight-zswap 8.1.0", + "midnight-serialize 1.1.0", + "midnight-storage 2.0.1 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", + "midnight-transient-crypto 2.1.0", + "midnight-zswap 8.2.0-rc.1", "rand 0.8.5", "rayon", "serde", - "sha2 0.10.9", + "sha2 0.11.0", "tokio", "tracing", "tracing-subscriber", @@ -7848,6 +7916,15 @@ dependencies = [ "quote 1.0.45", ] +[[package]] +name = "midnight-ledger-static" +version = "9.0.0" +source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1#4a5e2c862d03c2c4689dcbd32812edfaab30d20c" +dependencies = [ + "proc-macro2", + "quote 1.0.45", +] + [[package]] name = "midnight-ledger-v9" version = "1.0.0" @@ -7863,15 +7940,15 @@ dependencies = [ "is_sorted", "itertools 0.14.0", "lazy_static", - "midnight-base-crypto", + "midnight-base-crypto 1.1.0", "midnight-coin-structure 3.0.0", - "midnight-ledger-static", + "midnight-ledger-static 9.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "midnight-onchain-runtime 4.0.0", - "midnight-serialize", - "midnight-storage 2.0.1", + "midnight-serialize 1.2.0", + "midnight-storage 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "midnight-transient-crypto 2.2.0", "midnight-transient-crypto 3.0.0", - "midnight-zkir", + "midnight-zkir 2.2.0", "midnight-zswap 9.0.0", "rand 0.8.5", "rayon", @@ -7919,7 +7996,7 @@ dependencies = [ "midnight-primitives-reserve-observation", "midnight-primitives-session-info", "midnight-primitives-system-parameters", - "midnight-storage-core", + "midnight-storage-core 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "mmr-gadget", "mmr-rpc", "pallet-cnight-observation", @@ -8055,11 +8132,13 @@ dependencies = [ "hex", "lazy_static", "log", - "midnight-base-crypto", - "midnight-coin-structure 2.0.1", + "midnight-base-crypto 1.0.0", + "midnight-base-crypto 1.1.0", + "midnight-coin-structure 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "midnight-coin-structure 2.0.1 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", "midnight-coin-structure 3.0.0", "midnight-ledger 7.0.3", - "midnight-ledger 8.1.0", + "midnight-ledger 8.2.0-rc.1", "midnight-ledger-v9", "midnight-node-ledger-helpers", "midnight-node-res", @@ -8067,14 +8146,17 @@ dependencies = [ "midnight-onchain-runtime 3.1.0", "midnight-onchain-runtime 4.0.0", "midnight-primitives-ledger", - "midnight-serialize", + "midnight-serialize 1.1.0", + "midnight-serialize 1.2.0", "midnight-storage 1.1.1", - "midnight-storage 2.0.1", - "midnight-storage-core", + "midnight-storage 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "midnight-storage 2.0.1 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", + "midnight-storage-core 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "midnight-transient-crypto 2.1.0", "midnight-transient-crypto 2.2.0", "midnight-transient-crypto 3.0.0", "midnight-zswap 7.0.3", - "midnight-zswap 8.1.0", + "midnight-zswap 8.2.0-rc.1", "midnight-zswap 9.0.0", "moka 0.11.3", "parity-db 0.5.4", @@ -8106,23 +8188,29 @@ dependencies = [ "itertools 0.14.0", "lazy_static", "log", - "midnight-base-crypto", - "midnight-coin-structure 2.0.1", + "midnight-base-crypto 1.0.0", + "midnight-base-crypto 1.1.0", + "midnight-coin-structure 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "midnight-coin-structure 2.0.1 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", "midnight-coin-structure 3.0.0", "midnight-ledger 7.0.3", - "midnight-ledger 8.1.0", + "midnight-ledger 8.2.0-rc.1", "midnight-ledger-v9", "midnight-onchain-runtime 2.0.1", "midnight-onchain-runtime 3.1.0", "midnight-onchain-runtime 4.0.0", - "midnight-serialize", + "midnight-serialize 1.1.0", + "midnight-serialize 1.2.0", "midnight-storage 1.1.1", - "midnight-storage 2.0.1", + "midnight-storage 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "midnight-storage 2.0.1 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", + "midnight-transient-crypto 2.1.0", "midnight-transient-crypto 2.2.0", "midnight-transient-crypto 3.0.0", - "midnight-zkir", + "midnight-zkir 2.1.0", + "midnight-zkir 2.2.0", "midnight-zswap 7.0.3", - "midnight-zswap 8.1.0", + "midnight-zswap 8.2.0-rc.1", "midnight-zswap 9.0.0", "rand 0.8.5", "rayon", @@ -8156,7 +8244,7 @@ dependencies = [ "midnight-primitives-ics-observation", "midnight-primitives-reserve-observation", "midnight-primitives-system-parameters", - "midnight-serialize", + "midnight-serialize 1.2.0", "pallet-cnight-observation", "sc-service", "serde", @@ -8312,11 +8400,11 @@ dependencies = [ "hex", "konst 0.3.16", "lazy_static", - "midnight-base-crypto", - "midnight-coin-structure 2.0.1", + "midnight-base-crypto 1.1.0", + "midnight-coin-structure 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "midnight-onchain-state 2.0.1", "midnight-onchain-vm 1.0.2", - "midnight-serialize", + "midnight-serialize 1.2.0", "midnight-storage 1.1.1", "midnight-transient-crypto 2.2.0", "rand 0.8.5", @@ -8328,8 +8416,7 @@ dependencies = [ [[package]] name = "midnight-onchain-runtime" version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cbc5ffd4440bcadc02ad13d7e608c48de5facdc860f949eef4a22be50cb29b7" +source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1#4a5e2c862d03c2c4689dcbd32812edfaab30d20c" dependencies = [ "derive-where", "enum_index", @@ -8338,13 +8425,13 @@ dependencies = [ "hex", "konst 0.4.3", "lazy_static", - "midnight-base-crypto", - "midnight-coin-structure 2.0.1", + "midnight-base-crypto 1.0.0", + "midnight-coin-structure 2.0.1 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", "midnight-onchain-state 3.0.0", "midnight-onchain-vm 3.1.0", - "midnight-serialize", - "midnight-storage 2.0.1", - "midnight-transient-crypto 2.2.0", + "midnight-serialize 1.1.0", + "midnight-storage 2.0.1 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", + "midnight-transient-crypto 2.1.0", "rand 0.8.5", "serde", "serde_bytes", @@ -8363,12 +8450,12 @@ dependencies = [ "hex", "konst 0.4.3", "lazy_static", - "midnight-base-crypto", + "midnight-base-crypto 1.1.0", "midnight-coin-structure 3.0.0", "midnight-onchain-state 4.0.0", "midnight-onchain-vm 4.0.0", - "midnight-serialize", - "midnight-storage 2.0.1", + "midnight-serialize 1.2.0", + "midnight-storage 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "midnight-transient-crypto 3.0.0", "rand 0.8.5", "serde", @@ -8385,9 +8472,9 @@ dependencies = [ "derive-where", "fake", "hex", - "midnight-base-crypto", - "midnight-coin-structure 2.0.1", - "midnight-serialize", + "midnight-base-crypto 1.1.0", + "midnight-coin-structure 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "midnight-serialize 1.2.0", "midnight-storage 1.1.1", "midnight-transient-crypto 2.2.0", "rand 0.8.5", @@ -8398,17 +8485,16 @@ dependencies = [ [[package]] name = "midnight-onchain-state" version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cf32b5175d303251d7051fb30532d4fdef3c19c7e36c5831c002a27e8440163" +source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1#4a5e2c862d03c2c4689dcbd32812edfaab30d20c" dependencies = [ "derive-where", "fake", "hex", - "midnight-base-crypto", - "midnight-coin-structure 2.0.1", - "midnight-serialize", - "midnight-storage 2.0.1", - "midnight-transient-crypto 2.2.0", + "midnight-base-crypto 1.0.0", + "midnight-coin-structure 2.0.1 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", + "midnight-serialize 1.1.0", + "midnight-storage 2.0.1 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", + "midnight-transient-crypto 2.1.0", "rand 0.8.5", "serde", "serde_bytes", @@ -8422,10 +8508,10 @@ dependencies = [ "derive-where", "fake", "hex", - "midnight-base-crypto", + "midnight-base-crypto 1.1.0", "midnight-coin-structure 3.0.0", - "midnight-serialize", - "midnight-storage 2.0.1", + "midnight-serialize 1.2.0", + "midnight-storage 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "midnight-transient-crypto 2.2.0", "midnight-transient-crypto 3.0.0", "rand 0.8.5", @@ -8443,10 +8529,10 @@ dependencies = [ "fake", "hex", "konst 0.3.16", - "midnight-base-crypto", - "midnight-coin-structure 2.0.1", + "midnight-base-crypto 1.1.0", + "midnight-coin-structure 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "midnight-onchain-state 2.0.1", - "midnight-serialize", + "midnight-serialize 1.2.0", "midnight-storage 1.1.1", "midnight-transient-crypto 2.2.0", "rand 0.8.5", @@ -8458,19 +8544,18 @@ dependencies = [ [[package]] name = "midnight-onchain-vm" version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "950c687ea706f5dd92270e06474829c732b0d7e8119430a14ea60e635050071a" +source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1#4a5e2c862d03c2c4689dcbd32812edfaab30d20c" dependencies = [ "derive-where", "fake", "hex", "konst 0.4.3", - "midnight-base-crypto", - "midnight-coin-structure 2.0.1", + "midnight-base-crypto 1.0.0", + "midnight-coin-structure 2.0.1 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", "midnight-onchain-state 3.0.0", - "midnight-serialize", - "midnight-storage 2.0.1", - "midnight-transient-crypto 2.2.0", + "midnight-serialize 1.1.0", + "midnight-storage 2.0.1 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", + "midnight-transient-crypto 2.1.0", "rand 0.8.5", "rpds 1.2.1", "serde", @@ -8486,11 +8571,11 @@ dependencies = [ "fake", "hex", "konst 0.4.3", - "midnight-base-crypto", + "midnight-base-crypto 1.1.0", "midnight-coin-structure 3.0.0", "midnight-onchain-state 4.0.0", - "midnight-serialize", - "midnight-storage 2.0.1", + "midnight-serialize 1.2.0", + "midnight-storage 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "midnight-transient-crypto 3.0.0", "rand 0.8.5", "rpds 1.2.1", @@ -8672,6 +8757,19 @@ dependencies = [ "tracing", ] +[[package]] +name = "midnight-serialize" +version = "1.1.0" +source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1#4a5e2c862d03c2c4689dcbd32812edfaab30d20c" +dependencies = [ + "crypto", + "konst 0.4.3", + "lazy_static", + "midnight-serialize-macros 1.0.0 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", + "serde", + "serde_bytes", +] + [[package]] name = "midnight-serialize" version = "1.2.0" @@ -8680,7 +8778,7 @@ dependencies = [ "crypto", "konst 0.4.3", "lazy_static", - "midnight-serialize-macros", + "midnight-serialize-macros 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde", "serde_bytes", ] @@ -8696,6 +8794,16 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "midnight-serialize-macros" +version = "1.0.0" +source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1#4a5e2c862d03c2c4689dcbd32812edfaab30d20c" +dependencies = [ + "proc-macro2", + "quote 1.0.45", + "syn 2.0.117", +] + [[package]] name = "midnight-storage" version = "1.1.1" @@ -8704,9 +8812,9 @@ checksum = "df40bcb4aa0a709f5c4441f6d05aa15e853f434d777c6ef8a4692c00f24d3f6e" dependencies = [ "crypto", "derive-where", - "midnight-base-crypto", - "midnight-serialize", - "midnight-storage-core", + "midnight-base-crypto 1.1.0", + "midnight-serialize 1.2.0", + "midnight-storage-core 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.12.5", "rand 0.8.5", "serde", @@ -8722,9 +8830,9 @@ checksum = "210e601a89aee79ce2b007cf96c1a56c23baa306b0c40b9b98d12c27e18d1981" dependencies = [ "crypto", "derive-where", - "midnight-base-crypto", - "midnight-serialize", - "midnight-storage-core", + "midnight-base-crypto 1.1.0", + "midnight-serialize 1.2.0", + "midnight-storage-core 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.12.5", "rand 0.8.5", "serde", @@ -8733,6 +8841,25 @@ dependencies = [ "tempfile", ] +[[package]] +name = "midnight-storage" +version = "2.0.1" +source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1#4a5e2c862d03c2c4689dcbd32812edfaab30d20c" +dependencies = [ + "crypto", + "derive-where", + "digest 0.11.3", + "midnight-base-crypto 1.0.0", + "midnight-serialize 1.1.0", + "midnight-storage-core 1.2.0 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", + "parking_lot 0.12.5", + "rand 0.8.5", + "serde", + "sha2 0.11.0", + "sysinfo 0.39.6", + "tempfile", +] + [[package]] name = "midnight-storage-core" version = "1.2.0" @@ -8747,9 +8874,9 @@ dependencies = [ "itertools 0.14.0", "konst 0.4.3", "lru 0.16.4", - "midnight-base-crypto", - "midnight-serialize", - "midnight-storage-macros", + "midnight-base-crypto 1.1.0", + "midnight-serialize 1.2.0", + "midnight-storage-macros 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-db 0.5.4", "parking_lot 0.12.5", "rand 0.8.5", @@ -8759,18 +8886,91 @@ dependencies = [ "tempfile", ] +[[package]] +name = "midnight-storage-core" +version = "1.2.0" +source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1#4a5e2c862d03c2c4689dcbd32812edfaab30d20c" +dependencies = [ + "archery 1.2.2", + "crypto", + "derive-where", + "digest 0.11.3", + "fake", + "hex", + "itertools 0.14.0", + "konst 0.4.3", + "lru 0.18.0", + "midnight-base-crypto 1.0.0", + "midnight-serialize 1.1.0", + "midnight-storage-macros 1.0.0 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", + "parity-db 0.5.4", + "parking_lot 0.12.5", + "rand 0.8.5", + "serde", + "sha2 0.11.0", + "sysinfo 0.39.6", + "tempfile", +] + [[package]] name = "midnight-storage-macros" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6aeb4dc8c8ea5a6495036a88943c38cce40c23fc0181e0073ca52b7124800960" dependencies = [ - "midnight-serialize-macros", + "midnight-serialize-macros 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "midnight-storage-macros" +version = "1.0.0" +source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1#4a5e2c862d03c2c4689dcbd32812edfaab30d20c" +dependencies = [ + "midnight-serialize-macros 1.0.0 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", "proc-macro2", "quote 1.0.45", "syn 2.0.117", ] +[[package]] +name = "midnight-transient-crypto" +version = "2.1.0" +source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1#4a5e2c862d03c2c4689dcbd32812edfaab30d20c" +dependencies = [ + "anyhow", + "blake2b_simd", + "const-hex", + "derive-where", + "fake", + "ff", + "flate2", + "futures", + "group", + "k256", + "lazy_static", + "lru 0.18.0", + "midnight-base-crypto 1.0.0", + "midnight-base-crypto-derive 1.0.0", + "midnight-circuits 6.2.1", + "midnight-curves 0.2.1", + "midnight-proofs 0.7.2", + "midnight-serialize 1.1.0", + "midnight-storage-core 1.2.0 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", + "midnight-zk-stdlib 1.2.1", + "pastey", + "rand 0.8.5", + "serde", + "serde_bytes", + "serde_json", + "sha2 0.11.0", + "signature", + "tracing", + "zeroize", +] + [[package]] name = "midnight-transient-crypto" version = "2.2.0" @@ -8788,13 +8988,13 @@ dependencies = [ "k256", "lazy_static", "lru 0.18.0", - "midnight-base-crypto", - "midnight-base-crypto-derive", + "midnight-base-crypto 1.1.0", + "midnight-base-crypto-derive 1.1.0", "midnight-circuits 6.2.1", "midnight-curves 0.2.1", "midnight-proofs 0.7.2", - "midnight-serialize", - "midnight-storage-core", + "midnight-serialize 1.2.0", + "midnight-storage-core 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "midnight-zk-stdlib 1.2.1", "pastey", "rand 0.8.5", @@ -8823,13 +9023,13 @@ dependencies = [ "k256", "lazy_static", "lru 0.18.0", - "midnight-base-crypto", - "midnight-base-crypto-derive", + "midnight-base-crypto 1.1.0", + "midnight-base-crypto-derive 1.1.0", "midnight-circuits 7.2.1", "midnight-curves 0.3.1", "midnight-proofs 0.8.1", - "midnight-serialize", - "midnight-storage-core", + "midnight-serialize 1.2.0", + "midnight-storage-core 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "midnight-zk-stdlib 2.3.1", "pastey", "rand 0.8.5", @@ -8889,6 +9089,31 @@ dependencies = [ "sha3-circuit 0.2.0", ] +[[package]] +name = "midnight-zkir" +version = "2.1.0" +source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1#4a5e2c862d03c2c4689dcbd32812edfaab30d20c" +dependencies = [ + "anyhow", + "const-hex", + "group", + "hex", + "midnight-base-crypto 1.0.0", + "midnight-circuits 6.2.1", + "midnight-proofs 0.7.2", + "midnight-serialize 1.1.0", + "midnight-transient-crypto 2.1.0", + "midnight-zk-stdlib 1.2.1", + "num-bigint", + "rand 0.8.5", + "rand_chacha 0.3.1", + "serde", + "serde_bytes", + "serde_json", + "serde_repr", + "tracing", +] + [[package]] name = "midnight-zkir" version = "2.2.0" @@ -8899,12 +9124,12 @@ dependencies = [ "flate2", "group", "hex", - "midnight-base-crypto", + "midnight-base-crypto 1.1.0", "midnight-circuits 6.2.1", "midnight-circuits 7.2.1", "midnight-proofs 0.7.2", "midnight-proofs 0.8.1", - "midnight-serialize", + "midnight-serialize 1.2.0", "midnight-transient-crypto 2.2.0", "midnight-transient-crypto 3.0.0", "midnight-zk-stdlib 1.2.1", @@ -8931,11 +9156,11 @@ dependencies = [ "is_sorted", "itertools 0.14.0", "lazy_static", - "midnight-base-crypto", - "midnight-coin-structure 2.0.1", - "midnight-ledger-static", + "midnight-base-crypto 1.1.0", + "midnight-coin-structure 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "midnight-ledger-static 9.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "midnight-onchain-runtime 2.0.1", - "midnight-serialize", + "midnight-serialize 1.2.0", "midnight-storage 1.1.1", "midnight-transient-crypto 2.2.0", "rand 0.8.5", @@ -8946,9 +9171,8 @@ dependencies = [ [[package]] name = "midnight-zswap" -version = "8.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c83f946d8ac03abea38ca470599801fa08e91e2ddf3cb0963027a7701180c7c" +version = "8.2.0-rc.1" +source = "git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1#4a5e2c862d03c2c4689dcbd32812edfaab30d20c" dependencies = [ "derive-where", "fake", @@ -8956,13 +9180,13 @@ dependencies = [ "is_sorted", "itertools 0.14.0", "lazy_static", - "midnight-base-crypto", - "midnight-coin-structure 2.0.1", - "midnight-ledger-static", + "midnight-base-crypto 1.0.0", + "midnight-coin-structure 2.0.1 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", + "midnight-ledger-static 9.0.0 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", "midnight-onchain-runtime 3.1.0", - "midnight-serialize", - "midnight-storage 2.0.1", - "midnight-transient-crypto 2.2.0", + "midnight-serialize 1.1.0", + "midnight-storage 2.0.1 (git+https://github.com/midnightntwrk/midnight-ledger?tag=ledger-8.2.0-rc.1)", + "midnight-transient-crypto 2.1.0", "rand 0.8.5", "serde", "tracing", @@ -8981,15 +9205,15 @@ dependencies = [ "is_sorted", "itertools 0.14.0", "lazy_static", - "midnight-base-crypto", + "midnight-base-crypto 1.1.0", "midnight-coin-structure 3.0.0", - "midnight-ledger-static", + "midnight-ledger-static 9.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "midnight-onchain-runtime 4.0.0", - "midnight-serialize", - "midnight-storage 2.0.1", + "midnight-serialize 1.2.0", + "midnight-storage 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "midnight-transient-crypto 2.2.0", "midnight-transient-crypto 3.0.0", - "midnight-zkir", + "midnight-zkir 2.2.0", "rand 0.8.5", "serde", "tracing", @@ -9710,6 +9934,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +[[package]] +name = "objc2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" +dependencies = [ + "objc2-encode", +] + [[package]] name = "objc2-core-foundation" version = "0.3.2" @@ -9717,6 +9950,45 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ "bitflags 2.11.0", + "dispatch2", + "objc2", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags 2.11.0", + "objc2", +] + +[[package]] +name = "objc2-io-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15" +dependencies = [ + "libc", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-open-directory" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb82bed227edf5201dfedf072bba4015a33d3d4a98519837295a90f0a23f676d" +dependencies = [ + "objc2", + "objc2-core-foundation", + "objc2-foundation", ] [[package]] @@ -18526,6 +18798,21 @@ dependencies = [ "windows 0.57.0", ] +[[package]] +name = "sysinfo" +version = "0.39.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2071df9448915b71c4fe6d25deaf1c22f12bd234f01540b77312bb8e41361e6" +dependencies = [ + "libc", + "memchr", + "ntapi", + "objc2-core-foundation", + "objc2-io-kit", + "objc2-open-directory", + "windows 0.62.2", +] + [[package]] name = "system-configuration" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index ea5822b85..0d0ead41a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,18 +84,31 @@ zswap = { version = "=7.0.3", package = "midnight-zswap" } # transient-crypto 2.2.0's new tagged-IR trait methods. zkir = { version = "^2.2.0", package = "midnight-zkir" } -# Ledger 8 (compatible with layout-v2) -# coin-structure and transient-crypto (2.x) share versions with L7 so reuse those entries. -mn-ledger-8 = { version = "=8.1.0", package = "midnight-ledger" } -ledger-storage-ledger-8 = { version = "=2.0.1", package = "midnight-storage", features = ["parity-db"] } -onchain-runtime-ledger-8 = { version = "=3.1.0", package = "midnight-onchain-runtime" } -zswap-ledger-8 = { version = "=8.1.0", package = "midnight-zswap" } +# Ledger 8 (8.2.0-rc.1, compatible with layout-v2) — sourced from the git tag, not crates.io. +# 8.2.0-rc.1 is unpublished and the raw tag carries path deps, so the *whole* L8 companion set +# must resolve from the same git rev to unify types: a mixed crates.io/git graph forks a crate +# like midnight-storage-core 1.2.0 into two source-incompatible copies (E0277: trait `DB` not +# satisfied). Consequently L8 no longer shares coin-structure/base-crypto/transient-crypto/ +# serialize with L7 — each gets a dedicated `-ledger-8` entry pinned to the tag. +mn-ledger-8 = { git = "https://github.com/midnightntwrk/midnight-ledger", tag = "ledger-8.2.0-rc.1", package = "midnight-ledger" } +zswap-ledger-8 = { git = "https://github.com/midnightntwrk/midnight-ledger", tag = "ledger-8.2.0-rc.1", package = "midnight-zswap" } +onchain-runtime-ledger-8 = { git = "https://github.com/midnightntwrk/midnight-ledger", tag = "ledger-8.2.0-rc.1", package = "midnight-onchain-runtime" } +ledger-storage-ledger-8 = { git = "https://github.com/midnightntwrk/midnight-ledger", tag = "ledger-8.2.0-rc.1", package = "midnight-storage", features = ["parity-db"] } +coin-structure-ledger-8 = { git = "https://github.com/midnightntwrk/midnight-ledger", tag = "ledger-8.2.0-rc.1", package = "midnight-coin-structure" } +base-crypto-ledger-8 = { git = "https://github.com/midnightntwrk/midnight-ledger", tag = "ledger-8.2.0-rc.1", package = "midnight-base-crypto" } +transient-crypto-ledger-8 = { git = "https://github.com/midnightntwrk/midnight-ledger", tag = "ledger-8.2.0-rc.1", package = "midnight-transient-crypto" } +serialize-ledger-8 = { git = "https://github.com/midnightntwrk/midnight-ledger", tag = "ledger-8.2.0-rc.1", package = "midnight-serialize" } +# The workspace `zkir` (2.2.0) is bound to the 3.x-crypto stack and can't prove against L8's +# transient-crypto 2.1.0. Take zkir 2.1.0 from the same tag so L8's proving stack is self-consistent. +zkir-ledger-8 = { git = "https://github.com/midnightntwrk/midnight-ledger", tag = "ledger-8.2.0-rc.1", package = "midnight-zkir" } # Ledger 9 (compatible with layout-v2; midnight-ledger-v9 crate) -# storage shares versions with L8 so reuses that entry. coin-structure and -# transient-crypto went semver-major in L9 so get their own entries. The workspace `zkir` -# (midnight-zkir 2.2.0) serves all of L7/L8/L9. +# midnight-ledger-v9 uses registry deps, so its storage resolves to crates.io 2.0.1; L8 moved to +# the git tag for 8.2, so the two no longer share a storage entry — L9 keeps its own crates.io one. +# coin-structure and transient-crypto went semver-major in L9 so get their own entries. The +# workspace `zkir` (midnight-zkir 2.2.0) serves all of L7/L8/L9. mn-ledger-9 = { version = "=1.0.0", package = "midnight-ledger-v9" } +ledger-storage-ledger-9 = { version = "=2.0.1", package = "midnight-storage", features = ["parity-db"] } onchain-runtime-ledger-9 = { version = "=4.0.0", package = "midnight-onchain-runtime" } zswap-ledger-9 = { version = "=9.0.0", package = "midnight-zswap" } coin-structure-ledger-9 = { version = "=3.0.0", package = "midnight-coin-structure" } diff --git a/changes/node/changed/genesis-ledger-version-dispatch.md b/changes/node/changed/genesis-ledger-version-dispatch.md new file mode 100644 index 000000000..0c4dfb4f1 --- /dev/null +++ b/changes/node/changed/genesis-ledger-version-dispatch.md @@ -0,0 +1,20 @@ +#node #ledger +# Dispatch genesis bootstrap on the genesis blob's ledger version + +Genesis storage init and root derivation previously hardcoded the newest +ledger, so a node could not bootstrap a chain whose immutable genesis was +serialized with an older ledger (e.g. live mainnet, `ledger-state[v13]`). +The new `genesis_version` module reads the blob's serialization tag and +routes `get_root` / paritydb genesis init to the matching compiled-in ledger, +newest first (ledgers 7 and 8 share the `v13` wire tag, so `v13` blobs route +to ledger 8; `v18` to ledger 9). This is not state migration - each chain +keeps its own ledger version; only the forced-newest assumption at the +genesis boundary is gone. + +Regression test pins detection for every shipped genesis blob (mainnet -> L8, +undeployed -> L9, garbage -> unrecognised). The startup E2E is now a parallel +matrix - one leg boots the stock ledger-9 genesis, the other a ledger-8 (`v13`) +undeployed genesis fixture - each asserting finality advances. Each leg is its +own required status check ("Startup E2E in dev mode (ledger-N)"). + +PR: https://github.com/midnightntwrk/midnight-node/pull/1869 diff --git a/changes/node/changed/ledger-8-2-upgrade.md b/changes/node/changed/ledger-8-2-upgrade.md new file mode 100644 index 000000000..325b6c29c --- /dev/null +++ b/changes/node/changed/ledger-8-2-upgrade.md @@ -0,0 +1,24 @@ +#ledger #dependencies +# Upgrade ledger 8 from 8.1.0 to 8.2.0-rc.1 + +Bumps the ledger-8 stack to `midnight-ledger` 8.2.0-rc.1 (picking up +`apply_guaranteed_only`, infallible `post_block_update`, split-phase execution +with deferred events, and the segment-type refactor), keeping ledger 9 as-is. + +8.2.0-rc.1 is not published to crates.io, so the ledger-8 crates are sourced +directly from the `ledger-8.2.0-rc.1` git tag. Because the tag carries path +deps, ledger 8 no longer shares its companion crates with ledger 7 — each gets +a dedicated `-ledger-8` entry pinned to the tag. Per-generation storage code +now uses each ledger's own `DefaultHasher` instead of a hardcoded `sha2::Sha256` +so it tracks the git-8.2 storage-core's sha2 0.11 bump automatically, and the +hard-fork state-migration helpers serialize-round-trip across the (now +distinct) L7/L8/L9 storage arenas instead of reinterpreting arena keys in place. + +The Ledger-8 guaranteed-segment validation shim now calls 8.2's +`apply_guaranteed_only` (matching the Ledger-9 shim) instead of dry-running the +full `apply()`. Under the old path, mempool/pre-dispatch validation executed the +fallible segment even though acceptance depends only on the guaranteed segment - +an avoidable validation-cost/DoS vector that the 8.2 split-phase API exists to +close. + +PR: https://github.com/midnightntwrk/midnight-node/pull/1869 diff --git a/ledger/Cargo.toml b/ledger/Cargo.toml index 4cbea9a5f..45578bf5e 100644 --- a/ledger/Cargo.toml +++ b/ledger/Cargo.toml @@ -20,9 +20,14 @@ mn-ledger-8 = { workspace = true, features = ["proving"], optional = true } onchain-runtime-ledger-8 = { workspace = true, optional = true } ledger-storage-ledger-8 = { workspace = true, optional = true } zswap-ledger-8 = { workspace = true, optional = true } +coin-structure-ledger-8 = { workspace = true, optional = true } +base-crypto-ledger-8 = { workspace = true, optional = true } +transient-crypto-ledger-8 = { workspace = true, optional = true } +serialize-ledger-8 = { workspace = true, optional = true } mn-ledger-9 = { workspace = true, features = ["proving"], optional = true } onchain-runtime-ledger-9 = { workspace = true, optional = true } +ledger-storage-ledger-9 = { workspace = true, optional = true } zswap-ledger-9 = { workspace = true, optional = true } coin-structure-ledger-9 = { workspace = true, optional = true } transient-crypto-ledger-9 = { workspace = true, optional = true } @@ -83,8 +88,13 @@ std = [ "onchain-runtime-ledger-8", "ledger-storage-ledger-8", "zswap-ledger-8", + "coin-structure-ledger-8", + "base-crypto-ledger-8", + "transient-crypto-ledger-8", + "serialize-ledger-8", "mn-ledger-9", "onchain-runtime-ledger-9", + "ledger-storage-ledger-9", "zswap-ledger-9", "coin-structure-ledger-9", "transient-crypto-ledger-9", diff --git a/ledger/helpers/Cargo.toml b/ledger/helpers/Cargo.toml index 76c286887..d15f86ea4 100644 --- a/ledger/helpers/Cargo.toml +++ b/ledger/helpers/Cargo.toml @@ -29,9 +29,15 @@ mn-ledger-8 = { workspace = true, features = ["proving"] } onchain-runtime-ledger-8 = { workspace = true } ledger-storage-ledger-8 = { workspace = true } zswap-ledger-8 = { workspace = true } +coin-structure-ledger-8 = { workspace = true } +base-crypto-ledger-8 = { workspace = true } +transient-crypto-ledger-8 = { workspace = true } +serialize-ledger-8 = { workspace = true } +zkir-ledger-8 = { workspace = true } mn-ledger-9 = { workspace = true, features = ["proving", "test-utilities"] } onchain-runtime-ledger-9 = { workspace = true } +ledger-storage-ledger-9 = { workspace = true } zswap-ledger-9 = { workspace = true } coin-structure-ledger-9 = { workspace = true } transient-crypto-ledger-9 = { workspace = true } diff --git a/ledger/helpers/src/extract_tx_with_context.rs b/ledger/helpers/src/extract_tx_with_context.rs index 881426630..f5dc9d834 100644 --- a/ledger/helpers/src/extract_tx_with_context.rs +++ b/ledger/helpers/src/extract_tx_with_context.rs @@ -15,22 +15,15 @@ pub fn extract_tx_with_context_ledger_9(bytes: &[u8]) -> (Vec, crate::ledger #[cfg(feature = "can-panic")] pub fn extract_tx_with_context_ledger_8(bytes: &[u8]) -> (Vec, crate::ledger_8::BlockContext) { - use crate::fork::raw_block_data::RawTransaction; - - let serialized_tx: SerializedTx = + // The `BlockContext` JSON wire shape is version-agnostic (see `SerializedTx` + // docs), so deserialize straight into L8's context type. + let serialized_tx: SerializedTx = serde_json::from_slice(bytes).expect("failed to deserialize as SerializedTx"); let RawTransaction::Midnight(tx_bytes) = serialized_tx.tx else { panic!("expected test to run against midnight transaction"); }; - let block_context = crate::ledger_8::BlockContext { - tblock: serialized_tx.context.tblock, - tblock_err: serialized_tx.context.tblock_err, - parent_block_hash: serialized_tx.context.parent_block_hash, - last_block_time: serialized_tx.context.last_block_time, - }; - - (tx_bytes, block_context) + (tx_bytes, serialized_tx.context) } #[cfg(feature = "can-panic")] diff --git a/ledger/helpers/src/fork/fork_7_to_8.rs b/ledger/helpers/src/fork/fork_7_to_8.rs index 279b16e6f..57980e787 100644 --- a/ledger/helpers/src/fork/fork_7_to_8.rs +++ b/ledger/helpers/src/fork/fork_7_to_8.rs @@ -12,22 +12,23 @@ use crate::ledger_8::{ Timestamp as Timestamp8, UnshieldedWallet, Wallet, WalletSeed, WalletState, default_storage, }; +/// Move a storage-pointer value from ledger-7 storage into ledger-8 storage. +/// +/// L7 (crates.io storage-core) and L8 (git-8.2 storage-core) no longer share a storage arena, so +/// this serializes `t1` in the L7 format, deserializes it as `T2` in the L8 format, and allocates +/// the result into L8 storage. Hence the `Serializable`/`Deserializable` bounds. pub fn old_to_new_sp( - mut t1: crate::ledger_7::Sp, + t1: crate::ledger_7::Sp, ) -> Result, std::io::Error> where - T1: crate::ledger_7::Storable, - T2: crate::ledger_8::Storable + crate::ledger_8::Tagged, + T1: crate::ledger_7::Storable + crate::ledger_7::Serializable + crate::ledger_7::Tagged, + T2: crate::ledger_8::Storable + crate::ledger_8::Deserializable + crate::ledger_8::Tagged, { - t1.persist(); - let old_root = t1.as_typed_key().key; - // Both ArenaKey types are the same type (unified via midnight-storage-core patch). - let new_arena_key: crate::ledger_8::ArenaKey = old_root; - let new_root = crate::ledger_8::mn_ledger_storage::arena::TypedArenaKey::< - T2, - ::Hasher, - >::from(new_arena_key); - default_storage::().arena.get_lazy(&new_root) + // L7 (crates.io storage-core) and L8 (git-8.2 storage-core) no longer share a storage arena, + // so move the value across by serializing in the L7 format and deserializing in L8, then + // allocate it into L8 storage. (Previously this reinterpreted the arena key in place.) + let value: T2 = old_to_new_ser(&*t1)?; + Ok(default_storage::().arena.alloc(value)) } /// Serialize with ledger-7 format, deserialize with ledger-8 format (tagged). diff --git a/ledger/helpers/src/fork/fork_8_to_9.rs b/ledger/helpers/src/fork/fork_8_to_9.rs index 918cda2e9..50bf85c19 100644 --- a/ledger/helpers/src/fork/fork_8_to_9.rs +++ b/ledger/helpers/src/fork/fork_8_to_9.rs @@ -12,22 +12,23 @@ use crate::ledger_9::{ UnshieldedWallet, Wallet, WalletSeed, WalletState, default_storage, }; +/// Move a storage-pointer value from ledger-8 storage into ledger-9 storage. +/// +/// L8 (git-8.2 storage-core) and L9 (crates.io storage-core) no longer share a storage arena, so +/// this serializes `t1` in the L8 format, deserializes it as `T2` in the L9 format, and allocates +/// the result into L9 storage. Hence the `Serializable`/`Deserializable` bounds. pub fn old_to_new_sp( - mut t1: crate::ledger_8::Sp, + t1: crate::ledger_8::Sp, ) -> Result, std::io::Error> where - T1: crate::ledger_8::Storable + crate::ledger_8::Tagged, - T2: crate::ledger_9::Storable + crate::ledger_9::Tagged, + T1: crate::ledger_8::Storable + crate::ledger_8::Serializable + crate::ledger_8::Tagged, + T2: crate::ledger_9::Storable + crate::ledger_9::Deserializable + crate::ledger_9::Tagged, { - t1.persist(); - let old_root = t1.as_typed_key().key; - // Both ArenaKey types are the same type (unified via midnight-storage-core patch). - let new_arena_key: crate::ledger_9::ArenaKey = old_root; - let new_root = crate::ledger_9::mn_ledger_storage::arena::TypedArenaKey::< - T2, - ::Hasher, - >::from(new_arena_key); - default_storage::().arena.get_lazy(&new_root) + // L8 (git-8.2 storage-core) and L9 (crates.io storage-core) no longer share a storage arena, + // so the old in-place arena-key reinterpret is invalid. Move the value across by serializing in + // the L8 format and deserializing in L9, then allocate it into L9 storage. + let value: T2 = old_to_new_ser(&*t1)?; + Ok(default_storage::().arena.alloc(value)) } /// Serialize with ledger-8 format, deserialize with ledger-9 format (tagged). @@ -52,14 +53,18 @@ pub fn old_to_new_ser_untagged< crate::ledger_9::deserialize_untagged(&mut &t_bytes[..]) } -/// Convert a ledger-8 BlockContext to a ledger-9 BlockContext. +/// Convert a ledger-8 `BlockContext` to a ledger-9 one. /// +/// L8 and L9 base-crypto diverged (1.0.0 vs 1.1.0), so the `Timestamp` and `HashOutput` fields are +/// distinct types and are rebuilt by value rather than moved. pub fn block_context_8_to_9(ctx8: &crate::ledger_8::BlockContext) -> BlockContext9 { + use crate::ledger_9::base_crypto::time::Timestamp; + // L8/L9 base-crypto diverged (1.0.0 vs 1.1.0), so timestamps are rebuilt by value. BlockContext9 { - tblock: ctx8.tblock, + tblock: Timestamp::from_secs(ctx8.tblock.to_secs()), tblock_err: ctx8.tblock_err, parent_block_hash: HashOutput9(ctx8.parent_block_hash.0), - last_block_time: ctx8.last_block_time, + last_block_time: Timestamp::from_secs(ctx8.last_block_time.to_secs()), } } @@ -67,7 +72,7 @@ pub fn fork_context_8_to_9( context8: LedgerContext8, ) -> Result, std::io::Error> { let ledger_state_8 = context8.ledger_state.lock().expect("failed to lock ledger state"); - let ledger_state: crate::ledger_9::Sp, Db8> = + let ledger_state: crate::ledger_9::Sp, Db9> = old_to_new_sp(ledger_state_8.clone())?; let mut wallets = HashMap::new(); @@ -89,7 +94,7 @@ pub fn fork_context_8_to_9( .expect("wallet seed different length between versions") }), shielded: ShieldedWallet { - state: (*old_to_new_sp::<_, WalletState>(crate::ledger_8::Sp::new( + state: (*old_to_new_sp::<_, WalletState>(crate::ledger_8::Sp::new( v.shielded.state.clone(), ))?) .clone(), @@ -101,7 +106,7 @@ pub fn fork_context_8_to_9( v.unshielded.clone(), ))?) .clone(), - dust: (*old_to_new_sp::<_, DustWallet>(crate::ledger_8::Sp::new(v.dust.clone()))?) + dust: (*old_to_new_sp::<_, DustWallet>(crate::ledger_8::Sp::new(v.dust.clone()))?) .clone(), }; let new_key: WalletSeed = old_to_new_ser_untagged(&k)?; diff --git a/ledger/helpers/src/fork/raw_block_data.rs b/ledger/helpers/src/fork/raw_block_data.rs index ef65b83e1..cd0118a04 100644 --- a/ledger/helpers/src/fork/raw_block_data.rs +++ b/ledger/helpers/src/fork/raw_block_data.rs @@ -158,18 +158,24 @@ impl RawBlockData { } /// A single serialized transaction ready for sending or file output. +/// +/// `C` is the target ledger version's `BlockContext` (defaults to the current, +/// ledger-9, type). Every ledger version serializes `BlockContext` through the +/// same `SerdeBlockContext` bridge, so the JSON wire shape is version-agnostic +/// and the context can be deserialized directly as the version the caller +/// needs, e.g. `SerializedTx`. #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct SerializedTx { +pub struct SerializedTx { /// Serialized `Transaction` — the payload for `send_mn_transaction`. pub tx: RawTransaction, /// Serialized `BlockContext` - pub context: BlockContext, + pub context: C, /// Transaction hash for logging. #[serde(with = "hex_or_bytes_32")] pub tx_hash: [u8; 32], } -impl SerializedTx { +impl SerializedTx { pub fn tx_byte_len(&self) -> usize { match &self.tx { RawTransaction::Midnight(tx) => tx.len(), diff --git a/ledger/helpers/src/lib.rs b/ledger/helpers/src/lib.rs index 314cf5299..605d20e62 100644 --- a/ledger/helpers/src/lib.rs +++ b/ledger/helpers/src/lib.rs @@ -166,9 +166,11 @@ pub mod ledger_8 { /// Workspace dependency name of the ledger crate backing this module. pub const CRATE_NAME: &str = "mn-ledger-8"; pub use { - base_crypto, coin_structure, ledger_storage_ledger_8 as ledger_storage, midnight_serialize, - mn_ledger_8 as mn_ledger, onchain_runtime_ledger_8 as onchain_runtime, transient_crypto, - zkir, zswap_ledger_8 as zswap, + base_crypto_ledger_8 as base_crypto, coin_structure_ledger_8 as coin_structure, + ledger_storage_ledger_8 as ledger_storage, mn_ledger_8 as mn_ledger, + onchain_runtime_ledger_8 as onchain_runtime, serialize_ledger_8 as midnight_serialize, + transient_crypto_ledger_8 as transient_crypto, zkir_ledger_8 as zkir, + zswap_ledger_8 as zswap, }; // Vendored test-utilities shim for v8. @@ -285,7 +287,7 @@ pub mod ledger_9 { pub const CRATE_NAME: &str = "mn-ledger-9"; pub use { base_crypto, coin_structure_ledger_9 as coin_structure, - ledger_storage_ledger_8 as ledger_storage, midnight_serialize, mn_ledger_9 as mn_ledger, + ledger_storage_ledger_9 as ledger_storage, midnight_serialize, mn_ledger_9 as mn_ledger, onchain_runtime_ledger_9 as onchain_runtime, transient_crypto_ledger_9 as transient_crypto, zkir, zswap_ledger_9 as zswap, }; diff --git a/ledger/helpers/src/versions/common/wallet/dust.rs b/ledger/helpers/src/versions/common/wallet/dust.rs index f05461afa..f57d2f28c 100644 --- a/ledger/helpers/src/versions/common/wallet/dust.rs +++ b/ledger/helpers/src/versions/common/wallet/dust.rs @@ -194,8 +194,8 @@ impl TryFrom<&WalletAddress> for DustWallet { #[cfg(test)] mod tests { + use super::storage::DefaultDB; use super::{DerivationPath, DustWallet, Role, WalletSeed}; - use crate::DefaultDB; fn test_seed() -> WalletSeed { WalletSeed::from([0u8; 32]) diff --git a/ledger/src/host_api/ledger_8.rs b/ledger/src/host_api/ledger_8.rs index 13bf1a9c0..7e19dbfdc 100644 --- a/ledger/src/host_api/ledger_8.rs +++ b/ledger/src/host_api/ledger_8.rs @@ -32,7 +32,7 @@ type Signature = crate::ledger_8::base_crypto_local::signatures::Signature; type DbSeparate = crate::ledger_8::ledger_storage_local::db::ParityDb; #[cfg(feature = "std")] type DbUnified = crate::ledger_8::ledger_storage_local::db::ParityDb< - sha2::Sha256, + crate::ledger_8::ledger_storage_local::DefaultHasher, crate::ledger_8::ledger_storage_local::db::paritydb::OwnedDb, { LedgerStorageExt::COLUMN_OFFSET }, >; diff --git a/ledger/src/host_api/ledger_9.rs b/ledger/src/host_api/ledger_9.rs index 35bf5617b..9ebc267d1 100644 --- a/ledger/src/host_api/ledger_9.rs +++ b/ledger/src/host_api/ledger_9.rs @@ -477,7 +477,7 @@ pub trait Ledger9Bridge { /// drops new version's storage and initializes normal storage. /// Returns true if storage was (re)initialized, false if already correct. fn ensure_storage_initialized(&mut self) -> bool { - use ledger_storage_ledger_8::storage::try_get_default_storage; + use ledger_storage_ledger_9::storage::try_get_default_storage; let unified = is_unified(*self); diff --git a/ledger/src/lib.rs b/ledger/src/lib.rs index a62f0290a..23c7fa2b0 100644 --- a/ledger/src/lib.rs +++ b/ledger/src/lib.rs @@ -71,12 +71,12 @@ pub mod ledger_7 { pub mod ledger_8 { #[cfg(feature = "std")] pub(crate) use { - base_crypto as base_crypto_local, coin_structure as coin_structure_local, + base_crypto_ledger_8 as base_crypto_local, coin_structure_ledger_8 as coin_structure_local, ledger_storage_ledger_8 as ledger_storage_local, - midnight_node_ledger_helpers::ledger_8 as helpers_local, - midnight_serialize as midnight_serialize_local, mn_ledger_8 as mn_ledger_local, + midnight_node_ledger_helpers::ledger_8 as helpers_local, mn_ledger_8 as mn_ledger_local, onchain_runtime_ledger_8 as onchain_runtime_local, - transient_crypto as transient_crypto_local, zswap_ledger_8 as zswap_local, + serialize_ledger_8 as midnight_serialize_local, + transient_crypto_ledger_8 as transient_crypto_local, zswap_ledger_8 as zswap_local, }; #[path = "block_context/post_ledger_8.rs"] @@ -108,7 +108,7 @@ pub mod ledger_9 { #[cfg(feature = "std")] pub(crate) use { base_crypto as base_crypto_local, coin_structure_ledger_9 as coin_structure_local, - ledger_storage_ledger_8 as ledger_storage_local, + ledger_storage_ledger_9 as ledger_storage_local, midnight_node_ledger_helpers::ledger_9 as helpers_local, midnight_serialize as midnight_serialize_local, mn_ledger_9 as mn_ledger_local, onchain_runtime_ledger_9 as onchain_runtime_local, @@ -154,6 +154,143 @@ pub fn drop_all_default_storage() { ledger_9::storage::drop_default_storage_if_exists(); } +/// Genesis bootstrap that dispatches on the ledger version embedded in the +/// genesis state, instead of assuming the newest. +/// +/// All ledger versions are compiled in, but a genesis blob is serialized with +/// exactly one version's `LedgerState`, and its deserializer rejects any other +/// version's tag. Hardcoding the latest (as each ledger bump historically did) +/// makes the node unable to bootstrap a chain still on an older genesis — e.g. +/// live mainnet, whose genesis is immutable. These wrappers read the blob's tag +/// and route to the matching module. This is *not* state migration: each chain +/// keeps running its own ledger version; we only stop forcing the newest at the +/// genesis boundary. +#[cfg(feature = "std")] +pub mod genesis_version { + /// Ledger storage version a tagged genesis blob was produced with. + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + pub enum LedgerVersion { + /// ledger 7 + V7, + /// ledger 8 + V8, + /// ledger 9 + V9, + } + + /// Detect a genesis blob's ledger version by matching its leading tag + /// against each compiled-in module's own `LedgerState` tag. Newest first: + /// ledgers 7 and 8 currently share the `ledger-state[v13]` tag (same wire + /// format), so a `v13` blob routes to [`LedgerVersion::V8`] and the V7 arm + /// is unreachable while that tie holds - it stays as self-healing dispatch + /// should the tags ever diverge. `None` if no known version matches + /// (corrupt or future-version blob). + pub fn detect(genesis_state: &[u8]) -> Option { + let head = &genesis_state[..genesis_state.len().min(64)]; + let has = |tag: &str| head.windows(tag.len()).any(|w| w == tag.as_bytes()); + if has(&super::ledger_9::storage::genesis_ledger_state_tag()) { + Some(LedgerVersion::V9) + } else if has(&super::ledger_8::storage::genesis_ledger_state_tag()) { + Some(LedgerVersion::V8) + } else if has(&super::ledger_7::storage::genesis_ledger_state_tag()) { + Some(LedgerVersion::V7) + } else { + None + } + } + + fn unknown_version(genesis_state: &[u8]) -> String { + format!( + "unrecognised ledger genesis version tag in {}-byte genesis blob (known: {}, {}, {})", + genesis_state.len(), + super::ledger_9::storage::genesis_ledger_state_tag(), + super::ledger_8::storage::genesis_ledger_state_tag(), + super::ledger_7::storage::genesis_ledger_state_tag(), + ) + } + + /// Version-dispatched [`get_root`](super::ledger_9::storage::get_root). + pub fn get_root(genesis_state: &[u8], network_id: Option<&str>) -> Result, String> { + match detect(genesis_state) { + Some(LedgerVersion::V9) => { + super::ledger_9::storage::get_root(genesis_state, network_id) + .map_err(|e| e.to_string()) + }, + Some(LedgerVersion::V8) => { + super::ledger_8::storage::get_root(genesis_state, network_id) + .map_err(|e| e.to_string()) + }, + Some(LedgerVersion::V7) => { + super::ledger_7::storage::get_root(genesis_state, network_id) + .map_err(|e| e.to_string()) + }, + None => Err(unknown_version(genesis_state)), + } + } + + /// Version-dispatched separate-db genesis init. + /// + /// # Panics + /// Panics if the genesis blob's ledger version tag is unrecognised + /// (corrupt or future-version blob) - the node cannot start without a + /// bootable genesis, so there is nothing to recover to. + pub fn init_storage_paritydb_separate>( + dir: P, + genesis_state: &[u8], + cache_size: usize, + ) -> Vec { + match detect(genesis_state) { + Some(LedgerVersion::V9) => super::ledger_9::storage::init_storage_paritydb_separate( + dir, + genesis_state, + cache_size, + ), + Some(LedgerVersion::V8) => super::ledger_8::storage::init_storage_paritydb_separate( + dir, + genesis_state, + cache_size, + ), + Some(LedgerVersion::V7) => super::ledger_7::storage::init_storage_paritydb_separate( + dir, + genesis_state, + cache_size, + ), + None => panic!("{}", unknown_version(genesis_state)), + } + } + + /// Version-dispatched unified-db genesis init. + /// + /// # Panics + /// Panics if the genesis blob's ledger version tag is unrecognised + /// (corrupt or future-version blob) - the node cannot start without a + /// bootable genesis, so there is nothing to recover to. + pub fn init_storage_paritydb_unified< + D: std::ops::Deref + Default + Send + Sync + 'static, + const COLUMN_OFFSET: u8, + >( + db_instance: D, + genesis_state: &[u8], + cache_size: usize, + ) -> Vec { + match detect(genesis_state) { + Some(LedgerVersion::V9) => super::ledger_9::storage::init_storage_paritydb_unified::< + D, + COLUMN_OFFSET, + >(db_instance, genesis_state, cache_size), + Some(LedgerVersion::V8) => super::ledger_8::storage::init_storage_paritydb_unified::< + D, + COLUMN_OFFSET, + >(db_instance, genesis_state, cache_size), + Some(LedgerVersion::V7) => super::ledger_7::storage::init_storage_paritydb_unified::< + D, + COLUMN_OFFSET, + >(db_instance, genesis_state, cache_size), + None => panic!("{}", unknown_version(genesis_state)), + } + } +} + mod common; pub mod types { @@ -167,12 +304,27 @@ pub mod types { mod tests { use frame_support::assert_ok; use ledger_storage_ledger_8::{ - Storage, + DefaultHasher, Storage, db::ParityDb, storage::{set_default_storage, try_get_default_storage, unsafe_drop_default_storage}, }; use std::path::PathBuf; + /// Every shipped genesis blob must be recognised, and mainnet's immutable + /// pre-ledger-9 genesis must route to ledger 8 — the case + /// [`crate::genesis_version`] exists for. (Ledgers 7 and 8 share the `v13` + /// tag; newest-first dispatch means V8 claims it.) + #[test] + fn genesis_version_detects_all_shipped_genesis_states() { + use crate::genesis_version::{LedgerVersion, detect}; + use midnight_node_res::networks::{MidnightNetwork, UndeployedNetwork}; + + assert_eq!(detect(UndeployedNetwork.genesis_state()), Some(LedgerVersion::V9)); + let mainnet = include_bytes!("../../res/genesis/genesis_state_mainnet.mn"); + assert_eq!(detect(mainnet), Some(LedgerVersion::V8)); + assert_eq!(detect(b"midnight:not-a-ledger-state"), None); + } + #[test] fn set_and_drop_default_storage() { let mut db_path: PathBuf = std::env::temp_dir(); @@ -185,7 +337,7 @@ mod tests { panic!("Failed to create dir {}, err {}", db_path.display(), err) }); - let db = ParityDb::::open(&db_path); + let db = ParityDb::::open(&db_path); Storage::new(0, db) }); diff --git a/ledger/src/versions/common/mod.rs b/ledger/src/versions/common/mod.rs index 270e71c5d..40f941e5a 100644 --- a/ledger/src/versions/common/mod.rs +++ b/ledger/src/versions/common/mod.rs @@ -24,8 +24,6 @@ use super::{ #[cfg(feature = "std")] use midnight_serialize_local::Tagged; #[cfg(feature = "std")] -use sha2::digest::{OutputSizeUser, generic_array::typenum::U32}; -#[cfg(feature = "std")] use transient_crypto_local::commitment::PureGeneratorPedersen; use alloc::vec::Vec; @@ -58,7 +56,7 @@ use { }, coin_structure_local::coin::Nonce, ledger_storage_local::{ - Storage, + DefaultHasher, Storage, arena::{ArenaKey, Sp, TypedArenaKey}, db::{DB, ParityDb, paritydb::OwnedDb}, storage::{default_storage, set_default_storage}, @@ -166,7 +164,6 @@ pub struct Bridge, D: DB> { impl + std::fmt::Debug, D: DB> Bridge where mn_ledger_local::structure::Transaction: Tagged, - D::Hasher: OutputSizeUser, { pub fn set_default_storage(mut externalities: &mut dyn Externalities) { let maybe_storage = externalities.extension::(); @@ -175,7 +172,7 @@ where LedgerStorageDb::UnifiedDb(db) => { let res = set_default_storage(|| { let db = - ParityDb::::from_existing_db(OwnedDb(db.clone())); + ParityDb::::from_existing_db(OwnedDb(db.clone())); Storage::new(storage.cache_size, db) }); if res.is_err() { @@ -187,7 +184,7 @@ where }, LedgerStorageDb::SeparateDb(db_path) => { let res = set_default_storage(|| { - let db = ParityDb::::open(db_path.as_path()); + let db = ParityDb::::open(db_path.as_path()); Storage::new(storage.0.cache_size, db) }); if res.is_err() { @@ -941,8 +938,14 @@ where VerifiedTransaction: Send + Sync + 'static, { let state_hash = ledger.state.state_hash(); - let strict_key = - StrictTxValidationKey { state_hash: state_hash.0.into(), tx_hash: tx_hash.0 }; + let strict_key = StrictTxValidationKey { + // The hasher output is `GenericArray` (digest 0.10, used by L7/L9) or hybrid-array + // `Array` (digest 0.11, used by L8's git-8.2 storage-core). Both deref to `[u8]`, so + // go via the slice rather than a version-specific `OutputSize = U32` type bound. + state_hash: <[u8; 32]>::try_from(&state_hash.0[..]) + .expect("persistent state hash must be 32 bytes"), + tx_hash: tx_hash.0, + }; // Check strict cache if let Some(cached) = STRICT_TX_VALIDATION_CACHE.get(&strict_key) { @@ -1063,8 +1066,14 @@ where // Check strict cache to determine if this is a cache hit let state_hash = ledger.state.state_hash(); - let strict_key = - StrictTxValidationKey { state_hash: state_hash.0.into(), tx_hash: tx_hash.0 }; + let strict_key = StrictTxValidationKey { + // The hasher output is `GenericArray` (digest 0.10, used by L7/L9) or hybrid-array + // `Array` (digest 0.11, used by L8's git-8.2 storage-core). Both deref to `[u8]`, so + // go via the slice rather than a version-specific `OutputSize = U32` type bound. + state_hash: <[u8; 32]>::try_from(&state_hash.0[..]) + .expect("persistent state hash must be 32 bytes"), + tx_hash: tx_hash.0, + }; let was_cached = STRICT_TX_VALIDATION_CACHE.get(&strict_key).is_some(); let verified_tx = Self::get_verified_transaction(ledger, tx, block_context, tx_hash)?; diff --git a/ledger/src/versions/common/storage.rs b/ledger/src/versions/common/storage.rs index ef39ea8d9..e751343b2 100644 --- a/ledger/src/versions/common/storage.rs +++ b/ledger/src/versions/common/storage.rs @@ -15,6 +15,7 @@ use midnight_primitives_ledger::LedgerStorageExt; use super::LOG_TARGET; use super::ledger_storage_local::{ + DefaultHasher, db::{ParityDb, paritydb::OwnedDb}, storage::{try_get_default_storage, unsafe_drop_default_storage}, }; @@ -24,7 +25,7 @@ use super::ledger_storage_local::{ // (column offset 0) for `Separate`, or column offset = NUM_COLUMNS_POLKADOT // for `Unified`. Drop whichever exists. type DbSeparate = ParityDb; -type DbUnified = ParityDb; +type DbUnified = ParityDb; pub fn drop_default_storage_if_exists() { if try_get_default_storage::().is_some() { @@ -74,6 +75,18 @@ impl core::fmt::Display for GetRootError { } } +/// The `LedgerState` serialization tag for this ledger version, e.g. +/// `ledger-state[v13]` (ledgers 7 and 8 - they share a wire format) or +/// `ledger-state[v18]` (ledger 9). A tagged genesis blob carries this +/// verbatim, so it lets the bootstrap pick the right deserializer before +/// touching the body (see [`crate::genesis_version`]). +#[cfg(feature = "std")] +pub fn genesis_ledger_state_tag() -> std::borrow::Cow<'static, str> { + use super::ledger_storage_local::DefaultDB; + use super::midnight_serialize_local::Tagged; + as Tagged>::tag() +} + pub fn get_root(state: &[u8], network_id: Option<&str>) -> Result, GetRootError> { // Get empty state key use super::api::Ledger; @@ -128,7 +141,7 @@ pub fn init_storage_paritydb_separate>( std::fs::create_dir_all(dir.as_ref()) .unwrap_or_else(|_| panic!("Failed to create dir {}", dir.as_ref().display())); - let db = ParityDb::::open(dir.as_ref()); + let db = ParityDb::::open(dir.as_ref()); Storage::new(cache_size, db) }); if res.is_err() { @@ -159,14 +172,14 @@ pub fn init_storage_paritydb_unified< use super::ledger_storage_local::{Storage, db::ParityDb, storage::set_default_storage}; let res = set_default_storage(|| { - let db = ParityDb::::from_existing_db(db_instance); + let db = ParityDb::::from_existing_db(db_instance); Storage::new(cache_size, db) }); if res.is_err() { log::warn!("Warning: Failed to set default storage: {res:?}"); } - alloc_with_initial_state::>( + alloc_with_initial_state::>( genesis_state, ) } diff --git a/ledger/src/versions/guaranteed_validation/ledger_8.rs b/ledger/src/versions/guaranteed_validation/ledger_8.rs index 122b17b3b..16bd53d1f 100644 --- a/ledger/src/versions/guaranteed_validation/ledger_8.rs +++ b/ledger/src/versions/guaranteed_validation/ledger_8.rs @@ -13,8 +13,10 @@ //! Ledger-8 dry-run validation of the guaranteed transaction segment. //! -//! Ledger 8 has no `apply_guaranteed_only`; fall back to a full `apply()` dry-run -//! and treat `PartialSuccess` as acceptable (guaranteed segment succeeded). +//! Uses ledger 8.2's split-phase `apply_guaranteed_only` API so validation does +//! not execute the fallible segment - acceptance depends only on the guaranteed +//! segment, and mempool/pre-dispatch checks must not pay (or fail on) fallible +//! work. #![cfg(feature = "std")] @@ -22,7 +24,7 @@ use super::{ ledger_storage_local::db::DB, mn_ledger_local::{ error::TransactionInvalid, - semantics::{TransactionContext, TransactionResult}, + semantics::TransactionContext, structure::{LedgerState, VerifiedTransaction}, }, }; @@ -32,9 +34,5 @@ pub fn validate_guaranteed_execution( verified_tx: VerifiedTransaction, ctx: &TransactionContext, ) -> Result<(), TransactionInvalid> { - let (_next_state, result) = state.apply(&verified_tx, ctx); - match result { - TransactionResult::Success(_) | TransactionResult::PartialSuccess(_, _) => Ok(()), - TransactionResult::Failure(reason) => Err(reason), - } + state.apply_guaranteed_only(verified_tx, ctx).map(|_| ()) } diff --git a/node/src/backend/custom_parity_db.rs b/node/src/backend/custom_parity_db.rs index 5cd5ab729..688380d89 100644 --- a/node/src/backend/custom_parity_db.rs +++ b/node/src/backend/custom_parity_db.rs @@ -109,7 +109,7 @@ pub fn open>( match storage_config.separation { StorageSeparation::Separate => { - midnight_node_ledger::ledger_9::storage::init_storage_paritydb_separate( + midnight_node_ledger::genesis_version::init_storage_paritydb_separate( &storage_config.db_path, &storage_config.genesis_state, storage_config.cache_size, @@ -117,7 +117,7 @@ pub fn open>( Ok((OwnedDb(db), LedgerStorageDb::SeparateDb(storage_config.db_path.clone()))) }, StorageSeparation::Unified => { - midnight_node_ledger::ledger_9::storage::init_storage_paritydb_unified::< + midnight_node_ledger::genesis_version::init_storage_paritydb_unified::< _, NUM_COLUMNS_POLKADOT, >(OwnedDb(db.clone()), &storage_config.genesis_state, storage_config.cache_size); diff --git a/node/src/chain_spec/mod.rs b/node/src/chain_spec/mod.rs index 05ac37a03..71fd6ba7b 100644 --- a/node/src/chain_spec/mod.rs +++ b/node/src/chain_spec/mod.rs @@ -56,7 +56,7 @@ pub enum ChainSpecInitError { Missing(String), ParseError(String), Serialization(String), - GenesisStateError(midnight_node_ledger::ledger_9::storage::GetRootError), + GenesisStateError(String), } impl fmt::Display for ChainSpecInitError { @@ -268,7 +268,7 @@ fn genesis_config(genesis: T) -> Result`. +STARTUP_GENESIS="${STARTUP_GENESIS:-ledger9}" + +# Extra `docker run` args selecting the genesis. ledger9 is the stock dev +# genesis (no override); ledger8 points at the pinned pre-ledger-9 (v13) +# undeployed fixtures, exercising the genesis_version dispatch path. +GENESIS_ARGS=() +case "$STARTUP_GENESIS" in + ledger9) ;; + ledger8) + GENESIS_ARGS+=( + -e CHAINSPEC_GENESIS_STATE=res/genesis/genesis_state_undeployed_ledger8.mn + -e CHAINSPEC_GENESIS_BLOCK=res/genesis/genesis_block_undeployed_ledger8.mn + ) + ;; + *) + echo "❌ Unknown STARTUP_GENESIS='${STARTUP_GENESIS}' (expected ledger9 or ledger8)" + exit 1 + ;; +esac + echo "🧪 Running Startup E2E test with:" echo " NODE_IMAGE=${NODE_IMAGE}" +echo " STARTUP_GENESIS=${STARTUP_GENESIS}" # Setup working directory WORKDIR=$(mktemp -d) @@ -44,14 +68,15 @@ docker run -d --rm \ -p 9944:9944 \ -e CFG_PRESET=dev \ -e SIDECHAIN_BLOCK_BENEFICIARY="04bcf7ad3be7a5c790460be82a713af570f22e0f801f6659ab8e84a52be6969e" \ + "${GENESIS_ARGS[@]}" \ "${NODE_IMAGE}" # Smoke test: assert finality is advancing, matching the old `finalized #1` # log-grep semantics this script used to have. if wait_for_finalized_block http://localhost:9944 1 60; then - echo "✅ Node started successfully with CFG_PRESET=dev" + echo "✅ Node started successfully with CFG_PRESET=dev (${STARTUP_GENESIS})" else - echo "❌ Node failed to start with CFG_PRESET=dev" + echo "❌ Node failed to start with CFG_PRESET=dev (${STARTUP_GENESIS})" TEST_FAILED=true fi diff --git a/util/toolkit/src/remote_prover.rs b/util/toolkit/src/remote_prover.rs index 0ae3aa46b..1d9563909 100644 --- a/util/toolkit/src/remote_prover.rs +++ b/util/toolkit/src/remote_prover.rs @@ -73,7 +73,9 @@ impl ProofProvider for RemoteProofServer { } #[async_trait] -impl midnight_node_ledger_helpers::ledger_8::ProofProvider for RemoteProofServer { +impl + midnight_node_ledger_helpers::ledger_8::ProofProvider for RemoteProofServer +{ async fn prove( &self, tx: midnight_node_ledger_helpers::ledger_8::Transaction< diff --git a/util/toolkit/src/tx_generator/builder/builders/mod.rs b/util/toolkit/src/tx_generator/builder/builders/mod.rs index 59c328a1d..c9bfe8823 100644 --- a/util/toolkit/src/tx_generator/builder/builders/mod.rs +++ b/util/toolkit/src/tx_generator/builder/builders/mod.rs @@ -11,17 +11,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub mod ledger_9; -pub use ledger_9::*; - pub mod ledger_7; pub mod ledger_8; +pub mod ledger_9; +pub use ledger_9::*; // Conversion impls for encoded zswap types to ledger types. // These live here (not in common/) because common/ is compiled once per ledger // version, which would cause E0119 conflicts wherever versions share types. -// Ledger 9 uses coin-structure 3.x; ledgers 7 and 8 share coin-structure 2.x, -// so there are exactly two impl sets. +// Ledger 9 uses coin-structure 3.x; ledger 7 uses crates.io coin-structure 2.x; ledger 8 uses +// git-8.2 coin-structure 2.x (a distinct family since the 8.2 move). So there are three impl sets. use crate::toolkit_js::encoded_zswap_local_state::{ EncodedOutput, EncodedQualifiedShieldedCoinInfo, EncodedRecipient, }; @@ -30,6 +29,13 @@ use midnight_node_ledger_helpers::ledger_7::{ Nonce as NonceV2, QualifiedInfo as QualifiedInfoV2, Recipient as RecipientV2, ShieldedTokenType as ShieldedTokenTypeV2, }; +// L8's coin-structure (git-8.2) is now a distinct family from L7's (crates.io), so it needs its +// own conversion impls with its own base-crypto `HashOutput` (git-8.2 1.0.0). +use midnight_node_ledger_helpers::ledger_8::{ + CoinInfo as CoinInfoL8, CoinPublicKey as CoinPublicKeyL8, ContractAddress as ContractAddressL8, + HashOutput as HashOutputL8, Nonce as NonceL8, QualifiedInfo as QualifiedInfoL8, + Recipient as RecipientL8, ShieldedTokenType as ShieldedTokenTypeL8, +}; use midnight_node_ledger_helpers::ledger_9::{ CoinInfo, CoinPublicKey, ContractAddress, HashOutput, Nonce, QualifiedInfo, Recipient, ShieldedTokenType, @@ -39,14 +45,14 @@ use midnight_node_ledger_helpers::ledger_9::{ // coin-structure 2.x and 3.x (the same invariant type_convert.rs relies on), // so conversion is direct byte reconstruction. macro_rules! impl_encoded_zswap_conversions { - ($Recipient:ident, $CoinPublicKey:ident, $ContractAddress:ident, + ($HashOutput:ident, $Recipient:ident, $CoinPublicKey:ident, $ContractAddress:ident, $CoinInfo:ident, $Nonce:ident, $ShieldedTokenType:ident, $QualifiedInfo:ident) => { impl From<&EncodedRecipient> for $Recipient { fn from(value: &EncodedRecipient) -> Self { if value.is_left { - $Recipient::User($CoinPublicKey(HashOutput(value.left.0.0.0))) + $Recipient::User($CoinPublicKey($HashOutput(value.left.0.0.0))) } else { - $Recipient::Contract($ContractAddress(HashOutput(value.right.0.0.0))) + $Recipient::Contract($ContractAddress($HashOutput(value.right.0.0.0))) } } } @@ -54,8 +60,8 @@ macro_rules! impl_encoded_zswap_conversions { impl From<&EncodedOutput> for $CoinInfo { fn from(value: &EncodedOutput) -> Self { $CoinInfo { - nonce: $Nonce(HashOutput(value.coin_info.nonce)), - type_: $ShieldedTokenType(HashOutput(value.coin_info.color)), + nonce: $Nonce($HashOutput(value.coin_info.nonce)), + type_: $ShieldedTokenType($HashOutput(value.coin_info.color)), value: value.coin_info.value, } } @@ -64,8 +70,8 @@ macro_rules! impl_encoded_zswap_conversions { impl From<&EncodedQualifiedShieldedCoinInfo> for $CoinInfo { fn from(value: &EncodedQualifiedShieldedCoinInfo) -> Self { $CoinInfo { - nonce: $Nonce(HashOutput(value.nonce)), - type_: $ShieldedTokenType(HashOutput(value.color)), + nonce: $Nonce($HashOutput(value.nonce)), + type_: $ShieldedTokenType($HashOutput(value.color)), value: value.value, } } @@ -79,7 +85,9 @@ macro_rules! impl_encoded_zswap_conversions { }; } +// L7 shares base-crypto (1.1.0) with L9, so both use L9's `HashOutput`. impl_encoded_zswap_conversions!( + HashOutput, RecipientV2, CoinPublicKeyV2, ContractAddressV2, @@ -89,6 +97,7 @@ impl_encoded_zswap_conversions!( QualifiedInfoV2 ); impl_encoded_zswap_conversions!( + HashOutput, Recipient, CoinPublicKey, ContractAddress, @@ -97,3 +106,14 @@ impl_encoded_zswap_conversions!( ShieldedTokenType, QualifiedInfo ); +// L8 (git-8.2) uses its own base-crypto `HashOutput` (1.0.0). +impl_encoded_zswap_conversions!( + HashOutputL8, + RecipientL8, + CoinPublicKeyL8, + ContractAddressL8, + CoinInfoL8, + NonceL8, + ShieldedTokenTypeL8, + QualifiedInfoL8 +);