diff --git a/.github/workflows/cd-deploy-nodes-gcp.yml b/.github/workflows/cd-deploy-nodes-gcp.yml index eb60526214c..d652606ec96 100644 --- a/.github/workflows/cd-deploy-nodes-gcp.yml +++ b/.github/workflows/cd-deploy-nodes-gcp.yml @@ -228,14 +228,13 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.3 + uses: google-github-actions/auth@v2.1.4 with: - retries: '3' workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' - name: Set up Cloud SDK - uses: google-github-actions/setup-gcloud@v2.1.0 + uses: google-github-actions/setup-gcloud@v2.1.1 # TODO we should implement the fixes from https://github.com/ZcashFoundation/zebra/pull/5670 here # but the implementation is failing as it's requiring the disk names, contrary to what is stated in the official documentation @@ -330,14 +329,13 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.3 + uses: google-github-actions/auth@v2.1.4 with: - retries: '3' workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' - name: Set up Cloud SDK - uses: google-github-actions/setup-gcloud@v2.1.0 + uses: google-github-actions/setup-gcloud@v2.1.1 # Create instance template from container image - name: Manual deploy of a single ${{ inputs.network }} instance running zebrad diff --git a/.github/workflows/chore-delete-gcp-resources.yml b/.github/workflows/chore-delete-gcp-resources.yml index f6e0ba3cf21..15ce55e266c 100644 --- a/.github/workflows/chore-delete-gcp-resources.yml +++ b/.github/workflows/chore-delete-gcp-resources.yml @@ -46,14 +46,13 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.3 + uses: google-github-actions/auth@v2.1.4 with: - retries: '3' workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' - name: Set up Cloud SDK - uses: google-github-actions/setup-gcloud@v2.1.0 + uses: google-github-actions/setup-gcloud@v2.1.1 # Deletes all mainnet and testnet instances older than $DELETE_INSTANCE_DAYS days. # @@ -114,9 +113,8 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.3 + uses: google-github-actions/auth@v2.1.4 with: - retries: '3' workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' token_format: 'access_token' diff --git a/.github/workflows/ci-unit-tests-os.yml b/.github/workflows/ci-unit-tests-os.yml index 375ecc686b0..34bb57da2cd 100644 --- a/.github/workflows/ci-unit-tests-os.yml +++ b/.github/workflows/ci-unit-tests-os.yml @@ -254,7 +254,7 @@ jobs: - uses: r7kamura/rust-problem-matchers@v1.5.0 - name: Check ${{ matrix.checks }} with features ${{ matrix.features }} - uses: EmbarkStudios/cargo-deny-action@v1 + uses: EmbarkStudios/cargo-deny-action@v2 with: # --all-features spuriously activates openssl, but we want to ban that dependency in # all of zebrad's production features for security reasons. But the --all-features job is diff --git a/.github/workflows/docs-deploy-firebase.yml b/.github/workflows/docs-deploy-firebase.yml index 0785539be99..6e65364b733 100644 --- a/.github/workflows/docs-deploy-firebase.yml +++ b/.github/workflows/docs-deploy-firebase.yml @@ -106,9 +106,8 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.3 + uses: google-github-actions/auth@v2.1.4 with: - retries: '3' workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_FIREBASE_SA }}' @@ -165,9 +164,8 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.3 + uses: google-github-actions/auth@v2.1.4 with: - retries: '3' workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_FIREBASE_SA }}' diff --git a/.github/workflows/manual-zcashd-deploy.yml b/.github/workflows/manual-zcashd-deploy.yml index 2860d297248..7a8b218dc0a 100644 --- a/.github/workflows/manual-zcashd-deploy.yml +++ b/.github/workflows/manual-zcashd-deploy.yml @@ -52,14 +52,13 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.3 + uses: google-github-actions/auth@v2.1.4 with: - retries: '3' workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' - name: Set up Cloud SDK - uses: google-github-actions/setup-gcloud@v2.1.0 + uses: google-github-actions/setup-gcloud@v2.1.1 # Create instance template from container image - name: Create instance template diff --git a/.github/workflows/sub-build-docker-image.yml b/.github/workflows/sub-build-docker-image.yml index eafd488b8a6..ee0bbcc3bbb 100644 --- a/.github/workflows/sub-build-docker-image.yml +++ b/.github/workflows/sub-build-docker-image.yml @@ -75,6 +75,8 @@ jobs: permissions: contents: 'read' id-token: 'write' + env: + DOCKER_BUILD_SUMMARY: ${{ vars.DOCKER_BUILD_SUMMARY }} steps: - uses: actions/checkout@v4.1.7 with: @@ -122,9 +124,8 @@ jobs: - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.3 + uses: google-github-actions/auth@v2.1.4 with: - retries: '3' workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_ARTIFACTS_SA }}' token_format: 'access_token' @@ -158,7 +159,7 @@ jobs: # Build and push image to Google Artifact Registry, and possibly DockerHub - name: Build & push id: docker_build - uses: docker/build-push-action@v6.5.0 + uses: docker/build-push-action@v6.6.0 with: target: ${{ inputs.dockerfile_target }} context: . diff --git a/.github/workflows/sub-deploy-integration-tests-gcp.yml b/.github/workflows/sub-deploy-integration-tests-gcp.yml index b508b7ab951..f6f5c666c5d 100644 --- a/.github/workflows/sub-deploy-integration-tests-gcp.yml +++ b/.github/workflows/sub-deploy-integration-tests-gcp.yml @@ -150,14 +150,13 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.3 + uses: google-github-actions/auth@v2.1.4 with: - retries: '3' workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' - name: Set up Cloud SDK - uses: google-github-actions/setup-gcloud@v2.1.0 + uses: google-github-actions/setup-gcloud@v2.1.1 # Find a cached state disk for this job, matching all of: # - disk cached state (lwd_state_dir/zebra_state_dir or disk_prefix) - zebrad-cache or lwd-cache @@ -450,13 +449,13 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.3 + uses: google-github-actions/auth@v2.1.4 with: workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' - name: Set up Cloud SDK - uses: google-github-actions/setup-gcloud@v2.1.0 + uses: google-github-actions/setup-gcloud@v2.1.1 # Get the state version from the local constants.rs file to be used in the image creation, # as the state version is part of the disk image name. @@ -727,13 +726,13 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.3 + uses: google-github-actions/auth@v2.1.4 with: workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' - name: Set up Cloud SDK - uses: google-github-actions/setup-gcloud@v2.1.0 + uses: google-github-actions/setup-gcloud@v2.1.1 # Deletes the instances that has been recently deployed in the actual commit after all # previous jobs have run, no matter the outcome of the job. diff --git a/.github/workflows/sub-find-cached-disks.yml b/.github/workflows/sub-find-cached-disks.yml index d151af439b8..f7c57db1731 100644 --- a/.github/workflows/sub-find-cached-disks.yml +++ b/.github/workflows/sub-find-cached-disks.yml @@ -45,14 +45,13 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.3 + uses: google-github-actions/auth@v2.1.4 with: - retries: '3' workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' - name: Set up Cloud SDK - uses: google-github-actions/setup-gcloud@v2.1.0 + uses: google-github-actions/setup-gcloud@v2.1.1 # Disk images in GCP are required to be in lowercase, but the blockchain network # uses sentence case, so we need to downcase ${{ inputs.network }} diff --git a/Cargo.lock b/Cargo.lock index 40ad10a00d2..93940089a86 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,7 +12,7 @@ dependencies = [ "arc-swap", "backtrace", "canonical-path", - "clap 4.5.11", + "clap 4.5.13", "color-eyre", "fs-err", "once_cell", @@ -442,6 +442,22 @@ dependencies = [ "zeroize", ] +[[package]] +name = "bip32" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa13fae8b6255872fd86f7faf4b41168661d7d78609f7bfe6771b85c6739a15b" +dependencies = [ + "bs58", + "hmac", + "rand_core 0.6.4", + "ripemd", + "secp256k1 0.27.0", + "sha2", + "subtle", + "zeroize", +] + [[package]] name = "bit-set" version = "0.5.3" @@ -590,9 +606,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.1" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "bzip2-sys" @@ -793,9 +809,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.11" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3" +checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" dependencies = [ "clap_builder", "clap_derive", @@ -803,9 +819,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.11" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa" +checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" dependencies = [ "anstream", "anstyle", @@ -815,9 +831,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.11" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -972,7 +988,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.5.11", + "clap 4.5.13", "criterion-plot", "is-terminal", "itertools 0.10.5", @@ -1312,6 +1328,15 @@ dependencies = [ "byteorder", ] +[[package]] +name = "equihash" +version = "0.2.0" +source = "git+https://github.com/zcash/librustzcash/?branch=main#5a4a3e06dcd2cf5bdf79a7cd48709b58693c65f0" +dependencies = [ + "blake2b_simd", + "byteorder", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -1347,6 +1372,14 @@ dependencies = [ "blake2b_simd", ] +[[package]] +name = "f4jumble" +version = "0.1.0" +source = "git+https://github.com/zcash/librustzcash/?branch=main#5a4a3e06dcd2cf5bdf79a7cd48709b58693c65f0" +dependencies = [ + "blake2b_simd", +] + [[package]] name = "fastrand" version = "2.1.0" @@ -1408,7 +1441,7 @@ dependencies = [ "futures-sink", "nanorand", "pin-project", - "spin 0.9.8", + "spin", ] [[package]] @@ -1640,7 +1673,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.2.6", + "indexmap 2.3.0", "slab", "tokio", "tokio-util 0.7.11", @@ -1659,7 +1692,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.2.6", + "indexmap 2.3.0", "slab", "tokio", "tokio-util 0.7.11", @@ -1745,19 +1778,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "hdwallet" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a03ba7d4c9ea41552cd4351965ff96883e629693ae85005c501bb4b9e1c48a7" -dependencies = [ - "lazy_static", - "rand_core 0.6.4", - "ring 0.16.20", - "secp256k1", - "thiserror", -] - [[package]] name = "heck" version = "0.3.3" @@ -2112,9 +2132,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -2136,9 +2156,9 @@ dependencies = [ [[package]] name = "inferno" -version = "0.11.20" +version = "0.11.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c77a3ae7d4761b9c64d2c030f70746ceb8cfba32dce0325a56792e0a4816c31" +checksum = "232929e1d75fe899576a3d5c7416ad0d88dbfbb3c3d6aa00873a7408a50ddb88" dependencies = [ "ahash", "is-terminal", @@ -2360,7 +2380,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin 0.9.8", + "spin", ] [[package]] @@ -2544,7 +2564,7 @@ dependencies = [ "http-body-util", "hyper 1.4.1", "hyper-util", - "indexmap 2.2.6", + "indexmap 2.3.0", "ipnet", "metrics", "metrics-util", @@ -3009,7 +3029,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.2.6", + "indexmap 2.3.0", ] [[package]] @@ -3565,9 +3585,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", @@ -3659,21 +3679,6 @@ dependencies = [ "bytemuck", ] -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted 0.7.1", - "web-sys", - "winapi", -] - [[package]] name = "ring" version = "0.17.8" @@ -3684,8 +3689,8 @@ dependencies = [ "cfg-if 1.0.0", "getrandom 0.2.15", "libc", - "spin 0.9.8", - "untrusted 0.9.0", + "spin", + "untrusted", "windows-sys 0.52.0", ] @@ -3784,7 +3789,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", - "ring 0.17.8", + "ring", "rustls-webpki", "sct", ] @@ -3804,8 +3809,8 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", + "ring", + "untrusted", ] [[package]] @@ -3885,8 +3890,8 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", + "ring", + "untrusted", ] [[package]] @@ -3899,6 +3904,15 @@ dependencies = [ "serde", ] +[[package]] +name = "secp256k1" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" +dependencies = [ + "secp256k1-sys", +] + [[package]] name = "secp256k1-sys" version = "0.8.1" @@ -4059,11 +4073,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.121" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" +checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.3.0", "itoa", "memchr", "ryu", @@ -4111,7 +4125,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.2.6", + "indexmap 2.3.0", "serde", "serde_derive", "serde_json", @@ -4149,7 +4163,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.3.0", "itoa", "ryu", "serde", @@ -4271,12 +4285,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" @@ -4431,12 +4439,13 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.10.1" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53" dependencies = [ "cfg-if 1.0.0", "fastrand", + "once_cell", "rustix", "windows-sys 0.52.0", ] @@ -4664,21 +4673,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.16" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81967dd0dd2c1ab0bc3468bd7caecc32b8a4aa47d0c8c695d8c2b2108168d62c" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.17", + "toml_edit 0.22.20", ] [[package]] name = "toml_datetime" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] @@ -4689,22 +4698,22 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.3.0", "toml_datetime", "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.22.17" +version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9f8729f5aea9562aac1cc0441f5d6de3cff1ee0c5d67293eeca5eb36ee7c16" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.3.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.13", + "winnow 0.6.18", ] [[package]] @@ -5115,12 +5124,6 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "untrusted" version = "0.9.0" @@ -5599,9 +5602,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.13" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] @@ -5651,9 +5654,21 @@ checksum = "827c17a1f7e3a69f0d44e991ff610c7a842228afdc9dc2325ffdd1a67fee01e9" dependencies = [ "bech32", "bs58", - "f4jumble", - "zcash_encoding", - "zcash_protocol", + "f4jumble 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "zcash_address" +version = "0.3.2" +source = "git+https://github.com/zcash/librustzcash/?branch=main#5a4a3e06dcd2cf5bdf79a7cd48709b58693c65f0" +dependencies = [ + "bech32", + "bs58", + "f4jumble 0.1.0 (git+https://github.com/zcash/librustzcash/?branch=main)", + "zcash_encoding 0.2.0 (git+https://github.com/zcash/librustzcash/?branch=main)", + "zcash_protocol 0.1.1 (git+https://github.com/zcash/librustzcash/?branch=main)", ] [[package]] @@ -5686,12 +5701,12 @@ dependencies = [ "tonic-build 0.10.2", "tracing", "which", - "zcash_address", - "zcash_encoding", + "zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "zcash_keys", "zcash_note_encryption", - "zcash_primitives", - "zcash_protocol", + "zcash_primitives 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "zip32", ] @@ -5705,6 +5720,15 @@ dependencies = [ "nonempty", ] +[[package]] +name = "zcash_encoding" +version = "0.2.0" +source = "git+https://github.com/zcash/librustzcash/?branch=main#5a4a3e06dcd2cf5bdf79a7cd48709b58693c65f0" +dependencies = [ + "byteorder", + "nonempty", +] + [[package]] name = "zcash_history" version = "0.4.0" @@ -5735,10 +5759,10 @@ dependencies = [ "secrecy", "subtle", "tracing", - "zcash_address", - "zcash_encoding", - "zcash_primitives", - "zcash_protocol", + "zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_primitives 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "zip32", ] @@ -5766,11 +5790,46 @@ dependencies = [ "blake2b_simd", "byteorder", "document-features", - "equihash", + "equihash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ff", + "fpe", + "group", + "hex", + "incrementalmerkletree", + "jubjub", + "memuse", + "nonempty", + "orchard", + "rand 0.8.5", + "rand_core 0.6.4", + "redjubjub", + "sapling-crypto", + "sha2", + "subtle", + "tracing", + "zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_note_encryption", + "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_spec", + "zip32", +] + +[[package]] +name = "zcash_primitives" +version = "0.15.1" +source = "git+https://github.com/zcash/librustzcash/?branch=main#5a4a3e06dcd2cf5bdf79a7cd48709b58693c65f0" +dependencies = [ + "aes", + "bip32", + "blake2b_simd", + "bs58", + "byteorder", + "document-features", + "equihash 0.2.0 (git+https://github.com/zcash/librustzcash/?branch=main)", "ff", "fpe", "group", - "hdwallet", "hex", "incrementalmerkletree", "jubjub", @@ -5782,14 +5841,14 @@ dependencies = [ "redjubjub", "ripemd", "sapling-crypto", - "secp256k1", + "secp256k1 0.27.0", "sha2", "subtle", "tracing", - "zcash_address", - "zcash_encoding", + "zcash_address 0.3.2 (git+https://github.com/zcash/librustzcash/?branch=main)", + "zcash_encoding 0.2.0 (git+https://github.com/zcash/librustzcash/?branch=main)", "zcash_note_encryption", - "zcash_protocol", + "zcash_protocol 0.1.1 (git+https://github.com/zcash/librustzcash/?branch=main)", "zcash_spec", "zip32", ] @@ -5814,7 +5873,7 @@ dependencies = [ "sapling-crypto", "tracing", "xdg", - "zcash_primitives", + "zcash_primitives 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5827,6 +5886,15 @@ dependencies = [ "memuse", ] +[[package]] +name = "zcash_protocol" +version = "0.1.1" +source = "git+https://github.com/zcash/librustzcash/?branch=main#5a4a3e06dcd2cf5bdf79a7cd48709b58693c65f0" +dependencies = [ + "document-features", + "memuse", +] + [[package]] name = "zcash_script" version = "0.3.0" @@ -5861,7 +5929,7 @@ dependencies = [ "color-eyre", "criterion", "ed25519-zebra", - "equihash", + "equihash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures", "group", "halo2_proofs", @@ -5884,7 +5952,7 @@ dependencies = [ "redjubjub", "ripemd", "sapling-crypto", - "secp256k1", + "secp256k1 0.26.0", "serde", "serde-big-array", "serde_json", @@ -5898,13 +5966,13 @@ dependencies = [ "tracing", "uint", "x25519-dalek", - "zcash_address", + "zcash_address 0.3.2 (git+https://github.com/zcash/librustzcash/?branch=main)", "zcash_client_backend", - "zcash_encoding", + "zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "zcash_history", "zcash_note_encryption", - "zcash_primitives", - "zcash_protocol", + "zcash_primitives 0.15.1 (git+https://github.com/zcash/librustzcash/?branch=main)", + "zcash_protocol 0.1.1 (git+https://github.com/zcash/librustzcash/?branch=main)", "zebra-test", ] @@ -5969,7 +6037,7 @@ dependencies = [ "tonic-build 0.12.1", "tonic-reflection", "tower", - "zcash_primitives", + "zcash_primitives 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "zebra-chain", "zebra-node-services", "zebra-state", @@ -5989,7 +6057,7 @@ dependencies = [ "hex", "howudoin", "humantime-serde", - "indexmap 2.2.6", + "indexmap 2.3.0", "itertools 0.13.0", "lazy_static", "metrics", @@ -6008,7 +6076,7 @@ dependencies = [ "tokio", "tokio-stream", "tokio-util 0.7.11", - "toml 0.8.16", + "toml 0.8.19", "tower", "tracing", "tracing-error", @@ -6037,7 +6105,7 @@ dependencies = [ "chrono", "futures", "hex", - "indexmap 2.2.6", + "indexmap 2.3.0", "insta", "jsonrpc-core", "jsonrpc-derive", @@ -6055,8 +6123,8 @@ dependencies = [ "tonic-reflection", "tower", "tracing", - "zcash_address", - "zcash_primitives", + "zcash_address 0.3.2 (git+https://github.com/zcash/librustzcash/?branch=main)", + "zcash_primitives 0.15.1 (git+https://github.com/zcash/librustzcash/?branch=main)", "zebra-chain", "zebra-consensus", "zebra-network", @@ -6077,7 +6145,7 @@ dependencies = [ "futures", "group", "hex", - "indexmap 2.2.6", + "indexmap 2.3.0", "insta", "itertools 0.13.0", "jsonrpc", @@ -6093,16 +6161,16 @@ dependencies = [ "structopt", "tempfile", "tokio", - "toml 0.8.16", + "toml 0.8.19", "tonic", "tower", "tracing", "tracing-subscriber", - "zcash_address", + "zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "zcash_client_backend", "zcash_keys", "zcash_note_encryption", - "zcash_primitives", + "zcash_primitives 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "zebra-chain", "zebra-grpc", "zebra-node-services", @@ -6140,7 +6208,7 @@ dependencies = [ "howudoin", "human_bytes", "humantime-serde", - "indexmap 2.2.6", + "indexmap 2.3.0", "insta", "itertools 0.13.0", "jubjub", @@ -6177,7 +6245,7 @@ dependencies = [ "futures", "hex", "humantime", - "indexmap 2.2.6", + "indexmap 2.3.0", "insta", "itertools 0.13.0", "lazy_static", @@ -6220,8 +6288,8 @@ dependencies = [ "tracing-error", "tracing-subscriber", "zcash_client_backend", - "zcash_primitives", - "zcash_protocol", + "zcash_primitives 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "zebra-chain", "zebra-node-services", "zebra-rpc", @@ -6235,7 +6303,7 @@ dependencies = [ "atty", "bytes", "chrono", - "clap 4.5.11", + "clap 4.5.13", "color-eyre", "console-subscriber", "dirs", @@ -6247,7 +6315,7 @@ dependencies = [ "humantime-serde", "hyper 1.4.1", "hyper-util", - "indexmap 2.2.6", + "indexmap 2.3.0", "indicatif", "inferno", "insta", @@ -6275,7 +6343,7 @@ dependencies = [ "tinyvec", "tokio", "tokio-stream", - "toml 0.8.16", + "toml 0.8.19", "tonic", "tonic-build 0.12.1", "tower", diff --git a/deny.toml b/deny.toml index 2f5640a3f7c..d599e693636 100644 --- a/deny.toml +++ b/deny.toml @@ -12,7 +12,8 @@ multiple-versions = "deny" # Don't allow wildcard ("any version") dependencies -wildcards = "deny" +# TODO: Change to `deny` after we upgrade to crates.io version of the ECC dependencies (#8749). +wildcards = "allow" # Allow private and dev wildcard dependencies. # Switch this to `false` when #6924 is implemented. allow-wildcard-paths = true @@ -92,6 +93,15 @@ skip-tree = [ { name = "http", version = "=0.2.12" }, { name = "http-body", version = "=0.4.6" }, { name = "hyper", version = "=0.14.30" }, + + # TODO: Remove this after we upgrade ECC dependencies to a crates.io version (#8749) + { name = "equihash", version = "=0.2.0" }, + { name = "f4jumble", version = "=0.1.0" }, + { name = "secp256k1", version = "=0.26.0" }, + { name = "zcash_address", version = "=0.3.2" }, + { name = "zcash_encoding", version = "=0.2.0" }, + { name = "zcash_primitives", version = "=0.15.1" }, + { name = "zcash_protocol", version = "=0.1.1" }, ] # This section is considered when running `cargo deny check sources`. @@ -109,6 +119,7 @@ unknown-git = "deny" allow-registry = ["https://github.com/rust-lang/crates.io-index"] # List of URLs for allowed Git repositories allow-git = [ + "https://github.com/zcash/librustzcash.git" ] [sources.allow-org] diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml index cdde057433b..fd2e76233c1 100644 --- a/supply-chain/audits.toml +++ b/supply-chain/audits.toml @@ -16,6 +16,11 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "1.6.0 -> 1.6.1" +[[audits.bytes]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.6.1 -> 1.7.1" + [[audits.clap_derive]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -76,11 +81,21 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "1.3.1 -> 1.4.1" +[[audits.indexmap]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "2.2.6 -> 2.3.0" + [[audits.inferno]] who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.11.19 -> 0.11.20" +[[audits.inferno]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.11.20 -> 0.11.21" + [[audits.libgit2-sys]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -141,6 +156,11 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.12.6 -> 0.13.1" +[[audits.regex]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.10.5 -> 1.10.6" + [[audits.serde_spanned]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -166,6 +186,11 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "3.8.3 -> 3.9.0" +[[audits.tempfile]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "3.10.1 -> 3.11.0" + [[audits.thiserror]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -201,11 +226,21 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.8.15 -> 0.8.16" +[[audits.toml]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.8.16 -> 0.8.19" + [[audits.toml_datetime]] who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.6.6 -> 0.6.7" +[[audits.toml_datetime]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.6.7 -> 0.6.8" + [[audits.toml_edit]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -216,6 +251,11 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.22.16 -> 0.22.17" +[[audits.toml_edit]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.22.17 -> 0.22.20" + [[audits.tonic]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -236,6 +276,11 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "8.3.1 -> 8.3.2" +[[audits.winnow]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.6.13 -> 0.6.18" + [[trusted.clap]] criteria = "safe-to-deploy" user-id = 6743 # Ed Page (epage) diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index 9642265eca1..b9dd505d67b 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -9,22 +9,22 @@ user-login = "emilio" user-name = "Emilio Cobos Álvarez" [[publisher.clap]] -version = "4.5.11" -when = "2024-07-25" +version = "4.5.13" +when = "2024-07-31" user-id = 6743 user-login = "epage" user-name = "Ed Page" [[publisher.clap_builder]] -version = "4.5.11" -when = "2024-07-25" +version = "4.5.13" +when = "2024-07-31" user-id = 6743 user-login = "epage" user-name = "Ed Page" [[publisher.clap_derive]] -version = "4.5.11" -when = "2024-07-25" +version = "4.5.13" +when = "2024-07-31" user-id = 6743 user-login = "epage" user-name = "Ed Page" @@ -44,8 +44,8 @@ user-login = "hsivonen" user-name = "Henri Sivonen" [[publisher.serde_json]] -version = "1.0.121" -when = "2024-07-28" +version = "1.0.122" +when = "2024-08-01" user-id = 3618 user-login = "dtolnay" user-name = "David Tolnay" diff --git a/zebra-chain/Cargo.toml b/zebra-chain/Cargo.toml index ae3c9fec21e..f6113ee6e4e 100644 --- a/zebra-chain/Cargo.toml +++ b/zebra-chain/Cargo.toml @@ -97,10 +97,13 @@ orchard = "0.8.0" zcash_encoding = "0.2.0" zcash_history = "0.4.0" zcash_note_encryption = "0.4.0" -zcash_primitives = { version = "0.15.0", features = ["transparent-inputs"] } +# TODO: Revert to a release once librustzcash is released (#8749). +zcash_primitives = { git = "https://github.com/zcash/librustzcash/", branch = "main", features = ["transparent-inputs"] } sapling = { package = "sapling-crypto", version = "0.1" } -zcash_protocol = { version = "0.1.1" } -zcash_address = { version = "0.3.2" } +# TODO: Revert to a release once librustzcash is released (#8749). +zcash_protocol = { git = "https://github.com/zcash/librustzcash/", branch = "main"} +# TODO: Revert to a release once librustzcash is released (#8749). +zcash_address = { git = "https://github.com/zcash/librustzcash/", branch = "main"} # Time chrono = { version = "0.4.38", default-features = false, features = ["clock", "std", "serde"] } @@ -128,7 +131,7 @@ redjubjub = "0.7.0" reddsa = "0.5.1" # Production feature json-conversion -serde_json = { version = "1.0.121", optional = true } +serde_json = { version = "1.0.122", optional = true } # Production feature async-error and testing feature proptest-impl tokio = { version = "1.39.2", optional = true } @@ -176,7 +179,3 @@ required-features = ["bench"] [[bench]] name = "redpallas" harness = false - -[lints.rust] -# TODO: Remove this once it's no longer needed for NU6. -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(zcash_unstable, values("nu6"))'] } diff --git a/zebra-chain/src/parameters/network_upgrade.rs b/zebra-chain/src/parameters/network_upgrade.rs index 121a5bdcf13..73c027877c9 100644 --- a/zebra-chain/src/parameters/network_upgrade.rs +++ b/zebra-chain/src/parameters/network_upgrade.rs @@ -531,7 +531,6 @@ impl From for NetworkUpgrade { zcash_protocol::consensus::NetworkUpgrade::Heartwood => Self::Heartwood, zcash_protocol::consensus::NetworkUpgrade::Canopy => Self::Canopy, zcash_protocol::consensus::NetworkUpgrade::Nu5 => Self::Nu5, - #[cfg(zcash_unstable = "nu6")] zcash_protocol::consensus::NetworkUpgrade::Nu6 => Self::Nu6, } } diff --git a/zebra-consensus/src/block.rs b/zebra-consensus/src/block.rs index b7fd6740ecc..2b0013a5a3d 100644 --- a/zebra-consensus/src/block.rs +++ b/zebra-consensus/src/block.rs @@ -302,10 +302,12 @@ where })?; check::miner_fees_are_valid( - &block, + &coinbase_tx, + height, block_miner_fees, expected_block_subsidy, expected_deferred_amount, + &network, )?; // Finally, submit the block for contextual verification. diff --git a/zebra-consensus/src/block/check.rs b/zebra-consensus/src/block/check.rs index eca45e8bc0c..189cfdc8493 100644 --- a/zebra-consensus/src/block/check.rs +++ b/zebra-consensus/src/block/check.rs @@ -8,7 +8,7 @@ use zebra_chain::{ amount::{Amount, Error as AmountError, NonNegative}, block::{Block, Hash, Header, Height}, parameters::{subsidy::FundingStreamReceiver, Network, NetworkUpgrade}, - transaction, + transaction::{self, Transaction}, work::{ difficulty::{ExpandedDifficulty, ParameterDifficulty as _}, equihash, @@ -234,22 +234,24 @@ pub fn subsidy_is_valid( /// /// [7.1.2]: https://zips.z.cash/protocol/protocol.pdf#txnconsensus pub fn miner_fees_are_valid( - block: &Block, + coinbase_tx: &Transaction, + height: Height, block_miner_fees: Amount, expected_block_subsidy: Amount, expected_deferred_amount: Amount, + network: &Network, ) -> Result<(), BlockError> { - let coinbase = block.transactions.first().ok_or(SubsidyError::NoCoinbase)?; - - let transparent_value_balance: Amount = subsidy::general::output_amounts(coinbase) + let transparent_value_balance = subsidy::general::output_amounts(coinbase_tx) .iter() .sum::, AmountError>>() .map_err(|_| SubsidyError::SumOverflow)? .constrain() .expect("positive value always fit in `NegativeAllowed`"); - let sapling_value_balance = coinbase.sapling_value_balance().sapling_amount(); - let orchard_value_balance = coinbase.orchard_value_balance().orchard_amount(); + let sapling_value_balance = coinbase_tx.sapling_value_balance().sapling_amount(); + let orchard_value_balance = coinbase_tx.orchard_value_balance().orchard_amount(); + // TODO: Update the quote below once its been updated for NU6. + // // # Consensus // // > The total value in zatoshi of transparent outputs from a coinbase transaction, @@ -260,17 +262,26 @@ pub fn miner_fees_are_valid( // // The expected lockbox funding stream output of the coinbase transaction is also subtracted // from the block subsidy value plus the transaction fees paid by transactions in this block. - // - // TODO: Update the quote from the protocol specification once its been updated to reflect the changes in - // https://zips.z.cash/draft-nuttycom-funding-allocation and https://zips.z.cash/draft-hopwood-coinbase-balance. let left = (transparent_value_balance - sapling_value_balance - orchard_value_balance) .map_err(|_| SubsidyError::SumOverflow)?; let right = (expected_block_subsidy + block_miner_fees - expected_deferred_amount) .map_err(|_| SubsidyError::SumOverflow)?; - if left > right { - Err(SubsidyError::InvalidMinerFees)?; - } + // TODO: Updadte the quotes below if the final phrasing changes in the spec for NU6. + // + // # Consensus + // + // > [Pre-NU6] The total output of a coinbase transaction MUST NOT be greater than its total + // input. + // + // > [NU6 onward] The total output of a coinbase transaction MUST be equal to its total input. + if if NetworkUpgrade::current(network, height) < NetworkUpgrade::Nu6 { + left > right + } else { + left != right + } { + Err(SubsidyError::InvalidMinerFees)? + }; Ok(()) } diff --git a/zebra-consensus/src/block/subsidy/general.rs b/zebra-consensus/src/block/subsidy/general.rs index 233f7935c1c..03ebac36d21 100644 --- a/zebra-consensus/src/block/subsidy/general.rs +++ b/zebra-consensus/src/block/subsidy/general.rs @@ -2,6 +2,8 @@ //! //! [7.8]: https://zips.z.cash/protocol/protocol.pdf#subsidies +// TODO: Move the contents of this mod to the parent mod and remove this mod. + use std::collections::HashSet; use zebra_chain::{ diff --git a/zebra-consensus/src/block/tests.rs b/zebra-consensus/src/block/tests.rs index 8f202a716e2..d8f74bf7b2f 100644 --- a/zebra-consensus/src/block/tests.rs +++ b/zebra-consensus/src/block/tests.rs @@ -509,8 +509,12 @@ fn miner_fees_validation_for_network(network: Network) -> Result<(), Report> { for (&height, block) in block_iter { let height = Height(height); if height > network.slow_start_shift() { - let block = Block::zcash_deserialize(&block[..]).expect("block should deserialize"); + let coinbase_tx = check::coinbase_is_first( + &Block::zcash_deserialize(&block[..]).expect("block should deserialize"), + )?; + let expected_block_subsidy = block_subsidy(height, &network)?; + // TODO: Add link to lockbox stream ZIP let expected_deferred_amount = subsidy::funding_streams::funding_stream_values( height, @@ -521,17 +525,16 @@ fn miner_fees_validation_for_network(network: Network) -> Result<(), Report> { .remove(&FundingStreamReceiver::Deferred) .unwrap_or_default(); - // fake the miner fee to a big amount - let miner_fees = Amount::try_from(MAX_MONEY / 2).unwrap(); - - // Validate - let result = check::miner_fees_are_valid( - &block, - miner_fees, + assert!(check::miner_fees_are_valid( + &coinbase_tx, + height, + // Set the miner fees to a high-enough amount. + Amount::try_from(MAX_MONEY / 2).unwrap(), expected_block_subsidy, expected_deferred_amount, - ); - assert!(result.is_ok()); + &network, + ) + .is_ok(),); } } @@ -542,9 +545,8 @@ fn miner_fees_validation_for_network(network: Network) -> Result<(), Report> { fn miner_fees_validation_failure() -> Result<(), Report> { let _init_guard = zebra_test::init(); let network = Network::Mainnet; - let block = - Arc::::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_347499_BYTES[..]) - .expect("block should deserialize"); + let block = Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_347499_BYTES[..]) + .expect("block should deserialize"); let height = block.coinbase_height().expect("valid coinbase height"); let expected_block_subsidy = block_subsidy(height, &network)?; // TODO: Add link to lockbox stream ZIP @@ -554,22 +556,21 @@ fn miner_fees_validation_failure() -> Result<(), Report> { .remove(&FundingStreamReceiver::Deferred) .unwrap_or_default(); - // fake the miner fee to a small amount - let miner_fees = Amount::zero(); - - // Validate - let result = check::miner_fees_are_valid( - &block, - miner_fees, - expected_block_subsidy, - expected_deferred_amount, + assert_eq!( + check::miner_fees_are_valid( + check::coinbase_is_first(&block)?.as_ref(), + height, + // Set the miner fee to an invalid amount. + Amount::zero(), + expected_block_subsidy, + expected_deferred_amount, + &network + ), + Err(BlockError::Transaction(TransactionError::Subsidy( + SubsidyError::InvalidMinerFees, + ))) ); - let expected = Err(BlockError::Transaction(TransactionError::Subsidy( - SubsidyError::InvalidMinerFees, - ))); - assert_eq!(expected, result); - Ok(()) } diff --git a/zebra-network/Cargo.toml b/zebra-network/Cargo.toml index 805d66dd623..168105cb69d 100644 --- a/zebra-network/Cargo.toml +++ b/zebra-network/Cargo.toml @@ -42,12 +42,12 @@ proptest-impl = ["proptest", "proptest-derive", "zebra-chain/proptest-impl"] [dependencies] bitflags = "2.5.0" byteorder = "1.5.0" -bytes = "1.6.1" +bytes = "1.7.1" chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] } dirs = "5.0.1" hex = "0.4.3" humantime-serde = "1.1.1" -indexmap = { version = "2.2.6", features = ["serde"] } +indexmap = { version = "2.3.0", features = ["serde"] } itertools = "0.13.0" lazy_static = "1.4.0" num-integer = "0.1.46" @@ -55,9 +55,9 @@ ordered-map = "0.4.2" pin-project = "1.1.5" rand = "0.8.5" rayon = "1.10.0" -regex = "1.10.4" +regex = "1.10.6" serde = { version = "1.0.204", features = ["serde_derive"] } -tempfile = "3.10.1" +tempfile = "3.11.0" thiserror = "1.0.63" futures = "0.3.30" @@ -91,7 +91,7 @@ proptest-derive = "0.5.0" static_assertions = "1.1.0" tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] } -toml = "0.8.16" +toml = "0.8.19" zebra-chain = { path = "../zebra-chain", features = ["proptest-impl"] } zebra-test = { path = "../zebra-test/" } diff --git a/zebra-node-services/Cargo.toml b/zebra-node-services/Cargo.toml index db81afd342f..c9f823a23d3 100644 --- a/zebra-node-services/Cargo.toml +++ b/zebra-node-services/Cargo.toml @@ -47,7 +47,7 @@ jsonrpc-core = { version = "18.0.0", optional = true } # Security: avoid default dependency on openssl reqwest = { version = "0.11.26", default-features = false, features = ["rustls-tls"], optional = true } serde = { version = "1.0.204", optional = true } -serde_json = { version = "1.0.121", optional = true } +serde_json = { version = "1.0.122", optional = true } tokio = { version = "1.39.2", features = ["time"], optional = true } [dev-dependencies] @@ -56,4 +56,4 @@ color-eyre = "0.6.3" jsonrpc-core = "18.0.0" reqwest = { version = "0.11.26", default-features = false, features = ["rustls-tls"] } serde = "1.0.204" -serde_json = "1.0.121" +serde_json = "1.0.122" diff --git a/zebra-rpc/Cargo.toml b/zebra-rpc/Cargo.toml index ea3adeb6537..fb2c50b6412 100644 --- a/zebra-rpc/Cargo.toml +++ b/zebra-rpc/Cargo.toml @@ -65,8 +65,8 @@ jsonrpc-derive = "18.0.0" jsonrpc-http-server = "18.0.0" # zebra-rpc needs the preserve_order feature in serde_json, which is a dependency of jsonrpc-core -serde_json = { version = "1.0.121", features = ["preserve_order"] } -indexmap = { version = "2.2.6", features = ["serde"] } +serde_json = { version = "1.0.122", features = ["preserve_order"] } +indexmap = { version = "2.3.0", features = ["serde"] } tokio = { version = "1.39.2", features = [ "time", @@ -88,12 +88,14 @@ hex = { version = "0.4.3", features = ["serde"] } serde = { version = "1.0.204", features = ["serde_derive"] } -zcash_primitives = { version = "0.15.0" } +# TODO: Revert to a release once librustzcash is released (#8749). +zcash_primitives = { git = "https://github.com/zcash/librustzcash.git", branch = "main", features = ["transparent-inputs"] } # Experimental feature getblocktemplate-rpcs rand = { version = "0.8.5", optional = true } # ECC deps used by getblocktemplate-rpcs feature -zcash_address = { version = "0.3.2", optional = true } +# TODO: Revert to a release once librustzcash is released (#8749). +zcash_address = { git = "https://github.com/zcash/librustzcash.git", branch = "main", optional = true} # Test-only feature proptest-impl proptest = { version = "1.4.0", optional = true } diff --git a/zebra-scan/Cargo.toml b/zebra-scan/Cargo.toml index 4fe378a7a96..edd2d65a396 100644 --- a/zebra-scan/Cargo.toml +++ b/zebra-scan/Cargo.toml @@ -61,7 +61,7 @@ results-reader = [ [dependencies] color-eyre = "0.6.3" -indexmap = { version = "2.2.6", features = ["serde"] } +indexmap = { version = "2.3.0", features = ["serde"] } itertools = "0.13.0" semver = "1.0.23" serde = { version = "1.0.204", features = ["serde_derive"] } @@ -101,7 +101,7 @@ zebra-test = { path = "../zebra-test", version = "1.0.0-beta.38", optional = tru tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } structopt = "0.3.26" lazy_static = "1.4.0" -serde_json = "1.0.121" +serde_json = "1.0.122" jsonrpc = { version = "0.18.0", optional = true } hex = { version = "0.4.3", optional = true } @@ -119,9 +119,9 @@ ff = "0.13.0" group = "0.13.0" jubjub = "0.10.0" rand = "0.8.5" -tempfile = "3.10.1" +tempfile = "3.11.0" zcash_note_encryption = "0.4.0" -toml = "0.8.16" +toml = "0.8.19" tonic = "0.12.1" zebra-state = { path = "../zebra-state", version = "1.0.0-beta.38", features = ["proptest-impl"] } diff --git a/zebra-scan/src/bin/scanning-results-reader/main.rs b/zebra-scan/src/bin/scanning-results-reader/main.rs index bc7d5674f3a..88ae9549b54 100644 --- a/zebra-scan/src/bin/scanning-results-reader/main.rs +++ b/zebra-scan/src/bin/scanning-results-reader/main.rs @@ -40,6 +40,7 @@ use zebra_scan::{storage::Storage, Config}; #[allow(clippy::print_stdout)] pub fn main() { let network = zebra_chain::parameters::Network::Mainnet; + let zp_network = zebra_scan::scan::zp_network(&network); let storage = Storage::new(&Config::default(), &network, true); // If the first memo is empty, it doesn't get printed. But we never print empty memos anyway. let mut prev_memo = "".to_owned(); @@ -57,11 +58,13 @@ pub fn main() { let tx = Transaction::read( &hex::decode(fetch_tx_via_rpc(txid.encode_hex())) .expect("RPC response should be decodable from hex string to bytes")[..], - BranchId::for_height(&network, height), + BranchId::for_height(&zp_network, height), ) .expect("TX fetched via RPC should be deserializable from raw bytes"); - for output in decrypt_transaction(&network, height, &tx, &ufvks).sapling_outputs() { + for output in + decrypt_transaction(&zp_network, height, &tx, &ufvks).sapling_outputs() + { let memo = memo_bytes_to_string(output.memo().as_array()); if !memo.is_empty() diff --git a/zebra-scan/src/service/scan_task/scan.rs b/zebra-scan/src/service/scan_task/scan.rs index e2a36581ae1..586b9890b73 100644 --- a/zebra-scan/src/service/scan_task/scan.rs +++ b/zebra-scan/src/service/scan_task/scan.rs @@ -377,7 +377,7 @@ pub fn scan_block( }; zcash_client_backend::scanning::scan_block( - network, + &zp_network(network), block_to_compact(block, chain_metadata), scanning_key, // Ignore whether notes are change from a viewer's own spends for now. @@ -555,3 +555,11 @@ pub fn dfvk_to_ufvk(dfvk: &DiversifiableFullViewingKey) -> Result zcash_primitives::consensus::Network { + match network { + Network::Mainnet => zcash_primitives::consensus::Network::MainNetwork, + Network::Testnet(_) => zcash_primitives::consensus::Network::TestNetwork, + } +} diff --git a/zebra-state/Cargo.toml b/zebra-state/Cargo.toml index af2119589b0..5c8aa288854 100644 --- a/zebra-state/Cargo.toml +++ b/zebra-state/Cargo.toml @@ -54,17 +54,17 @@ hex = "0.4.3" hex-literal = "0.4.1" humantime-serde = "1.1.1" human_bytes = { version = "0.4.3", default-features = false } -indexmap = "2.2.6" +indexmap = "2.3.0" itertools = "0.13.0" lazy_static = "1.4.0" metrics = "0.23.0" mset = "0.1.1" -regex = "1.10.4" +regex = "1.10.6" rlimit = "0.10.1" rocksdb = { version = "0.22.0", default-features = false, features = ["lz4"] } semver = "1.0.23" serde = { version = "1.0.204", features = ["serde_derive"] } -tempfile = "3.10.1" +tempfile = "3.11.0" thiserror = "1.0.63" rayon = "1.10.0" @@ -75,7 +75,7 @@ tracing = "0.1.39" # elasticsearch specific dependencies. # Security: avoid default dependency on openssl elasticsearch = { version = "8.5.0-alpha.1", default-features = false, features = ["rustls-tls"], optional = true } -serde_json = { version = "1.0.121", package = "serde_json", optional = true } +serde_json = { version = "1.0.122", package = "serde_json", optional = true } zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.38", features = ["async-error"] } diff --git a/zebra-state/src/config.rs b/zebra-state/src/config.rs index 869fff66533..fa9032edf6e 100644 --- a/zebra-state/src/config.rs +++ b/zebra-state/src/config.rs @@ -15,7 +15,7 @@ use tracing::Span; use zebra_chain::parameters::Network; use crate::{ - constants::{DATABASE_FORMAT_VERSION_FILE_NAME, STATE_DATABASE_KIND}, + constants::{DATABASE_FORMAT_VERSION_FILE_NAME, RESTORABLE_DB_VERSIONS, STATE_DATABASE_KIND}, state_database_format_version_in_code, BoxError, }; @@ -317,6 +317,15 @@ fn check_and_delete_database( return None; } + // Don't delete databases that can be reused. + if RESTORABLE_DB_VERSIONS + .iter() + .map(|v| v - 1) + .any(|v| v == dir_major_version) + { + return None; + } + let outdated_path = entry.path(); // # Correctness diff --git a/zebra-state/src/constants.rs b/zebra-state/src/constants.rs index 3e33b73c254..905a35969fd 100644 --- a/zebra-state/src/constants.rs +++ b/zebra-state/src/constants.rs @@ -122,6 +122,9 @@ const MAX_FIND_BLOCK_HEADERS_RESULTS_FOR_PROTOCOL: u32 = 160; pub const MAX_FIND_BLOCK_HEADERS_RESULTS_FOR_ZEBRA: u32 = MAX_FIND_BLOCK_HEADERS_RESULTS_FOR_PROTOCOL - 2; +/// These database versions can be recreated from their directly preceding versions. +pub const RESTORABLE_DB_VERSIONS: [u64; 1] = [26]; + lazy_static! { /// Regex that matches the RocksDB error when its lock file is already open. pub static ref LOCK_FILE_ERROR: Regex = Regex::new("(lock file).*(temporarily unavailable)|(in use)|(being used by another process)").expect("regex is valid"); diff --git a/zebra-state/src/service/finalized_state/disk_db.rs b/zebra-state/src/service/finalized_state/disk_db.rs index 0c25f6a273c..b5095d22192 100644 --- a/zebra-state/src/service/finalized_state/disk_db.rs +++ b/zebra-state/src/service/finalized_state/disk_db.rs @@ -12,8 +12,8 @@ use std::{ collections::{BTreeMap, HashMap}, - fmt::Debug, - fmt::Write, + fmt::{Debug, Write}, + fs, ops::RangeBounds, path::Path, sync::Arc, @@ -27,6 +27,7 @@ use semver::Version; use zebra_chain::{parameters::Network, primitives::byte_array::increment_big_endian}; use crate::{ + constants::DATABASE_FORMAT_VERSION_FILE_NAME, service::finalized_state::disk_format::{FromDisk, IntoDisk}, Config, }; @@ -522,7 +523,9 @@ impl DiskDb { let db_options = DiskDb::options(); let column_families = DiskDb::construct_column_families(&db_options, db.path(), &[]); let mut column_families_log_string = String::from(""); + write!(column_families_log_string, "Column families and sizes: ").unwrap(); + for cf_descriptor in column_families.iter() { let cf_name = &cf_descriptor.name(); let cf_handle = db @@ -940,6 +943,123 @@ impl DiskDb { // Private methods + /// Tries to reuse an existing db after a major upgrade. + /// + /// If the current db version belongs to `restorable_db_versions`, the function moves a previous + /// db to a new path so it can be used again. It does so by merely trying to rename the path + /// corresponding to the db version directly preceding the current version to the path that is + /// used by the current db. If successful, it also deletes the db version file. + pub(crate) fn try_reusing_previous_db_after_major_upgrade( + restorable_db_versions: &[u64], + format_version_in_code: &Version, + config: &Config, + db_kind: impl AsRef, + network: &Network, + ) { + if let Some(&major_db_ver) = restorable_db_versions + .iter() + .find(|v| **v == format_version_in_code.major) + { + let db_kind = db_kind.as_ref(); + + let old_path = config.db_path(db_kind, major_db_ver - 1, network); + let new_path = config.db_path(db_kind, major_db_ver, network); + + let old_path = match fs::canonicalize(&old_path) { + Ok(canonicalized_old_path) => canonicalized_old_path, + Err(e) => { + warn!("could not canonicalize {old_path:?}: {e}"); + return; + } + }; + + let cache_path = match fs::canonicalize(&config.cache_dir) { + Ok(canonicalized_cache_path) => canonicalized_cache_path, + Err(e) => { + warn!("could not canonicalize {:?}: {e}", config.cache_dir); + return; + } + }; + + // # Correctness + // + // Check that the path we're about to move is inside the cache directory. + // + // If the user has symlinked the state directory to a non-cache directory, we don't want + // to move it, because it might contain other files. + // + // We don't attempt to guard against malicious symlinks created by attackers + // (TOCTOU attacks). Zebra should not be run with elevated privileges. + if !old_path.starts_with(&cache_path) { + info!("skipped reusing previous state cache: state is outside cache directory"); + return; + } + + let opts = DiskDb::options(); + let old_db_exists = DB::list_cf(&opts, &old_path).is_ok_and(|cf| !cf.is_empty()); + let new_db_exists = DB::list_cf(&opts, &new_path).is_ok_and(|cf| !cf.is_empty()); + + if old_db_exists && !new_db_exists { + // Create the parent directory for the new db. This is because we can't directly + // rename e.g. `state/v25/mainnet/` to `state/v26/mainnet/` with `fs::rename()` if + // `state/v26/` does not exist. + match fs::create_dir_all( + new_path + .parent() + .expect("new state cache must have a parent path"), + ) { + Ok(()) => info!("created new directory for state cache at {new_path:?}"), + Err(e) => { + warn!( + "could not create new directory for state cache at {new_path:?}: {e}" + ); + return; + } + }; + + match fs::rename(&old_path, &new_path) { + Ok(()) => { + info!("moved state cache from {old_path:?} to {new_path:?}"); + + match fs::remove_file(new_path.join(DATABASE_FORMAT_VERSION_FILE_NAME)) { + Ok(()) => info!("removed version file at {new_path:?}"), + Err(e) => { + warn!("could not remove version file at {new_path:?}: {e}") + } + } + + // Get the parent of the old path, e.g. `state/v25/` and delete it if it is + // empty. + let old_path = old_path + .parent() + .expect("old state cache must have parent path"); + + if fs::read_dir(old_path) + .expect("cached state dir needs to be readable") + .next() + .is_none() + { + match fs::remove_dir_all(old_path) { + Ok(()) => { + info!("removed empty old state cache directory at {old_path:?}") + } + Err(e) => { + warn!( + "could not remove empty old state cache directory \ + at {old_path:?}: {e}" + ) + } + } + } + } + Err(e) => { + warn!("could not move state cache from {old_path:?} to {new_path:?}: {e}") + } + } + } + } + } + /// Returns the database options for the finalized state database. fn options() -> rocksdb::Options { let mut opts = rocksdb::Options::default(); diff --git a/zebra-state/src/service/finalized_state/zebra_db.rs b/zebra-state/src/service/finalized_state/zebra_db.rs index 56145b1d4e2..b7ae76ea3a1 100644 --- a/zebra-state/src/service/finalized_state/zebra_db.rs +++ b/zebra-state/src/service/finalized_state/zebra_db.rs @@ -19,6 +19,7 @@ use zebra_chain::parameters::Network; use crate::{ config::database_format_version_on_disk, + constants::RESTORABLE_DB_VERSIONS, service::finalized_state::{ disk_db::DiskDb, disk_format::{ @@ -106,6 +107,14 @@ impl ZebraDb { ) .expect("unable to read database format version file"); + DiskDb::try_reusing_previous_db_after_major_upgrade( + &RESTORABLE_DB_VERSIONS, + format_version_in_code, + config, + &db_kind, + network, + ); + // Log any format changes before opening the database, in case opening fails. let format_change = DbFormatChange::open_database(format_version_in_code, disk_version); diff --git a/zebra-test/Cargo.toml b/zebra-test/Cargo.toml index da849a0da1f..82ee08c28c5 100644 --- a/zebra-test/Cargo.toml +++ b/zebra-test/Cargo.toml @@ -16,14 +16,14 @@ categories = ["command-line-utilities", "cryptography::cryptocurrencies"] [dependencies] hex = "0.4.3" -indexmap = "2.2.6" +indexmap = "2.3.0" lazy_static = "1.4.0" insta = "1.39.0" itertools = "0.13.0" proptest = "1.4.0" once_cell = "1.18.0" rand = "0.8.5" -regex = "1.10.4" +regex = "1.10.6" tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] } tower = { version = "0.4.13", features = ["util"] } @@ -44,4 +44,4 @@ tracing-error = "0.2.0" tracing = "0.1.39" [dev-dependencies] -tempfile = "3.10.1" +tempfile = "3.11.0" diff --git a/zebra-utils/Cargo.toml b/zebra-utils/Cargo.toml index 5c383f5cb6a..b465034e757 100644 --- a/zebra-utils/Cargo.toml +++ b/zebra-utils/Cargo.toml @@ -89,7 +89,7 @@ tinyvec = { version = "1.8.0", features = ["rustc_1_55"] } structopt = "0.3.26" hex = "0.4.3" -serde_json = "1.0.121" +serde_json = "1.0.122" tracing-error = "0.2.0" tracing-subscriber = "0.3.18" thiserror = "1.0.63" @@ -104,7 +104,7 @@ zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.38", optional = true itertools = { version = "0.13.0", optional = true } # These crates are needed for the search-issue-refs binary -regex = { version = "1.10.4", optional = true } +regex = { version = "1.10.6", optional = true } # Avoid default openssl dependency to reduce the dependency tree and security alerts. reqwest = { version = "0.11.26", default-features = false, features = ["rustls-tls"], optional = true } diff --git a/zebrad/Cargo.toml b/zebrad/Cargo.toml index 079f8efc734..525c3adb609 100644 --- a/zebrad/Cargo.toml +++ b/zebrad/Cargo.toml @@ -168,14 +168,14 @@ zebra-state = { path = "../zebra-state", version = "1.0.0-beta.38" } zebra-utils = { path = "../zebra-utils", version = "1.0.0-beta.38", optional = true } abscissa_core = "0.7.0" -clap = { version = "4.5.11", features = ["cargo"] } +clap = { version = "4.5.13", features = ["cargo"] } chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] } humantime-serde = "1.1.1" -indexmap = "2.2.6" +indexmap = "2.3.0" lazy_static = "1.4.0" semver = "1.0.23" serde = { version = "1.0.204", features = ["serde_derive"] } -toml = "0.8.16" +toml = "0.8.19" futures = "0.3.30" rayon = "1.10.0" @@ -213,7 +213,7 @@ sentry = { version = "0.32.2", default-features = false, features = ["backtrace" # prod feature flamegraph tracing-flame = { version = "0.2.0", optional = true } -inferno = { version = "0.11.20", default-features = false, optional = true } +inferno = { version = "0.11.21", default-features = false, optional = true } # prod feature journald tracing-journald = { version = "0.3.0", optional = true } @@ -222,7 +222,7 @@ tracing-journald = { version = "0.3.0", optional = true } hyper = { version = "1.3.1", features = ["http1", "http2", "server"], optional = true } http-body-util = { version = "0.1.2", optional = true } hyper-util = { version = "0.1.6", optional = true } -bytes = { version = "1.6.1", optional = true } +bytes = { version = "1.7.1", optional = true } # prod feature prometheus metrics-exporter-prometheus = { version = "0.15.3", default-features = false, features = ["http-listener"], optional = true } @@ -256,12 +256,12 @@ hex = "0.4.3" hex-literal = "0.4.1" jsonrpc-core = "18.0.0" once_cell = "1.18.0" -regex = "1.10.4" +regex = "1.10.6" insta = { version = "1.39.0", features = ["json"] } # zebra-rpc needs the preserve_order feature, it also makes test results more stable -serde_json = { version = "1.0.121", features = ["preserve_order"] } -tempfile = "3.10.1" +serde_json = { version = "1.0.122", features = ["preserve_order"] } +tempfile = "3.11.0" hyper = { version = "1.3.1", features = ["http1", "http2", "server"]} tracing-test = { version = "0.2.4", features = ["no-env-filter"] } @@ -299,5 +299,4 @@ zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.5" } zebra-utils = { path = "../zebra-utils", version = "1.0.0-beta.38" } [lints.rust] -# TODO: Remove 'cfg(zcash_unstable, values("nu6"))' once it's no longer needed for NU6. -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)', 'cfg(zcash_unstable, values("nu6"))'] } +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] } diff --git a/zebrad/tests/acceptance.rs b/zebrad/tests/acceptance.rs index 33974746fd9..de6a5264e86 100644 --- a/zebrad/tests/acceptance.rs +++ b/zebrad/tests/acceptance.rs @@ -3236,10 +3236,10 @@ async fn trusted_chain_sync_handles_forks_correctly() -> Result<()> { /// Test successful block template submission as a block proposal or submission on a custom Testnet. /// /// This test can be run locally with: -/// `RUSTFLAGS='--cfg zcash_unstable="nu6"' cargo test --package zebrad --test acceptance --features getblocktemplate-rpcs -- nu6_funding_streams --exact --show-output` +/// `cargo test --package zebrad --test acceptance --features getblocktemplate-rpcs -- nu6_funding_streams_and_coinbase_balance --exact --show-output` #[tokio::test(flavor = "multi_thread")] -#[cfg(all(feature = "getblocktemplate-rpcs", zcash_unstable = "nu6"))] -async fn nu6_funding_streams() -> Result<()> { +#[cfg(feature = "getblocktemplate-rpcs")] +async fn nu6_funding_streams_and_coinbase_balance() -> Result<()> { use zebra_chain::{ chain_sync_status::MockSyncStatus, parameters::{ @@ -3470,6 +3470,49 @@ async fn nu6_funding_streams() -> Result<()> { "invalid block with excessive coinbase output value should be rejected" ); + // Use an invalid coinbase transaction (with an output value less than than the `block_subsidy + miner_fees - expected_lockbox_funding_stream`) + let network = base_network_params + .clone() + .with_post_nu6_funding_streams(ConfiguredFundingStreams { + height_range: Some(Height(1)..Height(100)), + recipients: make_configured_recipients_with_lockbox_numerator(20), + }) + .to_network(); + + let (coinbase_txn, default_roots) = generate_coinbase_and_roots( + &network, + Height(block_template.height), + &miner_address, + &[], + history_tree.clone(), + true, + vec![], + ); + + let block_template = GetBlockTemplate { + coinbase_txn, + block_commitments_hash: default_roots.block_commitments_hash, + light_client_root_hash: default_roots.block_commitments_hash, + final_sapling_root_hash: default_roots.block_commitments_hash, + default_roots, + ..block_template + }; + + let proposal_block = proposal_block_from_template(&block_template, None, NetworkUpgrade::Nu6)?; + + // Submit the invalid block with an excessive coinbase input value + let submit_block_response = get_block_template_rpc_impl + .submit_block(HexData(proposal_block.zcash_serialize_to_vec()?), None) + .await?; + + tracing::info!(?submit_block_response, "submitted invalid block"); + + assert_eq!( + submit_block_response, + submit_block::Response::ErrorResponse(submit_block::ErrorResponse::Rejected), + "invalid block with insufficient coinbase output value should be rejected" + ); + // Check that the original block template can be submitted successfully let proposal_block = proposal_block_from_template(&valid_original_block_template, None, NetworkUpgrade::Nu6)?;