diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 7a51fa2c1..b6d0e1fb6 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -8,9 +8,9 @@ on: env: # Use docker.io for Docker Hub if empty - REGISTRY: ${{ github.ref_type != 'tag' && 'ghcr.io/' || '' }} + REGISTRY: 'ghcr.io/' # github.repository as / - IMAGE_NAME: godwoken-prebuilds + IMAGE_NAME: godwoken jobs: @@ -66,8 +66,8 @@ jobs: uses: docker/login-action@v2 with: registry: ${{ env.REGISTRY }} - username: ${{ github.ref_type != 'tag' && github.repository_owner || secrets.DOCKERHUB_USERNAME }} - password: ${{ github.ref_type != 'tag' && secrets.GITHUB_TOKEN || secrets.DOCKERHUB_TOKEN }} + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Prepare components id: prepare @@ -156,7 +156,7 @@ jobs: id: meta uses: docker/metadata-action@v4 with: - images: ${{ env.REGISTRY }}${{ startsWith(github.ref, 'refs/tags') && github.repository_owner == 'godwokenrises' && 'nervos' || github.repository_owner }}/${{ env.IMAGE_NAME }} + images: ${{ env.REGISTRY }}${{ github.repository_owner }}/${{ env.IMAGE_NAME }} # dynamically set date as a suffix tags: | type=ref,event=tag @@ -165,9 +165,9 @@ jobs: labels: | maintainer=Godwoken Core Dev org.opencontainers.image.authors=Godwoken Core Dev - source.component.godwoken=https://github.com/godwokenrises/godwoken/tree/${{steps.prepare.outputs.GODWOKEN_REF }} - source.component.gwos=https://github.com/godwokenrises/godwoken/tree/${{steps.prepare.outputs.GODWOKEN_REF }}/gwos - source.component.gwos-evm=https://github.com/godwokenrises/godwoken/tree/${{steps.prepare.outputs.GODWOKEN_REF }}/gwos-evm + source.component.godwoken=https://github.com/godwokenrises/godwoken/tree/${{steps.prepare.outputs.godwoken-sha1 }} + source.component.gwos=https://github.com/godwokenrises/godwoken/tree/${{steps.prepare.outputs.godwoken-sha1 }}/gwos + source.component.gwos-evm=https://github.com/godwokenrises/godwoken/tree/${{steps.prepare.outputs.godwoken-sha1 }}/gwos-evm source.component.ckb-production-scripts=https://github.com/nervosnetwork/ckb-production-scripts/tree/${{steps.prepare.outputs.OMNI_LOCK_REF }} ref.component.godwoken=${{ steps.prepare.outputs.GODWOKEN_REF }} ref.component.godwoken-sha1=${{ steps.prepare.outputs.godwoken-sha1 }} @@ -181,19 +181,6 @@ jobs: # Build and push Docker image with Buildx (don't push on PR) # https://github.com/docker/build-push-action - name: Build and push Docker image to ${{ env.REGISTRY }}${{ github.repository_owner }}/${{ env.IMAGE_NAME }} - if: ${{ github.ref_type != 'tag' }} - uses: docker/build-push-action@v3 - with: - context: . - file: docker/Dockerfile - push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - - # Build and push Docker image with Buildx (don't push on PR) - # only for new tag - - name: Build and push Docker image to https://hub.docker.com/r/nervos/godwoken-prebuilds - if: ${{ github.repository_owner == 'godwokenrises' && startsWith(github.ref, 'refs/tags') }} uses: docker/build-push-action@v3 with: context: . diff --git a/.github/workflows/gwos-evm-ci.yml b/.github/workflows/gwos-evm-ci.yml index 434edbbe8..9c9d6df99 100644 --- a/.github/workflows/gwos-evm-ci.yml +++ b/.github/workflows/gwos-evm-ci.yml @@ -35,7 +35,7 @@ jobs: run: rustup component add rustfmt && rustup component add clippy - name: Install moleculec run: | - export MOLC_VERSION=$(cat deps/godwoken-scripts/c/Makefile | egrep "MOLC_VERSION :=" | awk '{print $3}') + export MOLC_VERSION=$(cat ../gwos/c/Makefile | egrep "MOLC_VERSION :=" | awk '{print $3}') test "$(moleculec --version)" = "Moleculec $MOLC_VERSION" \ || CARGO_TARGET_DIR=target/ cargo install moleculec --version $MOLC_VERSION - name: Install ckb-cli from nervos/godwoken-prebuilds:latest diff --git a/.github/workflows/scripts.yml b/.github/workflows/scripts.yml index 789ca9526..2b74377b6 100644 --- a/.github/workflows/scripts.yml +++ b/.github/workflows/scripts.yml @@ -71,7 +71,6 @@ jobs: - name: Copy contracts from prebuild docker images run: devtools/fetch-binaries.sh - name: Test C Uint256 - working-directory: gwos - run: cargo test + run: cargo test -p c-uint256-tests - name: Script tests run: cargo test --features scripts script_tests diff --git a/CHANGELOG.md b/CHANGELOG.md index b8ffa87d4..15289d72b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com). ## [Unreleased] +## [v1.8.0-rc2] - 2022-12-19 + +A major change in this release is re-interpreting the meaning of the `xxx_timepoint` field to `finalized timestamp`. +Thus, we can use the CKB transaction's `since` field to determine the l1 timestamp and to unlock l1 cells without reference to the Rollup cell. It also simplifies the finality determination of withdrawal cells. + +- feat: change timepoint interpretation [#897](https://github.com/godwokenrises/godwoken/pull/897) +- refactor: rename structure fields [#912](https://github.com/godwokenrises/godwoken/pull/912) + +We also adjust the documentation: + +- doc: update Finality Mechanism Changes [#913](https://github.com/godwokenrises/godwoken/pull/913/files) + +Other changes: + +- refactor: move gw-types and gw-common to gwos folder [#905](https://github.com/godwokenrises/godwoken/pull/905) +- feat: support CKB built-in indexer #907 [#907](https://github.com/godwokenrises/godwoken/pull/907) + ## [v1.8.0-rc1] - 2022-12-09 In this version, an upgrading of on-chain scripts is included: @@ -16,6 +33,10 @@ We also introduce a change to activate the new behavior. - feat: determine global state version according to fork height[#858](https://github.com/godwokenrises/godwoken/pull/858) +Experimental gas-less feature [(discussion link)](https://github.com/godwokenrises/godwoken/discussions/860): + +- feat: (optionally) support gasless transactions [#869](https://github.com/godwokenrises/godwoken/pull/869) + Other changes: - perf: optional SMT trie feature and migrate command [#859](https://github.com/godwokenrises/godwoken/pull/859) diff --git a/Cargo.lock b/Cargo.lock index 3a9bf5d75..507325764 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -134,15 +134,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "autocfg" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.1.0", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -195,6 +186,15 @@ dependencies = [ "shlex", ] +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + [[package]] name = "bit-vec" version = "0.6.3" @@ -310,6 +310,16 @@ dependencies = [ "serde", ] +[[package]] +name = "c-uint256-tests" +version = "1.8.0-rc2" +dependencies = [ + "cc", + "cty", + "primitive-types", + "proptest", +] + [[package]] name = "cache-padded" version = "1.2.0" @@ -379,9 +389,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.22" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" dependencies = [ "iana-time-zone", "js-sys", @@ -831,15 +841,6 @@ dependencies = [ "os_str_bytes", ] -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - [[package]] name = "codespan-reporting" version = "0.11.1" @@ -984,7 +985,7 @@ version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" dependencies = [ - "autocfg 1.1.0", + "autocfg", "cfg-if 1.0.0", "crossbeam-utils", "memoffset", @@ -1396,12 +1397,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - [[package]] name = "funty" version = "2.0.0" @@ -1576,7 +1571,7 @@ dependencies = [ [[package]] name = "godwoken-bin" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "ckb-types", @@ -1591,6 +1586,7 @@ dependencies = [ "gw-generator", "gw-jsonrpc-types", "gw-metrics", + "gw-smt", "gw-store", "gw-telemetry", "gw-types", @@ -1609,7 +1605,7 @@ dependencies = [ [[package]] name = "gw-benches" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "criterion", @@ -1618,6 +1614,7 @@ dependencies = [ "gw-db", "gw-generator", "gw-mem-pool", + "gw-smt", "gw-store", "gw-traits", "gw-types", @@ -1627,7 +1624,7 @@ dependencies = [ [[package]] name = "gw-block-producer" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "async-channel", @@ -1653,6 +1650,7 @@ dependencies = [ "gw-polyjuice-sender-recover", "gw-rpc-client", "gw-rpc-server", + "gw-smt", "gw-store", "gw-telemetry", "gw-types", @@ -1672,7 +1670,7 @@ dependencies = [ [[package]] name = "gw-chain" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "ckb-fixed-hash", @@ -1684,6 +1682,7 @@ dependencies = [ "gw-jsonrpc-types", "gw-mem-pool", "gw-metrics", + "gw-smt", "gw-store", "gw-telemetry", "gw-traits", @@ -1700,7 +1699,7 @@ dependencies = [ [[package]] name = "gw-challenge" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "arc-swap", @@ -1715,6 +1714,7 @@ dependencies = [ "gw-generator", "gw-jsonrpc-types", "gw-rpc-client", + "gw-smt", "gw-store", "gw-traits", "gw-types", @@ -1730,19 +1730,18 @@ dependencies = [ [[package]] name = "gw-common" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "cfg-if 0.1.10", "gw-hash", "gw-types", "merkle-cbt", - "sparse-merkle-tree", "thiserror", ] [[package]] name = "gw-config" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "ckb-fixed-hash", "gw-jsonrpc-types", @@ -1753,7 +1752,7 @@ dependencies = [ [[package]] name = "gw-db" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "ckb-rocksdb", @@ -1766,7 +1765,7 @@ dependencies = [ [[package]] name = "gw-dynamic-config" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "arc-swap", @@ -1781,7 +1780,7 @@ dependencies = [ [[package]] name = "gw-generator" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "arc-swap", @@ -1791,6 +1790,7 @@ dependencies = [ "ethabi", "gw-common", "gw-config", + "gw-smt", "gw-store", "gw-traits", "gw-types", @@ -1799,7 +1799,7 @@ dependencies = [ "lazy_static", "log", "rlp", - "secp256k1 0.20.3", + "secp256k1 0.24.1", "sha3", "substrate-bn", "tempfile", @@ -1810,14 +1810,14 @@ dependencies = [ [[package]] name = "gw-hash" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "blake2b-ref 0.3.1", ] [[package]] name = "gw-jsonrpc-types" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "ckb-fixed-hash", @@ -1830,7 +1830,7 @@ dependencies = [ [[package]] name = "gw-mem-pool" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "async-trait", @@ -1860,7 +1860,7 @@ dependencies = [ [[package]] name = "gw-metrics" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "arc-swap", "gw-common", @@ -1877,7 +1877,7 @@ dependencies = [ [[package]] name = "gw-p2p-network" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "async-trait", @@ -1895,7 +1895,7 @@ dependencies = [ [[package]] name = "gw-polyjuice-sender-recover" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "gw-common", @@ -1911,7 +1911,7 @@ dependencies = [ [[package]] name = "gw-replay-chain" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "async-jsonrpc-client", @@ -1943,7 +1943,7 @@ dependencies = [ [[package]] name = "gw-rpc-client" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "arc-swap", @@ -1975,7 +1975,7 @@ dependencies = [ [[package]] name = "gw-rpc-server" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "async-trait", @@ -1998,6 +1998,7 @@ dependencies = [ "gw-metrics", "gw-polyjuice-sender-recover", "gw-rpc-client", + "gw-smt", "gw-store", "gw-telemetry", "gw-traits", @@ -2019,15 +2020,26 @@ dependencies = [ "tracing", ] +[[package]] +name = "gw-smt" +version = "1.8.0-rc2" +dependencies = [ + "cfg-if 0.1.10", + "gw-hash", + "gw-types", + "sparse-merkle-tree", +] + [[package]] name = "gw-store" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "arc-swap", "gw-common", "gw-config", "gw-db", + "gw-smt", "gw-traits", "gw-types", "im", @@ -2036,7 +2048,7 @@ dependencies = [ [[package]] name = "gw-telemetry" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "chrono", "faster-hex 0.6.1", @@ -2057,7 +2069,7 @@ dependencies = [ [[package]] name = "gw-tests" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "async-jsonrpc-client", @@ -2085,6 +2097,7 @@ dependencies = [ "gw-polyjuice-sender-recover", "gw-rpc-client", "gw-rpc-server", + "gw-smt", "gw-store", "gw-traits", "gw-types", @@ -2093,7 +2106,7 @@ dependencies = [ "jsonrpc-v2", "lazy_static", "rand 0.8.5", - "secp256k1 0.21.3", + "secp256k1 0.24.1", "serde", "serde_json", "sha3", @@ -2104,7 +2117,7 @@ dependencies = [ [[package]] name = "gw-tools" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "bech32", @@ -2154,7 +2167,7 @@ dependencies = [ [[package]] name = "gw-traits" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "gw-common", @@ -2164,10 +2177,11 @@ dependencies = [ [[package]] name = "gw-tx-filter" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "gw-common", "gw-config", + "gw-smt", "gw-traits", "gw-types", "hex", @@ -2177,7 +2191,7 @@ dependencies = [ [[package]] name = "gw-types" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "cfg-if 0.1.10", "ckb-fixed-hash", @@ -2185,12 +2199,11 @@ dependencies = [ "gw-hash", "molecule", "primitive-types", - "sparse-merkle-tree", ] [[package]] name = "gw-utils" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", "ckb-crypto", @@ -2201,12 +2214,13 @@ dependencies = [ "gw-config", "gw-jsonrpc-types", "gw-rpc-client", + "gw-smt", "gw-store", "gw-types", "hex-literal", "log", "rand 0.8.5", - "secp256k1 0.21.3", + "secp256k1 0.24.1", "sha3", "tokio", "zstd", @@ -2214,7 +2228,7 @@ dependencies = [ [[package]] name = "gw-version" -version = "1.8.0-rc1" +version = "1.8.0-rc2" dependencies = [ "anyhow", ] @@ -2498,7 +2512,7 @@ version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ - "autocfg 1.1.0", + "autocfg", "hashbrown", ] @@ -2695,7 +2709,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ - "autocfg 1.1.0", + "autocfg", "scopeguard", ] @@ -2762,7 +2776,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] @@ -2893,7 +2907,7 @@ version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ - "autocfg 1.1.0", + "autocfg", "num-traits", ] @@ -2903,7 +2917,7 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] @@ -3051,7 +3065,7 @@ version = "0.9.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" dependencies = [ - "autocfg 1.1.0", + "autocfg", "cc", "libc", "openssl-src", @@ -3484,6 +3498,26 @@ dependencies = [ "syn", ] +[[package]] +name = "proptest" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0d9cc07f18492d879586c92b485def06bc850da3118075cd45d50e9c95b0e5" +dependencies = [ + "bit-set", + "bitflags", + "byteorder", + "lazy_static", + "num-traits", + "quick-error 2.0.1", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", +] + [[package]] name = "prost" version = "0.9.0" @@ -3537,6 +3571,18 @@ dependencies = [ "prost", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quick-xml" version = "0.22.0" @@ -3561,25 +3607,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.8", - "libc", - "rand_chacha 0.1.1", - "rand_core 0.4.2", - "rand_hc 0.1.0", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg 0.1.2", - "rand_xorshift", - "winapi", -] - [[package]] name = "rand" version = "0.7.3" @@ -3590,8 +3617,8 @@ dependencies = [ "libc", "rand_chacha 0.2.2", "rand_core 0.5.1", - "rand_hc 0.2.0", - "rand_pcg 0.2.1", + "rand_hc", + "rand_pcg", ] [[package]] @@ -3605,16 +3632,6 @@ dependencies = [ "rand_core 0.6.3", ] -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.3.1", -] - [[package]] name = "rand_chacha" version = "0.2.2" @@ -3635,21 +3652,6 @@ dependencies = [ "rand_core 0.6.3", ] -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - [[package]] name = "rand_core" version = "0.5.1" @@ -3668,15 +3670,6 @@ dependencies = [ "getrandom 0.2.7", ] -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - [[package]] name = "rand_hc" version = "0.2.0" @@ -3686,50 +3679,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.4.2", -] - [[package]] name = "rand_pcg" version = "0.2.1" @@ -3741,11 +3690,11 @@ dependencies = [ [[package]] name = "rand_xorshift" -version = "0.1.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" dependencies = [ - "rand_core 0.3.1", + "rand_core 0.6.3", ] [[package]] @@ -3763,7 +3712,7 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" dependencies = [ - "autocfg 1.1.0", + "autocfg", "crossbeam-deque", "either", "rayon-core", @@ -3781,15 +3730,6 @@ dependencies = [ "num_cpus", ] -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - [[package]] name = "redox_syscall" version = "0.2.16" @@ -3942,6 +3882,18 @@ dependencies = [ "semver", ] +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error 1.2.3", + "tempfile", + "wait-timeout", +] + [[package]] name = "ryu" version = "1.0.11" @@ -4008,22 +3960,13 @@ dependencies = [ "secp256k1-sys 0.4.2", ] -[[package]] -name = "secp256k1" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c42e6f1735c5f00f51e43e28d6634141f2bcad10931b2609ddd74a86d751260" -dependencies = [ - "rand 0.6.5", - "secp256k1-sys 0.4.2", -] - [[package]] name = "secp256k1" version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff55dc09d460954e9ef2fa8a7ced735a964be9981fd50e870b2b3b0705e14964" dependencies = [ + "rand 0.8.5", "secp256k1-sys 0.6.1", ] @@ -4194,7 +4137,7 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] @@ -4612,7 +4555,7 @@ version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581" dependencies = [ - "autocfg 1.1.0", + "autocfg", "bytes", "libc", "memchr", @@ -4925,6 +4868,15 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "2.3.2" diff --git a/Cargo.toml b/Cargo.toml index d5f6c066f..03be23bee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,15 +1,16 @@ [workspace] members = [ + "gwos/crates/types", + "gwos/crates/common", + "gwos/crates/c-uint256-tests", "crates/challenge", "crates/chain", "crates/config", - "crates/common", "crates/mem-pool", "crates/generator", "crates/traits", "crates/db", "crates/store", - "crates/types", "crates/block-producer", "crates/jsonrpc-types", "crates/rpc-server", @@ -30,7 +31,8 @@ members = [ ] exclude = [ - "gwos-evm/polyjuice-tests" + "gwos-evm/polyjuice-tests", + "gwos/contracts", ] [profile.release] diff --git a/crates/benches/Cargo.toml b/crates/benches/Cargo.toml index 7003ed885..1324b9568 100644 --- a/crates/benches/Cargo.toml +++ b/crates/benches/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gw-benches" -version = "1.8.0-rc1" +version = "1.8.0-rc2" authors = ["Nervos Network"] edition = "2018" description = "Godwoken benchmarks." @@ -14,10 +14,11 @@ anyhow = "1.0.66" criterion = { version = "0.3", features = ["html_reports"] } pprof = { version = "0.6", features = ["flamegraph", "criterion"] } gw-store = { path = "../store" } -gw-common = { path = "../common" } +gw-common = { path = "../../gwos/crates/common" } +gw-smt = { path = "../smt" } gw-mem-pool = { path = "../mem-pool" } gw-generator = { path = "../generator" } -gw-types = { path = "../types" } +gw-types = { path = "../../gwos/crates/types" } gw-traits = { path = "../traits" } gw-db = { path = "../db" } gw-config = { path = "../config" } diff --git a/crates/benches/benches/benchmarks/fee_queue.rs b/crates/benches/benches/benchmarks/fee_queue.rs index a97e15984..34b6bc527 100644 --- a/crates/benches/benches/benchmarks/fee_queue.rs +++ b/crates/benches/benches/benchmarks/fee_queue.rs @@ -1,5 +1,5 @@ use criterion::{criterion_group, Bencher, Criterion}; -use gw_common::{h256_ext::H256Ext, state::State, H256}; +use gw_common::state::State; use gw_config::GenesisConfig; use gw_generator::genesis::init_genesis; use gw_mem_pool::fee::{ @@ -13,6 +13,7 @@ use gw_store::{ }; use gw_types::{ bytes::Bytes, + h256::*, packed::{AllowedTypeHash, L2Transaction, RawL2Transaction, RollupConfig}, prelude::{Builder, Entity, Pack, PackVec, Unpack}, }; @@ -165,10 +166,7 @@ fn setup_genesis(store: &Store) { meta_contract_validator_type_hash: [0u8; 32].into(), eth_registry_validator_type_hash: [1u8; 32].into(), rollup_config: rollup_config.into(), - rollup_type_hash: { - let h: [u8; 32] = rollup_type_hash.into(); - h.into() - }, + rollup_type_hash: rollup_type_hash.into(), secp_data_dep: Default::default(), }; init_genesis(store, &genesis_config, &[0u8; 32], Bytes::default()).unwrap(); diff --git a/crates/benches/benches/benchmarks/smt.rs b/crates/benches/benches/benchmarks/smt.rs index 3c3c77c9f..be21ebdf6 100644 --- a/crates/benches/benches/benchmarks/smt.rs +++ b/crates/benches/benches/benchmarks/smt.rs @@ -7,7 +7,6 @@ use gw_common::{ builtins::{CKB_SUDT_ACCOUNT_ID, ETH_REGISTRY_ACCOUNT_ID}, registry_address::RegistryAddress, state::State, - H256, }; use gw_config::{BackendConfig, BackendForkConfig, GenesisConfig, StoreConfig}; use gw_db::{schema::COLUMNS, RocksDB}; @@ -33,6 +32,7 @@ use gw_traits::{ChainView, CodeStore}; use gw_types::{ bytes::Bytes, core::{AllowedEoaType, ScriptHashType, Status}, + h256::*, packed::{ AccountMerkleState, AllowedTypeHash, BlockInfo, BlockMerkleState, Fee, GlobalState, L2Block, RawL2Block, RawL2Transaction, RollupConfig, SUDTArgs, SUDTTransfer, Script, @@ -147,7 +147,7 @@ impl BenchExecutionEnvironment { let rollup_context = RollupContext { rollup_config: genesis_config.rollup_config.clone().into(), - rollup_script_hash: ROLLUP_TYPE_HASH.into(), + rollup_script_hash: ROLLUP_TYPE_HASH, ..Default::default() }; @@ -175,8 +175,7 @@ impl BenchExecutionEnvironment { let account_lock_manage = { let mut manage = AccountLockManage::default(); - manage - .register_lock_algorithm(ALWAYS_SUCCESS_LOCK_HASH.into(), Arc::new(AlwaysSuccess)); + manage.register_lock_algorithm(ALWAYS_SUCCESS_LOCK_HASH, Arc::new(AlwaysSuccess)); manage }; @@ -220,7 +219,7 @@ impl BenchExecutionEnvironment { .collect(); let address_offset = state - .get_account_id_by_script_hash(&block_producer_script.hash().into()) + .get_account_id_by_script_hash(&block_producer_script.hash()) .unwrap() .unwrap(); // start from block producer let start_account_id = address_offset + 1; @@ -297,7 +296,7 @@ impl BenchExecutionEnvironment { ) -> Vec { let build_account = |idx: u32| -> Account { let (account_script, addr) = Account::build_script(idx); - let account_script_hash: H256 = account_script.hash().into(); + let account_script_hash: H256 = account_script.hash(); let account_id = state.create_account(account_script_hash).unwrap(); state.insert_script(account_script_hash, account_script); state @@ -316,7 +315,7 @@ impl BenchExecutionEnvironment { fn init_genesis(store: &Store, config: &GenesisConfig, accounts: u32) { if store.has_genesis().unwrap() { let chain_id = store.get_chain_id().unwrap(); - if chain_id == ROLLUP_TYPE_HASH.into() { + if chain_id == ROLLUP_TYPE_HASH { return; } else { panic!("store genesis already initialized"); @@ -324,7 +323,7 @@ impl BenchExecutionEnvironment { } let db = store.begin_transaction(); - db.setup_chain_id(ROLLUP_TYPE_HASH.into()).unwrap(); + db.setup_chain_id(ROLLUP_TYPE_HASH).unwrap(); let (db, genesis_state) = build_genesis_from_store(db, config, Default::default()).unwrap(); let smt = db @@ -340,8 +339,7 @@ impl BenchExecutionEnvironment { state.finalise().unwrap(); let (genesis, global_state) = { - let prev_state_checkpoint: [u8; 32] = - state.calculate_state_checkpoint().unwrap().into(); + let prev_state_checkpoint: [u8; 32] = state.calculate_state_checkpoint().unwrap(); let submit_txs = SubmitTransactions::new_builder() .prev_state_checkpoint(prev_state_checkpoint.pack()) .build(); diff --git a/crates/benches/benches/benchmarks/sudt.rs b/crates/benches/benches/benchmarks/sudt.rs index ddf887cea..f07d797b8 100644 --- a/crates/benches/benches/benchmarks/sudt.rs +++ b/crates/benches/benches/benchmarks/sudt.rs @@ -1,14 +1,14 @@ use anyhow::{bail, Result}; use criterion::*; use gw_common::{ - builtins::ETH_REGISTRY_ACCOUNT_ID, registry_address::RegistryAddress, smt::SMT, state::State, - H256, + builtins::ETH_REGISTRY_ACCOUNT_ID, registry_address::RegistryAddress, state::State, }; use gw_config::{BackendConfig, BackendForkConfig}; use gw_generator::{ account_lock_manage::AccountLockManage, backend_manage::BackendManage, error::TransactionError, traits::StateExt, Generator, }; +use gw_smt::smt::{SMT, SMTH256}; use gw_store::{ smt::smt_store::SMTStateStore, snapshot::StoreSnapshot, @@ -23,6 +23,7 @@ use gw_traits::{ChainView, CodeStore}; use gw_types::{ bytes::Bytes, core::{AllowedEoaType, ScriptHashType}, + h256::*, offchain::RunResult, packed::{AllowedTypeHash, BlockInfo, Fee}, packed::{RawL2Transaction, RollupConfig, SUDTArgs, SUDTTransfer, Script}, @@ -75,7 +76,7 @@ impl ChainView for DummyChainStore { } fn new_state(store: StoreSnapshot) -> MemStateDB { - let smt = SMT::new(H256::zero(), SMTStateStore::new(MemStore::new(store))); + let smt = SMT::new(SMTH256::zero(), SMTStateStore::new(MemStore::new(store))); let inner = MemStateTree::new(smt, 0); MemStateDB::new(inner) } @@ -105,7 +106,7 @@ fn run_contract_get_result( let account_lock_manage = AccountLockManage::default(); let rollup_ctx = RollupContext { rollup_config: rollup_config.clone(), - rollup_script_hash: [42u8; 32].into(), + rollup_script_hash: [42u8; 32], ..Default::default() }; let generator = Generator::new( @@ -222,7 +223,7 @@ pub fn bench(c: &mut Criterion) { .build() }; let block_producer = RegistryAddress::new(ETH_REGISTRY_ACCOUNT_ID, vec![3u8; 20]); - let block_producer_script_hash = block_producer_script.hash().into(); + let block_producer_script_hash = block_producer_script.hash(); tree.mapping_registry_address_to_script_hash( block_producer.clone(), block_producer_script_hash, diff --git a/crates/block-producer/Cargo.toml b/crates/block-producer/Cargo.toml index b9f7986f7..ba224e38e 100644 --- a/crates/block-producer/Cargo.toml +++ b/crates/block-producer/Cargo.toml @@ -1,15 +1,16 @@ [package] name = "gw-block-producer" -version = "1.8.0-rc1" +version = "1.8.0-rc2" authors = ["Nervos Network"] edition = "2021" [dependencies] gw-challenge = { path = "../challenge" } -gw-common = { path = "../common" } +gw-common = { path = "../../gwos/crates/common" } +gw-smt = { path = "../smt" } gw-config = { path = "../config" } gw-chain = { path = "../chain" } -gw-types = { path = "../types" } +gw-types = { path = "../../gwos/crates/types" } gw-db = { path = "../db" } gw-store = { path = "../store" } gw-generator = { path = "../generator" } diff --git a/crates/block-producer/src/block_producer.rs b/crates/block-producer/src/block_producer.rs index 48a91f8f6..e48cddb3a 100644 --- a/crates/block-producer/src/block_producer.rs +++ b/crates/block-producer/src/block_producer.rs @@ -12,7 +12,6 @@ use crate::{ use anyhow::{bail, ensure, Context, Result}; use ckb_chain_spec::consensus::MAX_BLOCK_BYTES; use gw_chain::chain::Chain; -use gw_common::H256; use gw_config::BlockProducerConfig; use gw_generator::Generator; use gw_jsonrpc_types::test_mode::TestModePayload; @@ -21,11 +20,12 @@ use gw_mem_pool::{ pool::{MemPool, OutputParam}, }; use gw_rpc_client::{contract::ContractsCellDepManager, rpc_client::RPCClient}; +use gw_smt::smt::SMTH256; use gw_store::Store; -use gw_types::core::Timepoint; use gw_types::offchain::{global_state_from_slice, CompatibleFinalizedTimepoint}; use gw_types::{ bytes::Bytes, + h256::*, offchain::{DepositInfo, InputCellInfo}, packed::{ CellDep, CellInput, CellOutput, GlobalState, L2Block, RollupAction, RollupActionUnion, @@ -34,9 +34,9 @@ use gw_types::{ prelude::*, }; use gw_utils::{ - fee::fill_tx_fee_with_local, genesis_info::CKBGenesisInfo, local_cells::LocalCellsManager, - query_rollup_cell, since::Since, transaction_skeleton::TransactionSkeleton, wallet::Wallet, - RollupContext, + fee::fill_tx_fee_with_local, finalized_timepoint, genesis_info::CKBGenesisInfo, + local_cells::LocalCellsManager, query_rollup_cell, since::Since, + transaction_skeleton::TransactionSkeleton, wallet::Wallet, RollupContext, }; use std::{collections::HashSet, sync::Arc, time::Instant}; use tokio::sync::Mutex; @@ -60,21 +60,15 @@ fn generate_custodian_cells( block: &L2Block, deposit_cells: &[DepositInfo], ) -> Vec<(CellOutput, Bytes)> { - let block_hash: H256 = block.hash().into(); - let block_timepoint = { - let block_number = block.raw().number().unpack(); - if rollup_context - .fork_config - .use_timestamp_as_timepoint(block_number) - { - let block_timestamp = block.raw().timestamp().unpack(); - Timepoint::from_timestamp(block_timestamp) - } else { - Timepoint::from_block_number(block_number) - } - }; + let block_hash: H256 = block.hash(); + let finalized_timepoint = finalized_timepoint( + &rollup_context.rollup_config, + &rollup_context.fork_config, + block.raw().number().unpack(), + block.raw().timestamp().unpack(), + ); let to_custodian = |deposit| -> _ { - to_custodian_cell(rollup_context, &block_hash, &block_timepoint, deposit) + to_custodian_cell(rollup_context, &block_hash, &finalized_timepoint, deposit) .expect("sanitized deposit") }; @@ -179,11 +173,11 @@ impl BlockProducer { let reverted_block_root: H256 = { let db = self.store.begin_transaction(); let smt = db.reverted_block_smt()?; - smt.root().to_owned() + (*smt.root()).into() }; let param = ProduceBlockParam { - stake_cell_owner_lock_hash: self.wallet.lock_script().hash().into(), + stake_cell_owner_lock_hash: self.wallet.lock_script().hash(), reverted_block_root, rollup_config_hash: self.rollup_config_hash, block_param, @@ -265,20 +259,24 @@ impl BlockProducer { let db = self.store.begin_transaction(); let block_smt = db.reverted_block_smt()?; - let local_root: &H256 = block_smt.root(); + let local_root: H256 = (*block_smt.root()).into(); let global_revert_block_root: H256 = global_state.reverted_block_root().unpack(); - assert_eq!(local_root, &global_revert_block_root); + assert_eq!(local_root, global_revert_block_root); let keys: Vec = collected_block_hashes.into_iter().collect(); for key in keys.iter() { log::info!("submit revert block {:?}", hex::encode(key.as_slice())); } - let proof = block_smt - .merkle_proof(keys.clone())? - .compile(keys.clone())?; + let reverted_block_hashes = keys.pack(); + let proof = { + let smt_keys: Vec = keys.into_iter().map(Into::into).collect(); + block_smt + .merkle_proof(smt_keys.clone())? + .compile(smt_keys)? + }; RollupSubmitBlock::new_builder() - .reverted_block_hashes(keys.pack()) + .reverted_block_hashes(reverted_block_hashes) .reverted_block_proof(proof.0.pack()) } else { RollupSubmitBlock::new_builder() @@ -380,7 +378,7 @@ impl BlockProducer { } // withdrawal cells - let map_withdrawal_extras = withdrawal_extras.into_iter().map(|w| (w.hash().into(), w)); + let map_withdrawal_extras = withdrawal_extras.into_iter().map(|w| (w.hash(), w)); if let Some(generated_withdrawal_cells) = crate::withdrawal::generate( rollup_context, finalized_custodians, diff --git a/crates/block-producer/src/block_sync_client.rs b/crates/block-producer/src/block_sync_client.rs index c77d3b4f8..945d5e6c9 100644 --- a/crates/block-producer/src/block_sync_client.rs +++ b/crates/block-producer/src/block_sync_client.rs @@ -339,7 +339,7 @@ async fn handle_local_block( let store_tx = &client.store.begin_transaction(); let store_block_hash = store_tx.get_block_hash_by_number(block_number)?; if let Some(store_block_hash) = store_block_hash { - if store_block_hash != block_hash.into() { + if store_block_hash != block_hash { log::info!("revert to {}", block_number - 1); revert(client, store_tx, block_number - 1).await?; store_tx.commit()?; diff --git a/crates/block-producer/src/chain_updater.rs b/crates/block-producer/src/chain_updater.rs index 050a3dd99..11b1181a6 100644 --- a/crates/block-producer/src/chain_updater.rs +++ b/crates/block-producer/src/chain_updater.rs @@ -71,7 +71,7 @@ impl ChainUpdater { let tx = self .rpc_client .ckb - .get_transaction(tx_hash.0.into()) + .get_transaction(tx_hash.0) .await? .context("get transaction")?; @@ -219,7 +219,7 @@ impl ChainUpdater { let tx = self .rpc_client .ckb - .get_transaction(tx_hash.0.into()) + .get_transaction(tx_hash.0) .await? .ok_or_else(|| QueryL1TxError::new(&tx_hash, anyhow!("cannot locate tx")))?; let cell_output = tx diff --git a/crates/block-producer/src/challenger.rs b/crates/block-producer/src/challenger.rs index c529ea663..25ea4edaa 100644 --- a/crates/block-producer/src/challenger.rs +++ b/crates/block-producer/src/challenger.rs @@ -16,7 +16,6 @@ use gw_challenge::offchain::verify_tx::{verify_tx, TxWithContext}; use gw_challenge::offchain::{mock_cancel_challenge_tx, OffChainMockContext}; use gw_challenge::revert::Revert; use gw_challenge::types::{RevertContext, VerifyContext}; -use gw_common::H256; use gw_config::{BlockProducerConfig, DebugConfig}; use gw_generator::types::vm::ChallengeContext; use gw_jsonrpc_types::test_mode::TestModePayload; @@ -24,6 +23,7 @@ use gw_rpc_client::contract::ContractsCellDepManager; use gw_rpc_client::rpc_client::RPCClient; use gw_types::bytes::Bytes; use gw_types::core::{ChallengeTargetType, Status}; +use gw_types::h256::*; use gw_types::offchain::{global_state_from_slice, CellInfo, InputCellInfo, TxStatus}; use gw_types::packed::{ CellDep, CellInput, CellOutput, ChallengeLockArgs, ChallengeLockArgsReader, ChallengeTarget, diff --git a/crates/block-producer/src/cleaner.rs b/crates/block-producer/src/cleaner.rs index 9e170f521..9953eacce 100644 --- a/crates/block-producer/src/cleaner.rs +++ b/crates/block-producer/src/cleaner.rs @@ -6,9 +6,9 @@ use gw_utils::{fee::fill_tx_fee, wallet::Wallet}; use anyhow::{anyhow, Result}; use ckb_types::prelude::{Builder, Entity}; use gw_challenge::cancel_challenge::RecoverAccountsContext; -use gw_common::H256; use gw_rpc_client::rpc_client::RPCClient; use gw_types::core::Status; +use gw_types::h256::*; use gw_types::offchain::{global_state_from_slice, CellInfo, InputCellInfo, TxStatus}; use gw_types::packed::{CellDep, CellInput, Transaction, WitnessArgs}; use gw_types::prelude::Unpack; diff --git a/crates/block-producer/src/custodian.rs b/crates/block-producer/src/custodian.rs index 45ca48d98..aa40123e4 100644 --- a/crates/block-producer/src/custodian.rs +++ b/crates/block-producer/src/custodian.rs @@ -140,7 +140,7 @@ async fn query_mergeable_ckb_custodians( }; if !compatible_finalized_timepoint.is_finalized(&Timepoint::from_full_value( custodian_lock_args_reader - .deposit_block_timepoint() + .deposit_finalized_timepoint() .unpack(), )) { continue; diff --git a/crates/block-producer/src/debugger.rs b/crates/block-producer/src/debugger.rs index d28aea06e..1395388a8 100644 --- a/crates/block-producer/src/debugger.rs +++ b/crates/block-producer/src/debugger.rs @@ -5,12 +5,12 @@ use std::{ use anyhow::{anyhow, Result}; use ckb_types::prelude::Entity; -use gw_common::H256; use gw_jsonrpc_types::{ ckb_jsonrpc_types, debugger::{ReprMockCellDep, ReprMockInfo, ReprMockInput, ReprMockTransaction}, }; use gw_rpc_client::rpc_client::RPCClient; +use gw_types::h256::*; use gw_types::{ core::DepType, offchain::TxStatus, @@ -134,7 +134,7 @@ pub async fn build_mock_transaction( }; inputs.push(mock_input); if let Some(input_block_hash) = input_block_hash { - header_deps_hashes.push(input_block_hash.into()); + header_deps_hashes.push(input_block_hash); } } @@ -191,7 +191,7 @@ pub async fn build_mock_transaction( }; cell_deps.push(mock_cell_dep); if let Some(dep_cell_block_hash) = dep_cell_block_hash { - header_deps_hashes.push(dep_cell_block_hash.into()); + header_deps_hashes.push(dep_cell_block_hash); } } diff --git a/crates/block-producer/src/produce_block.rs b/crates/block-producer/src/produce_block.rs index 8eeb94aaf..68a949d8f 100644 --- a/crates/block-producer/src/produce_block.rs +++ b/crates/block-producer/src/produce_block.rs @@ -4,24 +4,25 @@ use anyhow::{anyhow, Result}; use gw_common::{ - h256_ext::H256Ext, merkle_utils::{calculate_ckb_merkle_root, calculate_state_checkpoint, ckb_merkle_leaf_hash}, - smt::Blake2bHasher, - sparse_merkle_tree::CompiledMerkleProof, state::State, - H256, }; use gw_generator::Generator; use gw_mem_pool::mem_block::MemBlock; +use gw_smt::{ + smt::{Blake2bHasher, SMTH256}, + smt_h256_ext::SMTH256Ext, + sparse_merkle_tree::CompiledMerkleProof, +}; use gw_store::{ state::{history::history_state::RWConfig, BlockStateDB}, traits::chain_store::ChainStore, transaction::StoreTransaction, Store, }; -use gw_types::core::Timepoint; use gw_types::{ core::Status, + h256::*, offchain::{BlockParam, DepositInfo, FinalizedCustodianCapacity}, packed::{ AccountMerkleState, BlockMerkleState, GlobalState, L2Block, RawL2Block, SubmitTransactions, @@ -29,6 +30,7 @@ use gw_types::{ }, prelude::*, }; +use gw_utils::global_state_finalized_timepoint; use tracing::instrument; #[derive(Clone)] @@ -80,17 +82,16 @@ pub fn produce_block( } = param; let rollup_context = generator.rollup_context(); - let parent_block_hash: H256 = parent_block.hash().into(); + let parent_block_hash: H256 = parent_block.hash(); // assemble block let submit_txs = { let tx_witness_root = calculate_ckb_merkle_root( txs.iter() .enumerate() - .map(|(id, tx)| ckb_merkle_leaf_hash(id as u32, &tx.witness_hash().into())) + .map(|(id, tx)| ckb_merkle_leaf_hash(id as u32, &tx.witness_hash())) .collect(), - ) - .map_err(|err| anyhow!("merkle root error: {:?}", err))?; + ); let tx_count = txs.len() as u32; SubmitTransactions::new_builder() .tx_witness_root(tx_witness_root.pack()) @@ -103,12 +104,9 @@ pub fn produce_block( withdrawals .iter() .enumerate() - .map(|(id, request)| { - ckb_merkle_leaf_hash(id as u32, &request.witness_hash().into()) - }) + .map(|(id, request)| ckb_merkle_leaf_hash(id as u32, &request.witness_hash())) .collect(), - ) - .map_err(|err| anyhow!("merkle root error: {:?}", err))?; + ); let withdrawal_count = withdrawals.len() as u32; SubmitWithdrawals::new_builder() .withdrawal_witness_root(withdrawal_witness_root.pack()) @@ -140,9 +138,9 @@ pub fn produce_block( .build(); let block_smt = db.block_smt()?; let block_proof = block_smt - .merkle_proof(vec![H256::from_u64(number)]) + .merkle_proof(vec![SMTH256::from_u64(number)]) .map_err(|err| anyhow!("merkle proof error: {:?}", err))? - .compile(vec![H256::from_u64(number)])?; + .compile(vec![SMTH256::from_u64(number)])?; let packed_kv_state = kv_state.pack(); let withdrawal_requests = withdrawals.iter().map(|w| w.request()); let block = L2Block::new_builder() @@ -164,22 +162,12 @@ pub fn produce_block( .build() }; - let last_finalized_timepoint = if rollup_context - .fork_config - .use_timestamp_as_timepoint(number) - { - let finality_time_in_ms = rollup_context.rollup_config.finality_time_in_ms(); - Timepoint::from_timestamp( - block - .raw() - .timestamp() - .unpack() - .saturating_sub(finality_time_in_ms), - ) - } else { - let finality_as_blocks = rollup_context.rollup_config.finality_blocks().unpack(); - Timepoint::from_block_number(number.saturating_sub(finality_as_blocks)) - }; + let last_finalized_timepoint = global_state_finalized_timepoint( + &rollup_context.rollup_config, + &rollup_context.fork_config, + block.raw().number().unpack(), + block.raw().timestamp().unpack(), + ); let global_state = GlobalState::new_builder() .account(post_merkle_state) .block(post_block) @@ -233,7 +221,7 @@ pub fn generate_produce_block_param( } else { let state_smt = db.state_smt()?; - let keys: Vec = kv_state.iter().map(|(k, _v)| *k).collect(); + let keys: Vec = kv_state.iter().map(|(k, _v)| (*k).into()).collect(); state_smt .merkle_proof(keys.clone()) .map_err(|err| anyhow!("merkle proof error: {:?}", err))? @@ -289,16 +277,22 @@ pub fn generate_produce_block_param( let expected_kv_state_root: H256 = prev_merkle_state.merkle_root().unpack(); let smt = db.state_smt()?; assert_eq!( - smt.root(), - &expected_kv_state_root, + H256::from(*smt.root()), + expected_kv_state_root, "check smt root consistent" ); if !kv_state_proof.is_empty() { log::debug!("[output mem-block] check merkle proof"); // check state merkle proof before output - let prev_kv_state_root = CompiledMerkleProof(kv_state_proof.clone()) - .compute_root::(kv_state.clone())?; + let prev_kv_state_root: H256 = CompiledMerkleProof(kv_state_proof.clone()) + .compute_root::( + kv_state + .iter() + .map(|(k, v)| ((*k).into(), (*v).into())) + .collect(), + )? + .into(); let expected_kv_state_root: H256 = prev_merkle_state.merkle_root().unpack(); assert_eq!( expected_kv_state_root, prev_kv_state_root, diff --git a/crates/block-producer/src/psc.rs b/crates/block-producer/src/psc.rs index de224fff7..db0c34a50 100644 --- a/crates/block-producer/src/psc.rs +++ b/crates/block-producer/src/psc.rs @@ -4,7 +4,6 @@ use std::{collections::HashSet, fmt::Display, sync::Arc, time::Duration}; use anyhow::{bail, ensure, Context, Result}; use gw_chain::chain::Chain; -use gw_common::H256; use gw_config::PscConfig; use gw_mem_pool::{block_sync_server::BlockSyncServerState, pool::MemPool}; use gw_rpc_client::{ @@ -14,6 +13,7 @@ use gw_rpc_client::{ use gw_store::{snapshot::StoreSnapshot, traits::chain_store::ChainStore, Store}; use gw_telemetry::traits::{OpenTelemetrySpanExt, TraceContextExt}; use gw_types::{ + h256::*, offchain::{CellStatus, DepositInfo, TxStatus}, packed::{ self, Confirmed, GlobalState, LocalBlock, NumberHash, OutPoint, Revert, Script, ScriptVec, @@ -399,7 +399,7 @@ async fn produce_local_block(ctx: &PSCContext) -> Result<()> { }; let number: u64 = block.raw().number().unpack(); - let block_hash: H256 = block.hash().into(); + let block_hash: H256 = block.hash(); let block_txs = block.transactions().len(); let block_withdrawals = block.withdrawals().len(); @@ -638,10 +638,7 @@ async fn poll_tx_confirmed(rpc_client: &RPCClient, tx: &Transaction) -> Result<( log::info!("waiting for tx 0x{}", hex::encode(tx.hash())); let mut last_sent = Instant::now(); loop { - let status = rpc_client - .ckb - .get_transaction_status(tx.hash().into()) - .await?; + let status = rpc_client.ckb.get_transaction_status(tx.hash()).await?; let should_resend = match status { Some(TxStatus::Committed) => break, Some(TxStatus::Rejected) => true, @@ -668,7 +665,7 @@ async fn poll_tx_confirmed(rpc_client: &RPCClient, tx: &Transaction) -> Result<( // Wait for indexer syncing the L1 block. let block_number = rpc_client .ckb - .get_transaction_block_number(tx.hash().into()) + .get_transaction_block_number(tx.hash()) .await? .context("get tx block hash")?; loop { @@ -771,7 +768,7 @@ async fn check_cell(rpc_client: &RPCClient, out_point: &OutPoint) -> Result<()> .any(|i| i.previous_output().eq(out_point)) { bail!(DeadCellError { - consumed_by_tx: Some(tx.hash().into()), + consumed_by_tx: Some(tx.hash()), }); } } @@ -804,7 +801,7 @@ async fn send_transaction_or_check_inputs( // This can happen if the tx is confirmed right before it is // resent and its inputs is checked. if let Some(dead) = e.downcast_ref::() { - if dead.consumed_by_tx == Some(tx.hash().into()) { + if dead.consumed_by_tx == Some(tx.hash()) { return Ok(()); } } @@ -911,7 +908,7 @@ fn publish_local_block( let withdrawals = { let reqs = block.as_reader().withdrawals(); let extra_reqs = reqs.iter().map(|w| { - let h = w.hash().into(); + let h = w.hash(); snap.get_withdrawal(&h)? .with_context(|| format!("block {} withdrawal {} not found", b, h.pack())) }); diff --git a/crates/block-producer/src/replay_block.rs b/crates/block-producer/src/replay_block.rs index c8a147d87..a8395b377 100644 --- a/crates/block-producer/src/replay_block.rs +++ b/crates/block-producer/src/replay_block.rs @@ -3,7 +3,6 @@ use ckb_types::bytes::Bytes; use ckb_types::prelude::{Builder, Entity}; use gw_common::registry_address::RegistryAddress; use gw_common::state::State; -use gw_common::H256; use gw_generator::traits::StateExt; use gw_generator::Generator; use gw_store::chain_view::ChainView; @@ -11,6 +10,7 @@ use gw_store::state::traits::JournalDB; use gw_store::state::MemStateDB; use gw_store::traits::chain_store::ChainStore; use gw_store::Store; +use gw_types::h256::*; use gw_types::packed::{BlockInfo, DepositRequest, L2Block, RawL2Block, WithdrawalRequestExtra}; use gw_types::prelude::Unpack; diff --git a/crates/block-producer/src/runner.rs b/crates/block-producer/src/runner.rs index 984e9be21..71920d7af 100644 --- a/crates/block-producer/src/runner.rs +++ b/crates/block-producer/src/runner.rs @@ -13,7 +13,7 @@ use anyhow::{anyhow, bail, Context, Result}; use futures::future::OptionFuture; use gw_chain::chain::Chain; use gw_challenge::offchain::{OffChainMockContext, OffChainMockContextBuildArgs}; -use gw_common::{blake2b::new_blake2b, registry_address::RegistryAddress, H256}; +use gw_common::{blake2b::new_blake2b, registry_address::RegistryAddress}; use gw_config::{BlockProducerConfig, Config, NodeMode}; use gw_db::migrate::{init_migration_factory, open_or_create_db}; use gw_dynamic_config::manager::DynamicConfigManager; @@ -43,6 +43,7 @@ use gw_store::Store; use gw_types::{ bytes::Bytes, core::AllowedEoaType, + h256::*, packed::{Byte32, CellDep, NumberHash, RollupConfig, Script}, prelude::*, }; @@ -202,7 +203,7 @@ impl ChainTask { } // update tip - Ok(Some((new_block_number, block.header().hash().into()))) + Ok(Some((new_block_number, block.header().hash()))) } else { log::debug!( "Not found layer1 block #{} sleep {}s then retry", @@ -272,16 +273,17 @@ impl BaseInitComponents { let rollup_config: RollupConfig = config.genesis.rollup_config.clone().into(); let rollup_context = RollupContext { rollup_config: rollup_config.clone(), - rollup_script_hash: { - let rollup_script_hash: [u8; 32] = config.genesis.rollup_type_hash.clone().into(); - rollup_script_hash.into() - }, + rollup_script_hash: config.genesis.rollup_type_hash.clone().into(), fork_config: config.fork.clone(), }; let rollup_type_script: Script = config.chain.rollup_type_script.clone().into(); let rpc_client = { - let indexer_client = CKBIndexerClient::with_url(&config.rpc_client.indexer_url)?; let ckb_client = CKBClient::with_url(&config.rpc_client.ckb_url)?; + let indexer_client = if let Some(ref indexer_url) = config.rpc_client.indexer_url { + CKBIndexerClient::with_url(indexer_url)? + } else { + CKBIndexerClient::new(ckb_client.client().clone(), false) + }; let rollup_type_script = ckb_types::packed::Script::new_unchecked(rollup_type_script.as_bytes()); RPCClient::new( @@ -338,7 +340,7 @@ impl BaseInitComponents { let out_point = config.genesis.secp_data_dep.out_point.clone(); rpc_client .ckb - .get_transaction(out_point.tx_hash.0.into()) + .get_transaction(out_point.tx_hash.0) .await? .ok_or_else(|| anyhow!("can not found transaction: {:?}", out_point.tx_hash))? .raw() @@ -365,7 +367,7 @@ impl BaseInitComponents { if let Some(res) = gw_dynamic_config::try_reload(dynamic_config_manager.clone()).await { log::info!("Reload dynamic config: {:?}", res); } - let rollup_config_hash: H256 = rollup_config.hash().into(); + let rollup_config_hash: H256 = rollup_config.hash(); let generator = { let backend_manage = BackendManage::from_config(config.fork.backend_forks.clone()) .with_context(|| "config backends")?; @@ -404,7 +406,7 @@ impl BaseInitComponents { }; let mut builtin_load_data = HashMap::new(); builtin_load_data.insert( - to_hash(secp_data.as_ref()).into(), + to_hash(secp_data.as_ref()), config.genesis.secp_data_dep.clone().into(), ); diff --git a/crates/block-producer/src/stake.rs b/crates/block-producer/src/stake.rs index f2853758c..ea72fbc2a 100644 --- a/crates/block-producer/src/stake.rs +++ b/crates/block-producer/src/stake.rs @@ -20,7 +20,7 @@ use gw_types::{ use gw_utils::local_cells::{ collect_local_and_indexer_cells, CollectLocalAndIndexerCursor, LocalCellsManager, }; -use gw_utils::RollupContext; +use gw_utils::{finalized_timepoint, RollupContext}; pub struct GeneratedStake { pub deps: Vec, @@ -39,22 +39,16 @@ pub async fn generate( local_cells_manager: &LocalCellsManager, ) -> Result { let owner_lock_hash = lock_script.hash(); - let stake_block_timepoint = { - let block_number: u64 = block.raw().number().unpack(); - if rollup_context - .fork_config - .use_timestamp_as_timepoint(block_number) - { - let block_timestamp: u64 = block.raw().timestamp().unpack(); - Timepoint::from_timestamp(block_timestamp) - } else { - Timepoint::from_block_number(block_number) - } - }; + let stake_finalized_timepoint = finalized_timepoint( + &rollup_context.rollup_config, + &rollup_context.fork_config, + block.raw().number().unpack(), + block.raw().timestamp().unpack(), + ); let lock_args: Bytes = { let stake_lock_args = StakeLockArgs::new_builder() .owner_lock_hash(owner_lock_hash.pack()) - .stake_block_timepoint(stake_block_timepoint.full_value().pack()) + .stake_finalized_timepoint(stake_finalized_timepoint.full_value().pack()) .build(); let rollup_type_hash = rollup_context.rollup_script_hash.as_slice().iter(); rollup_type_hash @@ -186,7 +180,7 @@ pub async fn query_stake( match &compatible_finalize_timepoint_opt { Some(compatible_finalized_timepoint) => { compatible_finalized_timepoint.is_finalized(&Timepoint::from_full_value( - stake_lock_args.stake_block_timepoint().unpack(), + stake_lock_args.stake_finalized_timepoint().unpack(), )) && stake_lock_args.owner_lock_hash().as_slice() == owner_lock_hash } None => stake_lock_args.owner_lock_hash().as_slice() == owner_lock_hash, diff --git a/crates/block-producer/src/sync_l1.rs b/crates/block-producer/src/sync_l1.rs index 5fba7c38d..a8aaaaf2c 100644 --- a/crates/block-producer/src/sync_l1.rs +++ b/crates/block-producer/src/sync_l1.rs @@ -112,7 +112,6 @@ async fn sync_l1_unknown( ..Default::default() })); let mut last_cursor = None; - let tx_hash: [u8; 32] = tx_hash.into(); let last_confirmed_tx_hash = tx_hash.into(); let mut seen_last_confirmed = false; let mut reverted = false; @@ -141,9 +140,7 @@ async fn sync_l1_unknown( if !reverted { // It's likely that this transaction confirms the next block. In // this case, we just update the last confirmed block. - if store_tx.get_block_submit_tx_hash(last_confirmed + 1) - == Some(tx.tx_hash.0.into()) - { + if store_tx.get_block_submit_tx_hash(last_confirmed + 1) == Some(tx.tx_hash.0) { last_confirmed += 1; log::info!("confirmed block {last_confirmed}"); continue; diff --git a/crates/block-producer/src/test_mode_control.rs b/crates/block-producer/src/test_mode_control.rs index 87eb0d9e4..9134abaed 100644 --- a/crates/block-producer/src/test_mode_control.rs +++ b/crates/block-producer/src/test_mode_control.rs @@ -1,15 +1,14 @@ use anyhow::{anyhow, Result}; use async_trait::async_trait; use ckb_types::prelude::{Builder, Entity}; -use gw_common::h256_ext::H256Ext; use gw_common::merkle_utils::{calculate_ckb_merkle_root, ckb_merkle_leaf_hash}; -use gw_common::smt::Blake2bHasher; -use gw_common::H256; use gw_generator::types::vm::ChallengeContext; use gw_jsonrpc_types::test_mode::ChallengeType; use gw_jsonrpc_types::{godwoken::GlobalState as JsonGlobalState, test_mode::TestModePayload}; use gw_rpc_client::rpc_client::RPCClient; use gw_rpc_server::registry::TestModeRPC; +use gw_smt::smt::{Blake2bHasher, SMTH256}; +use gw_smt::smt_h256_ext::SMTH256Ext; use gw_store::traits::chain_store::ChainStore; use gw_store::Store; use gw_types::core::{ChallengeTargetType, Status}; @@ -74,131 +73,133 @@ impl TestModeControl { (target_index, target_type) }; - let bad_block = - match target_type { - ChallengeType::TxExecution => { - let tx_count: u32 = block.raw().submit_transactions().tx_count().unpack(); - if target_index >= tx_count { - return Err(anyhow!("target index out of bound, total {}", tx_count)); - } - - let tx = block.transactions().get_unchecked(target_index as usize); - let bad_tx = { - let raw_tx = tx - .raw() - .as_builder() - .nonce(99999999u32.pack()) - .to_id(99999999u32.pack()) - .args(Bytes::copy_from_slice("break tx execution".as_bytes()).pack()) - .build(); - - tx.as_builder().raw(raw_tx).build() - }; - - let mut txs: Vec = block.transactions().into_iter().collect(); - *txs.get_mut(target_index as usize).expect("exists") = bad_tx; - - let tx_witness_root = { - let witnesses = txs.iter().enumerate().map(|(id, tx)| { - ckb_merkle_leaf_hash(id as u32, &tx.witness_hash().into()) - }); - calculate_ckb_merkle_root(witnesses.collect())? - }; - - let submit_txs = { - let builder = block.raw().submit_transactions().as_builder(); - builder.tx_witness_root(tx_witness_root.pack()).build() - }; - - let raw_block = block - .raw() - .as_builder() - .submit_transactions(submit_txs) - .build(); - - block - .as_builder() - .raw(raw_block) - .transactions(txs.pack()) - .build() + let bad_block = match target_type { + ChallengeType::TxExecution => { + let tx_count: u32 = block.raw().submit_transactions().tx_count().unpack(); + if target_index >= tx_count { + return Err(anyhow!("target index out of bound, total {}", tx_count)); } - ChallengeType::TxSignature => { - let tx_count: u32 = block.raw().submit_transactions().tx_count().unpack(); - if target_index >= tx_count { - return Err(anyhow!("target index out of bound, total {}", tx_count)); - } - - let tx = block.transactions().get_unchecked(target_index as usize); - let bad_tx = tx.as_builder().signature(Bytes::default().pack()).build(); - - let mut txs: Vec = block.transactions().into_iter().collect(); - *txs.get_mut(target_index as usize).expect("exists") = bad_tx; - - let tx_witness_root = { - let witnesses = txs.iter().enumerate().map(|(id, tx)| { - ckb_merkle_leaf_hash(id as u32, &tx.witness_hash().into()) - }); - calculate_ckb_merkle_root(witnesses.collect())? - }; - - let submit_txs = { - let builder = block.raw().submit_transactions().as_builder(); - builder.tx_witness_root(tx_witness_root.pack()).build() - }; - - let raw_block = block + + let tx = block.transactions().get_unchecked(target_index as usize); + let bad_tx = { + let raw_tx = tx .raw() .as_builder() - .submit_transactions(submit_txs) + .nonce(99999999u32.pack()) + .to_id(99999999u32.pack()) + .args(Bytes::copy_from_slice("break tx execution".as_bytes()).pack()) .build(); - block - .as_builder() - .raw(raw_block) - .transactions(txs.pack()) - .build() + tx.as_builder().raw(raw_tx).build() + }; + + let mut txs: Vec = block.transactions().into_iter().collect(); + *txs.get_mut(target_index as usize).expect("exists") = bad_tx; + + let tx_witness_root = { + let witnesses = txs + .iter() + .enumerate() + .map(|(id, tx)| ckb_merkle_leaf_hash(id as u32, &tx.witness_hash())); + calculate_ckb_merkle_root(witnesses.collect()) + }; + + let submit_txs = { + let builder = block.raw().submit_transactions().as_builder(); + builder.tx_witness_root(tx_witness_root.pack()).build() + }; + + let raw_block = block + .raw() + .as_builder() + .submit_transactions(submit_txs) + .build(); + + block + .as_builder() + .raw(raw_block) + .transactions(txs.pack()) + .build() + } + ChallengeType::TxSignature => { + let tx_count: u32 = block.raw().submit_transactions().tx_count().unpack(); + if target_index >= tx_count { + return Err(anyhow!("target index out of bound, total {}", tx_count)); } - ChallengeType::WithdrawalSignature => { - let count: u32 = block.raw().submit_withdrawals().withdrawal_count().unpack(); - if target_index >= count { - return Err(anyhow!("target index out of bound, total {}", count)); - } - - let withdrawal = block.withdrawals().get_unchecked(target_index as usize); - let bad_withdrawal = withdrawal - .as_builder() - .signature(Bytes::default().pack()) - .build(); - - let mut withdrawals: Vec = - block.withdrawals().into_iter().collect(); - *withdrawals.get_mut(target_index as usize).expect("exists") = bad_withdrawal; - - let withdrawal_witness_root = { - let witnesses = withdrawals.iter().enumerate().map(|(idx, t)| { - ckb_merkle_leaf_hash(idx as u32, &t.witness_hash().into()) - }); - calculate_ckb_merkle_root(witnesses.collect())? - }; - let submit_withdrawals = SubmitWithdrawals::new_builder() - .withdrawal_witness_root(withdrawal_witness_root.pack()) - .withdrawal_count((withdrawals.len() as u32).pack()) - .build(); - - let raw_block = block - .raw() - .as_builder() - .submit_withdrawals(submit_withdrawals) - .build(); - - block - .as_builder() - .raw(raw_block) - .withdrawals(withdrawals.pack()) - .build() + let tx = block.transactions().get_unchecked(target_index as usize); + let bad_tx = tx.as_builder().signature(Bytes::default().pack()).build(); + + let mut txs: Vec = block.transactions().into_iter().collect(); + *txs.get_mut(target_index as usize).expect("exists") = bad_tx; + + let tx_witness_root = { + let witnesses = txs + .iter() + .enumerate() + .map(|(id, tx)| ckb_merkle_leaf_hash(id as u32, &tx.witness_hash())); + calculate_ckb_merkle_root(witnesses.collect()) + }; + + let submit_txs = { + let builder = block.raw().submit_transactions().as_builder(); + builder.tx_witness_root(tx_witness_root.pack()).build() + }; + + let raw_block = block + .raw() + .as_builder() + .submit_transactions(submit_txs) + .build(); + + block + .as_builder() + .raw(raw_block) + .transactions(txs.pack()) + .build() + } + ChallengeType::WithdrawalSignature => { + let count: u32 = block.raw().submit_withdrawals().withdrawal_count().unpack(); + if target_index >= count { + return Err(anyhow!("target index out of bound, total {}", count)); } - }; + + let withdrawal = block.withdrawals().get_unchecked(target_index as usize); + let bad_withdrawal = withdrawal + .as_builder() + .signature(Bytes::default().pack()) + .build(); + + let mut withdrawals: Vec = + block.withdrawals().into_iter().collect(); + *withdrawals.get_mut(target_index as usize).expect("exists") = bad_withdrawal; + + let withdrawal_witness_root = { + let witnesses = withdrawals + .iter() + .enumerate() + .map(|(idx, t)| ckb_merkle_leaf_hash(idx as u32, &t.witness_hash())); + calculate_ckb_merkle_root(witnesses.collect()) + }; + + let submit_withdrawals = SubmitWithdrawals::new_builder() + .withdrawal_witness_root(withdrawal_witness_root.pack()) + .withdrawal_count((withdrawals.len() as u32).pack()) + .build(); + + let raw_block = block + .raw() + .as_builder() + .submit_withdrawals(submit_withdrawals) + .build(); + + block + .as_builder() + .raw(raw_block) + .withdrawals(withdrawals.pack()) + .build() + } + }; let block_number = bad_block.raw().number().unpack(); let bad_global_state = { @@ -206,8 +207,8 @@ impl TestModeControl { let bad_block_proof = db .block_smt()? - .merkle_proof(vec![H256::from_u64(block_number)])? - .compile(vec![H256::from_u64(block_number)])?; + .merkle_proof(vec![SMTH256::from_u64(block_number)])? + .compile(vec![SMTH256::from_u64(block_number)])?; // Generate new block smt for global state let bad_block_smt = { diff --git a/crates/block-producer/src/utils.rs b/crates/block-producer/src/utils.rs index 90561e641..e5b138b38 100644 --- a/crates/block-producer/src/utils.rs +++ b/crates/block-producer/src/utils.rs @@ -1,6 +1,9 @@ use crate::debugger; use gw_rpc_client::rpc_client::RPCClient; -use gw_types::packed::Transaction; +use gw_types::core::Timepoint; +use gw_types::packed::{GlobalState, Transaction}; +use gw_types::prelude::Unpack; +use gw_utils::since::Since; use std::path::Path; pub async fn dump_transaction>(dir: P, rpc_client: &RPCClient, tx: &Transaction) { @@ -12,3 +15,15 @@ pub async fn dump_transaction>(dir: P, rpc_client: &RPCClient, tx ); } } + +/// Convert global_state.last_finalized_timepoint to the form fo Since. +pub fn global_state_last_finalized_timepoint_to_since(global_state: &GlobalState) -> u64 { + match Timepoint::from_full_value(global_state.last_finalized_timepoint().unpack()) { + Timepoint::BlockNumber(_) => 0, + Timepoint::Timestamp(time_ms) => { + // the since is used to prove finality, so since value can be 1 second later + // we adjust the value as `time_ms / 1000 + 1` to prevent the `since` in seconds is less than `time_ms`, + Since::new_timestamp_seconds(time_ms / 1000 + 1).as_u64() + } + } +} diff --git a/crates/block-producer/src/withdrawal.rs b/crates/block-producer/src/withdrawal.rs index ca5b9be1d..4b3f32904 100644 --- a/crates/block-producer/src/withdrawal.rs +++ b/crates/block-producer/src/withdrawal.rs @@ -1,9 +1,10 @@ #![allow(clippy::mutable_key_type)] use anyhow::{anyhow, Result}; -use gw_common::H256; use gw_config::ContractsCellDep; use gw_mem_pool::{custodian::sum_withdrawals, withdrawal::Generator}; +use gw_types::core::Timepoint; +use gw_types::h256::*; use gw_types::offchain::CompatibleFinalizedTimepoint; use gw_types::packed::RollupConfig; use gw_types::{ @@ -17,6 +18,7 @@ use gw_types::{ }, prelude::*, }; +use gw_utils::withdrawal::parse_lock_args; use gw_utils::RollupContext; use std::{ collections::HashMap, @@ -48,7 +50,7 @@ pub fn generate( let total_withdrawal_amount = sum_withdrawals(block.withdrawals().into_iter()); let mut generator = Generator::new(rollup_context, finalized_custodians.into()); for req in block.withdrawals().into_iter() { - let req_extra = match withdrawal_extras.get(&req.hash().into()) { + let req_extra = match withdrawal_extras.get(&req.hash()) { Some(req_extra) => req_extra.to_owned(), None => WithdrawalRequestExtra::new_builder().request(req).build(), }; @@ -190,6 +192,7 @@ pub fn revert( })) } +#[derive(Debug)] pub struct UnlockedWithdrawals { pub deps: Vec, pub inputs: Vec, @@ -202,6 +205,7 @@ pub fn unlock_to_owner( rollup_config: &RollupConfig, contracts_dep: &ContractsCellDep, withdrawal_cells: Vec, + global_state_since: u64, ) -> Result> { if withdrawal_cells.is_empty() { return Ok(None); @@ -229,6 +233,7 @@ pub fn unlock_to_owner( rollup_config.finality_blocks().unpack(), ); let l1_sudt_script_hash = rollup_config.l1_sudt_script_type_hash(); + let mut if_exist_legacy_withdrawal_cells = false; for withdrawal_cell in withdrawal_cells { // Double check if let Err(err) = gw_rpc_client::withdrawal::verify_unlockable_to_owner( @@ -240,6 +245,10 @@ pub fn unlock_to_owner( continue; } + if !if_exist_legacy_withdrawal_cells { + if_exist_legacy_withdrawal_cells = is_legacy_finality_withdrawal_cell(&withdrawal_cell); + } + let owner_lock = { let args: Bytes = withdrawal_cell.output.lock().args().unpack(); match gw_utils::withdrawal::parse_lock_args(&args) { @@ -254,6 +263,7 @@ pub fn unlock_to_owner( let withdrawal_input = { let input = CellInput::new_builder() .previous_output(withdrawal_cell.out_point.clone()) + .since(global_state_since.pack()) .build(); InputCellInfo { @@ -282,12 +292,21 @@ pub fn unlock_to_owner( let withdrawal_lock_dep = contracts_dep.withdrawal_cell_lock.clone(); let sudt_type_dep = contracts_dep.l1_sudt_type.clone(); - let mut cell_deps = vec![ - // rollup_dep and rollup_config_dep will be used by withdrawal_lock_script - rollup_dep, - rollup_config_dep.into(), - withdrawal_lock_dep.into(), - ]; + let mut cell_deps = if if_exist_legacy_withdrawal_cells { + // Some withdrawal cells were born at legacy version, withdrawal_lock_script checks finality of withdrawal + // cells by comparing with GlobalState.last_finalized_timepoint, so rollup_dep and + // rollup_config_dep are required + vec![ + rollup_dep, + rollup_config_dep.into(), + withdrawal_lock_dep.into(), + ] + } else { + // All withdrawal cells were born at v2, withdrawal_lock_script checks finality of withdrawal + // cells by comparing with `since`. + vec![withdrawal_lock_dep.into()] + }; + if unlocked_to_owner_outputs .iter() .any(|output| output.0.type_().to_opt().is_some()) @@ -303,26 +322,41 @@ pub fn unlock_to_owner( })) } +fn is_legacy_finality_withdrawal_cell(withdrawal_cell: &CellInfo) -> bool { + let withdrawal_lock_args = parse_lock_args(&withdrawal_cell.output.lock().args().raw_data()) + .expect("parse withdrawal lock args"); + match Timepoint::from_full_value( + withdrawal_lock_args + .lock_args + .withdrawal_finalized_timepoint() + .unpack(), + ) { + Timepoint::BlockNumber(_) => true, + Timepoint::Timestamp(_) => false, + } +} + #[cfg(test)] mod test { use std::collections::HashMap; use std::iter::FromIterator; + use crate::utils::global_state_last_finalized_timepoint_to_since; use crate::withdrawal::generate; - use gw_common::{h256_ext::H256Ext, H256}; - use gw_config::ContractsCellDep; + use gw_config::{ContractsCellDep, ForkConfig}; use gw_types::core::{DepType, ScriptHashType, Timepoint}; + use gw_types::h256::*; use gw_types::offchain::{ CellInfo, CollectedCustodianCells, CompatibleFinalizedTimepoint, InputCellInfo, }; use gw_types::packed::{ - CellDep, CellInput, CellOutput, GlobalState, L2Block, OutPoint, RawL2Block, - RawWithdrawalRequest, RollupConfig, Script, UnlockWithdrawalViaFinalize, + BlockMerkleState, CellDep, CellInput, CellOutput, GlobalState, L2Block, OutPoint, + RawL2Block, RawWithdrawalRequest, RollupConfig, Script, UnlockWithdrawalViaFinalize, UnlockWithdrawalWitness, UnlockWithdrawalWitnessUnion, WithdrawalLockArgs, WithdrawalRequest, WithdrawalRequestExtra, WitnessArgs, }; use gw_types::prelude::{Builder, Entity, Pack, PackVec, Unpack}; - use gw_utils::RollupContext; + use gw_utils::{global_state_finalized_timepoint, RollupContext}; use super::unlock_to_owner; @@ -384,8 +418,7 @@ mod test { .request(withdrawal.clone()) .owner_lock(owner_lock) .build(); - let withdrawal_extras = - HashMap::from_iter([(withdrawal.hash().into(), withdrawal_extra.clone())]); + let withdrawal_extras = HashMap::from_iter([(withdrawal.hash(), withdrawal_extra.clone())]); let generated = generate( &rollup_context, @@ -401,7 +434,7 @@ mod test { let (expected_output, expected_data) = gw_generator::utils::build_withdrawal_cell_output( &rollup_context, &withdrawal_extra, - &block.hash().into(), + &block.hash(), &block_timepoint, Some(sudt_script.clone()), ) @@ -430,7 +463,7 @@ mod test { } #[test] - fn test_unlock_to_owner() { + fn test_unlock_to_owner_v1() { // Output should only change lock to owner lock let last_finalized_timepoint = Timepoint::from_block_number(100); let global_state = GlobalState::new_builder() @@ -458,7 +491,7 @@ mod test { .build(); let rollup_context = RollupContext { - rollup_script_hash: rollup_type.hash().into(), + rollup_script_hash: rollup_type.hash(), rollup_config: RollupConfig::new_builder() .withdrawal_script_type_hash(H256::from_u32(5).pack()) .l1_sudt_script_type_hash(sudt_script.code_hash()) @@ -497,7 +530,7 @@ mod test { let withdrawal_without_owner_lock = { let lock_args = WithdrawalLockArgs::new_builder() .owner_lock_hash(owner_lock.hash().pack()) - .withdrawal_block_timepoint(last_finalized_timepoint.full_value().pack()) + .withdrawal_finalized_timepoint(last_finalized_timepoint.full_value().pack()) .build(); let mut args = rollup_type.hash().to_vec(); @@ -513,7 +546,7 @@ mod test { let withdrawal_with_owner_lock = { let lock_args = WithdrawalLockArgs::new_builder() .owner_lock_hash(owner_lock.hash().pack()) - .withdrawal_block_timepoint(last_finalized_timepoint.full_value().pack()) + .withdrawal_finalized_timepoint(last_finalized_timepoint.full_value().pack()) .build(); let mut args = rollup_type.hash().to_vec(); @@ -532,6 +565,7 @@ mod test { } }; + let global_state_since = global_state_last_finalized_timepoint_to_since(&global_state); let unlocked = unlock_to_owner( rollup_cell.clone(), &rollup_context.rollup_config, @@ -540,6 +574,7 @@ mod test { withdrawal_without_owner_lock, withdrawal_with_owner_lock.clone(), ], + global_state_since, ) .expect("unlock") .expect("some unlocked"); @@ -615,4 +650,238 @@ mod test { CellDep::from(contracts_dep.l1_sudt_type).as_slice(), ); } + + #[test] + fn test_unlock_to_owner_finality() { + const FINALITY_BLOCKS: u64 = 10; + const UPGRADE_GLOBAL_STATE_VERSION_TO_V2: u64 = 100; + const BLOCK_TIMESTAMP: u64 = 1670000000000; + + let cases = vec![ + CaseParam { + // v1 withdrawal, v1 global state, not finalized + id: 0, + finality_blocks: FINALITY_BLOCKS, + upgrade_global_state_version_to_v2: UPGRADE_GLOBAL_STATE_VERSION_TO_V2, + block_timestamp: BLOCK_TIMESTAMP, + block_number: UPGRADE_GLOBAL_STATE_VERSION_TO_V2 - 1, + withdrawal_finalized_timepoint: Timepoint::BlockNumber( + UPGRADE_GLOBAL_STATE_VERSION_TO_V2 - FINALITY_BLOCKS, + ), + expected_result: Err(()), + }, + CaseParam { + // v1 withdrawal, v1 global state, finalized + id: 1, + finality_blocks: FINALITY_BLOCKS, + upgrade_global_state_version_to_v2: UPGRADE_GLOBAL_STATE_VERSION_TO_V2, + block_timestamp: BLOCK_TIMESTAMP, + block_number: UPGRADE_GLOBAL_STATE_VERSION_TO_V2 - 1, + withdrawal_finalized_timepoint: Timepoint::BlockNumber( + UPGRADE_GLOBAL_STATE_VERSION_TO_V2 - 1 - FINALITY_BLOCKS, + ), + expected_result: Ok(()), + }, + CaseParam { + // v1 withdrawal, v2 global state, not finalized + id: 2, + finality_blocks: FINALITY_BLOCKS, + upgrade_global_state_version_to_v2: UPGRADE_GLOBAL_STATE_VERSION_TO_V2, + block_timestamp: BLOCK_TIMESTAMP, + block_number: UPGRADE_GLOBAL_STATE_VERSION_TO_V2, + withdrawal_finalized_timepoint: Timepoint::BlockNumber( + UPGRADE_GLOBAL_STATE_VERSION_TO_V2 + 1 - FINALITY_BLOCKS, + ), + expected_result: Err(()), + }, + CaseParam { + // v1 withdrawal, v2 global state, finalized + id: 3, + finality_blocks: FINALITY_BLOCKS, + upgrade_global_state_version_to_v2: UPGRADE_GLOBAL_STATE_VERSION_TO_V2, + block_timestamp: BLOCK_TIMESTAMP, + block_number: UPGRADE_GLOBAL_STATE_VERSION_TO_V2, + withdrawal_finalized_timepoint: Timepoint::BlockNumber( + UPGRADE_GLOBAL_STATE_VERSION_TO_V2 - FINALITY_BLOCKS, + ), + expected_result: Ok(()), + }, + CaseParam { + // v2 withdrawal, v2 global state, not finalized + id: 4, + finality_blocks: FINALITY_BLOCKS, + upgrade_global_state_version_to_v2: UPGRADE_GLOBAL_STATE_VERSION_TO_V2, + block_timestamp: BLOCK_TIMESTAMP, + block_number: UPGRADE_GLOBAL_STATE_VERSION_TO_V2, + withdrawal_finalized_timepoint: Timepoint::Timestamp(BLOCK_TIMESTAMP + 1), + expected_result: Err(()), + }, + CaseParam { + // v2 withdrawal, v2 global state, finalized + id: 5, + finality_blocks: FINALITY_BLOCKS, + upgrade_global_state_version_to_v2: UPGRADE_GLOBAL_STATE_VERSION_TO_V2, + block_timestamp: BLOCK_TIMESTAMP, + block_number: UPGRADE_GLOBAL_STATE_VERSION_TO_V2, + withdrawal_finalized_timepoint: Timepoint::Timestamp(BLOCK_TIMESTAMP), + expected_result: Ok(()), + }, + ]; + for case in cases { + run_case(case); + } + + #[derive(Debug)] + struct CaseParam { + #[allow(dead_code)] + id: usize, + finality_blocks: u64, + upgrade_global_state_version_to_v2: u64, + block_timestamp: u64, + block_number: u64, + withdrawal_finalized_timepoint: Timepoint, + expected_result: Result<(), ()>, + } + + fn run_case(case_param: CaseParam) { + println!("case: {:?}", case_param); + let CaseParam { + id: _, + finality_blocks, + upgrade_global_state_version_to_v2, + block_number, + block_timestamp, + withdrawal_finalized_timepoint, + expected_result, + } = case_param; + + let sudt_script = Script::new_builder() + .code_hash(H256::from_u32(3).pack()) + .hash_type(ScriptHashType::Type.into()) + .args(vec![4u8; 32].pack()) + .build(); + let rollup_config = RollupConfig::new_builder() + .l1_sudt_script_type_hash(sudt_script.code_hash()) + .finality_blocks(finality_blocks.pack()) + .build(); + let fork_config = ForkConfig { + upgrade_global_state_version_to_v2: Some(upgrade_global_state_version_to_v2), + ..Default::default() + }; + let global_state = GlobalState::new_builder() + .rollup_config_hash(rollup_config.hash().pack()) + .last_finalized_timepoint( + global_state_finalized_timepoint( + &rollup_config, + &fork_config, + block_number, + block_timestamp, + ) + .full_value() + .pack(), + ) + .block( + BlockMerkleState::new_builder() + .count((block_number + 1).pack()) + .build(), + ) + .build(); + let rollup_state_script = Script::new_builder() + .code_hash(H256::from_u32(1).pack()) + .build(); + let rollup_state_cell = CellInfo { + data: global_state.as_bytes(), + out_point: OutPoint::new_builder() + .tx_hash(H256::from_u32(2).pack()) + .build(), + output: CellOutput::new_builder() + .type_(Some(rollup_state_script.clone()).pack()) + .build(), + }; + let rollup_context = RollupContext { + rollup_script_hash: rollup_state_script.hash(), + rollup_config: rollup_config.clone(), + fork_config, + }; + let contracts_dep = { + ContractsCellDep { + withdrawal_cell_lock: CellDep::new_builder() + .out_point( + OutPoint::new_builder() + .tx_hash(H256::from_u32(6).pack()) + .build(), + ) + .build() + .into(), + l1_sudt_type: CellDep::new_builder() + .out_point( + OutPoint::new_builder() + .tx_hash(H256::from_u32(7).pack()) + .build(), + ) + .build() + .into(), + ..Default::default() + } + }; + + // Build owner's lock script and withdrawal cell + let owner_lock_script = Script::new_builder() + .code_hash(H256::from_u32(8).pack()) + .hash_type(ScriptHashType::Type.into()) + .args(vec![9u8; 32].pack()) + .build(); + let withdrawal_lock_args = WithdrawalLockArgs::new_builder() + .owner_lock_hash(owner_lock_script.hash().pack()) + .withdrawal_finalized_timepoint(withdrawal_finalized_timepoint.full_value().pack()) + .build(); + let withdrawal_cell = CellInfo { + output: CellOutput::new_builder() + .type_(Some(sudt_script).pack()) + .lock( + Script::new_builder() + .code_hash(rollup_config.withdrawal_script_type_hash()) + .hash_type(ScriptHashType::Type.into()) + .args({ + let mut args = rollup_state_script.hash().to_vec(); + args.extend_from_slice(&withdrawal_lock_args.as_bytes()); + args.extend_from_slice( + &(owner_lock_script.as_bytes().len() as u32).to_be_bytes(), + ); + args.extend_from_slice(&owner_lock_script.as_bytes()); + args.pack() + }) + .build(), + ) + .build(), + data: 100u128.pack().as_bytes(), + ..Default::default() + }; + + let unlocked = unlock_to_owner( + rollup_state_cell, + &rollup_context.rollup_config, + &contracts_dep, + vec![withdrawal_cell], + global_state_last_finalized_timepoint_to_since(&global_state), + ) + .expect("unlock"); + + match expected_result { + Ok(()) => { + assert!(unlocked.is_some()); + let unlocked = unlocked.unwrap(); + for input in unlocked.inputs.iter() { + assert_eq!( + input.input.since().unpack(), + global_state_last_finalized_timepoint_to_since(&global_state), + ); + } + } + Err(()) => { + assert!(unlocked.is_none(), "actual unlocked: {:?}", unlocked); + } + } + } + } } diff --git a/crates/block-producer/src/withdrawal_unlocker.rs b/crates/block-producer/src/withdrawal_unlocker.rs index b551a26c0..4121e41e8 100644 --- a/crates/block-producer/src/withdrawal_unlocker.rs +++ b/crates/block-producer/src/withdrawal_unlocker.rs @@ -5,10 +5,10 @@ use std::sync::Arc; use anyhow::{bail, Result}; use async_trait::async_trait; -use gw_common::H256; use gw_config::{ContractsCellDep, DebugConfig}; use gw_rpc_client::contract::ContractsCellDepManager; use gw_rpc_client::rpc_client::RPCClient; +use gw_types::h256::*; use gw_types::offchain::{ global_state_from_slice, CellInfo, CompatibleFinalizedTimepoint, TxStatus, }; @@ -26,6 +26,7 @@ use tracing::instrument; use crate::types::ChainEvent; use crate::utils; +use crate::utils::global_state_last_finalized_timepoint_to_since; pub use gw_rpc_client::contract::Guard; const TRANSACTION_FAILED_TO_RESOLVE_ERROR: &str = "TransactionFailedToResolve"; @@ -197,11 +198,13 @@ pub trait BuildUnlockWithdrawalToOwner { unlockable_withdrawals.len() ); + let global_state_since = global_state_last_finalized_timepoint_to_since(&global_state); let to_unlock = match crate::withdrawal::unlock_to_owner( rollup_cell, self.rollup_config(), &self.contracts_dep(), unlockable_withdrawals, + global_state_since, )? { Some(to_unlock) => to_unlock, None => return Ok(None), diff --git a/crates/chain/Cargo.toml b/crates/chain/Cargo.toml index 17579302b..21b1ff53c 100644 --- a/crates/chain/Cargo.toml +++ b/crates/chain/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gw-chain" -version = "1.8.0-rc1" +version = "1.8.0-rc2" authors = ["Nervos Network"] edition = "2018" @@ -8,9 +8,10 @@ edition = "2018" [dependencies] gw-challenge = { path = "../challenge" } -gw-types = { path = "../types" } +gw-types = { path = "../../gwos/crates/types" } gw-config = { path = "../config" } -gw-common = { path = "../common" } +gw-common = { path = "../../gwos/crates/common" } +gw-smt = { path = "../smt" } gw-generator = { path = "../generator" } gw-mem-pool = { path = "../mem-pool" } gw-store = { path = "../store" } diff --git a/crates/chain/src/chain.rs b/crates/chain/src/chain.rs index da7a9edbe..6af11347b 100644 --- a/crates/chain/src/chain.rs +++ b/crates/chain/src/chain.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, bail, ensure, Context, Result}; use gw_challenge::offchain::{verify_tx::TxWithContext, OffChainMockContext}; -use gw_common::{sparse_merkle_tree, state::State, CKB_SUDT_SCRIPT_ARGS, H256}; +use gw_common::{state::State, CKB_SUDT_SCRIPT_ARGS}; use gw_config::ChainConfig; use gw_generator::{ generator::{ApplyBlockArgs, ApplyBlockResult}, @@ -22,6 +22,7 @@ use gw_store::{ use gw_types::{ bytes::Bytes, core::Status, + h256::*, offchain::global_state_from_slice, packed::{ BlockMerkleState, Byte32, CellInput, CellOutput, ChallengeTarget, ChallengeWitness, @@ -119,7 +120,8 @@ impl SyncEvent { } /// concrete type aliases -pub type StateStore = sparse_merkle_tree::default_store::DefaultStore; +pub type StateStore = + gw_smt::sparse_merkle_tree::default_store::DefaultStore; pub struct LocalState { tip: L2Block, @@ -169,14 +171,14 @@ impl Chain { "check generator rollup config" ); let rollup_type_script_hash = rollup_type_script.hash(); - let chain_id: [u8; 32] = store.get_chain_id()?.into(); + let chain_id: [u8; 32] = store.get_chain_id()?; assert_eq!( chain_id, rollup_type_script_hash, "Database chain_id must equals to rollup_script_hash" ); let tip = store.get_tip_block()?; let last_global_state = store - .get_block_post_global_state(&tip.hash().into())? + .get_block_post_global_state(&tip.hash())? .ok_or_else(|| anyhow!("can't find last global state"))?; let local_state = LocalState { tip, @@ -186,10 +188,7 @@ impl Chain { .skipped_invalid_block_list .iter() .cloned() - .map(|ckb_h256| { - let h: [u8; 32] = ckb_h256.into(); - h.into() - }) + .map(H256::from) .collect(); Ok(Chain { store, @@ -309,8 +308,7 @@ impl Chain { assert_eq!(local_reverted_block_root, global_reverted_block_root); // Check bad block challenge target - let challenge_target = - db.get_bad_block_challenge_target(&l2block.hash().into())?; + let challenge_target = db.get_bad_block_challenge_target(&l2block.hash())?; if self.challenge_target.is_none() && challenge_target.is_some() { self.challenge_target = challenge_target; } @@ -355,10 +353,7 @@ impl Chain { assert_eq!(local_block_root, global_block_root, "block root fork"); assert!(self.challenge_target.is_none()); - db.set_bad_block_challenge_target( - &l2block.hash().into(), - &challenge_target, - )?; + db.set_bad_block_challenge_target(&l2block.hash(), &challenge_target)?; self.challenge_target = Some(challenge_target.clone()); self.local_state.tip = l2block; @@ -481,7 +476,7 @@ impl Chain { // Both bad blocks and reverted_blocks should be ascended and matched let local_reverted_blocks = - package_bad_blocks(db, &first_reverted_block.hash().into())?; + package_bad_blocks(db, &first_reverted_block.hash())?; let local_slice: Vec<[u8; 32]> = local_reverted_blocks.iter().map(|b| b.hash()).collect(); let submit_slice: Vec<[u8; 32]> = @@ -493,8 +488,7 @@ impl Chain { db.revert_bad_blocks(&local_reverted_blocks)?; log::debug!("bad blocks reverted"); - let reverted_block_hashes = - local_reverted_blocks.iter().map(|b| b.hash().into()); + let reverted_block_hashes = local_reverted_blocks.iter().map(|b| b.hash()); db.set_reverted_block_hashes( &db.get_reverted_block_smt_root()?, prev_reverted_block_root, @@ -510,7 +504,7 @@ impl Chain { // Check block smt let global_block_smt = global_state.block(); let local_block_smt = { - let root: [u8; 32] = db.get_block_smt_root()?.into(); + let root: [u8; 32] = db.get_block_smt_root()?; BlockMerkleState::new_builder() .merkle_root(root.pack()) .count(first_reverted_block.number()) @@ -534,7 +528,7 @@ impl Chain { log::info!("revert to block {}", local_tip_block_number); // Check whether our bad block is reverted - if Some(H256::from(first_reverted_block.hash())) == self.bad_block_hash() { + if Some(first_reverted_block.hash()) == self.bad_block_hash() { self.challenge_target = None; log::info!("clear local bad block"); } @@ -675,9 +669,9 @@ impl Chain { "rewind to last valid tip first" ); - let local_state_tip_hash: H256 = self.local_state.tip.hash().into(); + let local_state_tip_hash: H256 = self.local_state.tip.hash(); let last_valid_tip_hash = db.get_last_valid_tip_block_hash()?; - let block_hash: H256 = l2block.hash().into(); + let block_hash: H256 = l2block.hash(); assert_eq!( local_state_tip_hash, last_valid_tip_hash, "rewind to last valid tip first" @@ -711,7 +705,7 @@ impl Chain { assert_eq!(local_tip.hash(), local_valid_tip.hash()); let parent_block_hash: H256 = l2block.raw().parent_block_hash().unpack(); - assert_eq!(parent_block_hash, local_tip.hash().into()); + assert_eq!(parent_block_hash, local_tip.hash()); let l2block_number: u64 = l2block.raw().number().unpack(); let local_tip_number: u64 = local_tip.raw().number().unpack(); @@ -763,7 +757,7 @@ impl Chain { Ok(()) } RevertL1ActionContext::RewindToLastValidTip => { - let local_state_tip_hash: H256 = self.local_state.tip.hash().into(); + let local_state_tip_hash: H256 = self.local_state.tip.hash(); let last_valid_tip_block_hash = db.get_last_valid_tip_block_hash()?; let local_state_global_state = &self.local_state.last_global_state; @@ -887,7 +881,7 @@ impl Chain { // and get reclaimed. Finalized custodians may be merged in bad block submit tx and this // will not be reverted. let is_bad_block_reverted = has_bad_block_before_update && self.challenge_target.is_none(); - let tip_block_hash: H256 = self.local_state.tip.hash().into(); + let tip_block_hash: H256 = self.local_state.tip.hash(); if let Some(mem_pool) = &self.mem_pool { if matches!(self.last_sync_event, SyncEvent::Success) && (is_l1_revert_happend || is_bad_block_reverted) @@ -912,8 +906,8 @@ impl Chain { }; assert_eq!( - db.state_smt().unwrap().root(), - &expected_account.merkle_root().unpack(), + H256::from(*db.state_smt().unwrap().root()).pack(), + expected_account.merkle_root(), "account root consistent in DB" ); @@ -1018,7 +1012,7 @@ impl Chain { deposit_info_vec: deposit_info_vec.clone(), withdrawals: withdrawals.clone(), }; - let tip_block_hash = self.local_state.tip().hash().into(); + let tip_block_hash = self.local_state.tip().hash(); let chain_view = ChainView::new(&db, tip_block_hash); { @@ -1141,7 +1135,7 @@ fn package_bad_blocks(db: &StoreTransaction, start_block_hash: &H256) -> Result< .collect(); blocks.reverse(); ensure!( - blocks.first().map(|b| b.hash().into()) == Some(*start_block_hash), + blocks.first().map(|b| b.hash()) == Some(*start_block_hash), "package_bad_blocks: start block hash does not match" ); Ok(blocks) diff --git a/crates/challenge/Cargo.toml b/crates/challenge/Cargo.toml index f90d163de..bab62a2ae 100644 --- a/crates/challenge/Cargo.toml +++ b/crates/challenge/Cargo.toml @@ -1,15 +1,16 @@ [package] name = "gw-challenge" -version = "1.8.0-rc1" +version = "1.8.0-rc2" authors = ["Nervos Network"] edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -gw-common = { path = "../common" } +gw-types = { path = "../../gwos/crates/types" } +gw-common = { path = "../../gwos/crates/common" } +gw-smt = { path = "../smt" } gw-config = { path = "../config" } -gw-types = { path = "../types" } gw-db = { path = "../db" } gw-store = { path = "../store" } gw-generator = { path = "../generator" } diff --git a/crates/challenge/src/cancel_challenge.rs b/crates/challenge/src/cancel_challenge.rs index ea151b187..9c013a9ca 100644 --- a/crates/challenge/src/cancel_challenge.rs +++ b/crates/challenge/src/cancel_challenge.rs @@ -2,9 +2,9 @@ use crate::types::{VerifyContext, VerifyWitness}; use anyhow::{anyhow, Result}; use ckb_types::prelude::{Builder, Entity}; -use gw_common::H256; use gw_config::ContractsCellDep; use gw_types::core::{DepType, SigningType, Status}; +use gw_types::h256::*; use gw_types::offchain::{CellInfo, InputCellInfo, RecoverAccount}; use gw_types::packed::{ CCTransactionSignatureWitness, CCTransactionWitness, CCWithdrawalWitness, CellDep, CellInput, @@ -67,7 +67,6 @@ pub struct CancelChallengeOutput { impl CancelChallengeOutput { pub fn verifier_input(&self, tx_hash: H256, tx_index: u32) -> InputCellInfo { let (output, data) = self.verifier_cell.clone(); - let tx_hash: [u8; 32] = tx_hash.into(); let out_point = OutPoint::new_builder() .tx_hash(tx_hash.pack()) @@ -173,7 +172,7 @@ pub fn build_output( witness, ); - let data = cancel.build_verifier_data(receiver_script.hash().into()); + let data = cancel.build_verifier_data(receiver_script.hash()); Ok(cancel.build_output(data, Some(verifier_witness), None, None)) } VerifyWitness::TxExecution { @@ -226,7 +225,7 @@ pub fn build_output( }; let recover_accounts = { - let owner_lock_hash = owner_lock.hash().into(); + let owner_lock_hash = owner_lock.hash(); let accounts = recover_accounts.into_iter(); let to_cell = accounts.map(|a| build_recover_account_cell(owner_lock_hash, a)); let (cells, witnesses) = to_cell.unzip(); @@ -421,13 +420,11 @@ impl<'a> CancelChallenge<'a, CCTransactionSignatureWitness> { fn calc_tx_message(&self, receiver_script_hash: &H256) -> [u8; 32] { let raw_tx = self.verify_witness.l2tx().raw(); - raw_tx - .calc_message( - &self.rollup_type_hash, - &H256::from(self.verifier_lock.hash()), - receiver_script_hash, - ) - .into() + raw_tx.calc_message( + &self.rollup_type_hash, + &self.verifier_lock.hash(), + receiver_script_hash, + ) } } @@ -446,7 +443,7 @@ impl<'a> CancelChallenge<'a, CCWithdrawalWitness> { fn calc_withdrawal_message(&self) -> [u8; 32] { let raw_withdrawal = self.verify_witness.withdrawal().raw(); - raw_withdrawal.calc_message(&self.rollup_type_hash).into() + raw_withdrawal.calc_message(&self.rollup_type_hash) } } diff --git a/crates/challenge/src/context.rs b/crates/challenge/src/context.rs index 31a6b1385..fa30925b3 100644 --- a/crates/challenge/src/context.rs +++ b/crates/challenge/src/context.rs @@ -3,14 +3,14 @@ use crate::types::{RevertContext, RevertWitness, VerifyContext, VerifyWitness}; use anyhow::{anyhow, Result}; -use gw_common::h256_ext::H256Ext; +use gw_common::blake2b::new_blake2b; use gw_common::merkle_utils::{calculate_state_checkpoint, ckb_merkle_leaf_hash, CBMT}; -use gw_common::smt::Blake2bHasher; -use gw_common::sparse_merkle_tree::CompiledMerkleProof; use gw_common::state::State; -use gw_common::{blake2b::new_blake2b, H256}; use gw_generator::traits::StateExt; use gw_generator::{types::vm::ChallengeContext, Generator}; +use gw_smt::smt::{Blake2bHasher, SMTH256}; +use gw_smt::smt_h256_ext::SMTH256Ext; +use gw_smt::sparse_merkle_tree::CompiledMerkleProof; use gw_store::chain_view::ChainView; use gw_store::state::history::history_state::{RWConfig, ReadOpt, WriteOpt}; use gw_store::state::{BlockStateDB, MemStateDB}; @@ -18,6 +18,7 @@ use gw_store::traits::chain_store::ChainStore; use gw_store::transaction::StoreTransaction; use gw_traits::CodeStore; use gw_types::core::ChallengeTargetType; +use gw_types::h256::*; use gw_types::offchain::RecoverAccount; use gw_types::packed::{ BlockHashEntry, BlockHashEntryVec, BlockInfo, Byte32, Bytes, CCTransactionSignatureWitness, @@ -90,14 +91,14 @@ pub fn build_revert_context( // Build reverted block proof let (post_reverted_block_root, reverted_block_proof) = { let mut smt = db.reverted_block_smt()?; - let to_key = |b: &RawL2Block| H256::from(b.hash()); + let to_key = |b: &RawL2Block| SMTH256::from(b.hash()); - let keys: Vec = reverted_raw_blocks.iter().map(to_key).collect(); + let keys: Vec = reverted_raw_blocks.iter().map(to_key).collect(); for key in keys.iter() { - smt.update(key.to_owned(), H256::one())?; + smt.update(key.to_owned(), SMTH256::one())?; } - let root = smt.root().to_owned(); + let root: H256 = (*smt.root()).into(); let proof = smt.merkle_proof(keys.clone())?.compile(keys.clone())?; (root, proof) @@ -527,7 +528,7 @@ fn build_block_proof( let block_proof = { let smt = db.block_smt()?; - let smt_keys: Vec = raw_blocks.iter().map(|rb| rb.smt_key().into()).collect(); + let smt_keys: Vec = raw_blocks.iter().map(|rb| rb.smt_key().into()).collect(); smt.merkle_proof(smt_keys.clone())?.compile(smt_keys)? }; @@ -536,11 +537,11 @@ fn build_block_proof( #[cfg(test)] mod tests { - use gw_common::{ - merkle_utils::{calculate_ckb_merkle_root, ckb_merkle_leaf_hash, CBMTMerkleProof}, - H256, + use gw_common::merkle_utils::{ + calculate_ckb_merkle_root, ckb_merkle_leaf_hash, CBMTMerkleProof, }; use gw_types::{ + h256::*, packed::{L2Block, L2Transaction, RawL2Transaction}, prelude::*, }; @@ -598,10 +599,9 @@ mod tests { .map(|(id, l)| ckb_merkle_leaf_hash(id as u32, &l.witness_hash().into())) .collect(), ); - assert!(root.is_ok()); // verify - assert!(proof.verify(&root.unwrap(), &proof_leaves)); + assert!(proof.verify(&root, &proof_leaves)); } } } diff --git a/crates/challenge/src/enter_challenge.rs b/crates/challenge/src/enter_challenge.rs index cd50335bd..15d5513c1 100644 --- a/crates/challenge/src/enter_challenge.rs +++ b/crates/challenge/src/enter_challenge.rs @@ -1,7 +1,7 @@ use ckb_types::prelude::{Builder, Entity}; -use gw_common::H256; use gw_generator::types::vm::ChallengeContext; use gw_types::core::{ScriptHashType, Status}; +use gw_types::h256::*; use gw_types::packed::{ Byte32, CellOutput, ChallengeLockArgs, ChallengeTarget, ChallengeWitness, GlobalState, RollupAction, RollupActionUnion, RollupEnterChallenge, Script, WitnessArgs, diff --git a/crates/challenge/src/offchain.rs b/crates/challenge/src/offchain.rs index 0cccb5823..3bb832620 100644 --- a/crates/challenge/src/offchain.rs +++ b/crates/challenge/src/offchain.rs @@ -3,13 +3,13 @@ use anyhow::{anyhow, bail, Result}; use ckb_chain_spec::consensus::MAX_BLOCK_BYTES; use gw_common::registry_address::RegistryAddress; -use gw_common::H256; use gw_config::{BlockProducerConfig, DebugConfig, OffChainValidatorConfig}; use gw_rpc_client::contract::ContractsCellDepManager; use gw_rpc_client::rpc_client::RPCClient; use gw_store::state::MemStateDB; use gw_store::transaction::StoreTransaction; use gw_types::core::DepType; +use gw_types::h256::*; use gw_types::offchain::{CellInfo, InputCellInfo}; use gw_types::packed::{ CellDep, CellInput, L2Block, OutPoint, OutPointVec, WithdrawalRequestExtra, diff --git a/crates/challenge/src/offchain/mock_block.rs b/crates/challenge/src/offchain/mock_block.rs index f00f4b3f6..9116063b5 100644 --- a/crates/challenge/src/offchain/mock_block.rs +++ b/crates/challenge/src/offchain/mock_block.rs @@ -1,23 +1,23 @@ use crate::types::{VerifyContext, VerifyWitness}; use anyhow::{anyhow, bail, Context, Result}; -use gw_common::h256_ext::H256Ext; use gw_common::merkle_utils::{ calculate_ckb_merkle_root, calculate_state_checkpoint, ckb_merkle_leaf_hash, CBMT, }; use gw_common::registry_address::RegistryAddress; -use gw_common::smt::{Blake2bHasher, SMT}; -use gw_common::sparse_merkle_tree::default_store::DefaultStore; use gw_common::state::{ build_account_field_key, State, GW_ACCOUNT_NONCE_TYPE, GW_ACCOUNT_SCRIPT_HASH_TYPE, }; -use gw_common::H256; use gw_generator::traits::StateExt; +use gw_smt::smt::{Blake2bHasher, SMT, SMTH256}; +use gw_smt::smt_h256_ext::SMTH256Ext; +use gw_smt::sparse_merkle_tree::default_store::DefaultStore; use gw_store::state::traits::JournalDB; use gw_store::state::MemStateDB; use gw_store::transaction::StoreTransaction; use gw_traits::CodeStore; -use gw_types::core::{ChallengeTargetType, Status, Timepoint}; +use gw_types::core::{ChallengeTargetType, Status}; +use gw_types::h256::*; use gw_types::offchain::RunResult; use gw_types::packed::{ AccountMerkleState, BlockMerkleState, Byte32, CCTransactionSignatureWitness, @@ -25,13 +25,12 @@ use gw_types::packed::{ RawL2Block, Script, SubmitTransactions, SubmitWithdrawals, Uint64, WithdrawalRequestExtra, }; use gw_types::prelude::*; -use gw_utils::RollupContext; +use gw_utils::{global_state_finalized_timepoint, RollupContext}; type MemTree = MemStateDB; pub struct MockBlockParam { rollup_context: RollupContext, - finality_blocks: u64, number: u64, rollup_config_hash: Byte32, block_producer: RegistryAddress, @@ -61,7 +60,6 @@ impl MockBlockParam { reverted_block_root: H256, ) -> Self { MockBlockParam { - finality_blocks: rollup_context.rollup_config.finality_blocks().unpack(), rollup_config_hash: rollup_context.rollup_config.hash().pack(), rollup_context, block_producer, @@ -301,14 +299,16 @@ impl MockBlockParam { ) -> Result { let block_smt = db.block_smt()?; let block_proof = block_smt - .merkle_proof(vec![H256::from_u64(self.number)]) + .merkle_proof(vec![SMTH256::from_u64(self.number)]) .map_err(|err| anyhow!("merkle proof error: {:?}", err))? - .compile(vec![H256::from_u64(self.number)])?; + .compile(vec![SMTH256::from_u64(self.number)])?; let post_block = { - let post_block_root = block_proof.compute_root::(vec![( - raw_block.smt_key().into(), - raw_block.hash().into(), - )])?; + let post_block_root: H256 = block_proof + .compute_root::(vec![( + raw_block.smt_key().into(), + raw_block.hash().into(), + )])? + .into(); let block_count = self.number + 1; BlockMerkleState::new_builder() .merkle_root(post_block_root.pack()) @@ -316,15 +316,12 @@ impl MockBlockParam { .build() }; - let last_finalized_timepoint = if self - .rollup_context - .fork_config - .use_timestamp_as_timepoint(self.number) - { - unimplemented!() - } else { - Timepoint::from_block_number(self.number.saturating_sub(self.finality_blocks)) - }; + let last_finalized_timepoint = global_state_finalized_timepoint( + &self.rollup_context.rollup_config, + &self.rollup_context.fork_config, + self.number, + self.timestamp.unpack(), + ); let global_state = GlobalState::new_builder() .account(post_account) .block(post_block) @@ -344,9 +341,9 @@ impl MockBlockParam { sender_script: Script, owner_lock: Script, ) -> Result { - let mut tree: SMT> = Default::default(); + let mut tree: SMT> = Default::default(); for (index, witness_hash) in self.withdrawals.witness_hashes.iter().enumerate() { - tree.update(H256::from_u32(index as u32), witness_hash.to_owned())?; + tree.update(SMTH256::from_u32(index as u32), (*witness_hash).into())?; } let withdrawal_index = self.withdrawals.witness_hashes.len().saturating_sub(1) as u32; @@ -391,11 +388,11 @@ impl MockBlockParam { let kv_state: Vec<(H256, H256)> = vec![ ( build_account_field_key(sender_id, GW_ACCOUNT_SCRIPT_HASH_TYPE), - sender_script.hash().into(), + sender_script.hash(), ), ( build_account_field_key(receiver_id, GW_ACCOUNT_SCRIPT_HASH_TYPE), - receiver_script.hash().into(), + receiver_script.hash(), ), ( build_account_field_key(sender_id, GW_ACCOUNT_NONCE_TYPE), @@ -407,7 +404,7 @@ impl MockBlockParam { Unpack::::unpack(&tx.raw().nonce()) ); - let touched_keys: Vec = kv_state.iter().map(|(key, _)| key.to_owned()).collect(); + let touched_keys: Vec = kv_state.iter().map(|(key, _)| (*key).into()).collect(); let kv_state_proof = { let smt = mem_tree.inner_smt_tree(); smt.merkle_proof(touched_keys.clone())? @@ -584,12 +581,12 @@ impl RawBlockWithdrawalRequests { } fn contains(&self, req: &WithdrawalRequestExtra) -> bool { - self.witness_hashes.contains(&req.witness_hash().into()) + self.witness_hashes.contains(&req.witness_hash()) } fn push(&mut self, req: WithdrawalRequestExtra, post_account: AccountMerkleState) { let wth_index = self.witness_hashes.len() as u32; - let witness_hash: H256 = req.witness_hash().into(); + let witness_hash: H256 = req.witness_hash(); let merkle_leaf_hash = ckb_merkle_leaf_hash(wth_index, &witness_hash); self.witness_hashes.push(witness_hash); @@ -599,8 +596,7 @@ impl RawBlockWithdrawalRequests { } fn submit_withdrawals(&self) -> Result { - let root = calculate_ckb_merkle_root(self.merkle_leaf_hashes.clone()) - .map_err(|err| anyhow!("mock submit withdrawal error: {}", err))?; + let root = calculate_ckb_merkle_root(self.merkle_leaf_hashes.clone()); let count = self.inner.len() as u32; Ok(SubmitWithdrawals::new_builder() @@ -641,12 +637,12 @@ impl RawBlockTransactions { } fn contains(&self, tx: &L2Transaction) -> bool { - self.witness_hashes.contains(&tx.witness_hash().into()) + self.witness_hashes.contains(&tx.witness_hash()) } fn push(&mut self, tx: L2Transaction, post_account: AccountMerkleState) { let tx_index = self.merkle_leaf_hashes.len() as u32; - let witness_hash: H256 = tx.witness_hash().into(); + let witness_hash: H256 = tx.witness_hash(); let merkle_leaf_hash = ckb_merkle_leaf_hash(tx_index, &witness_hash); self.witness_hashes.push(witness_hash); @@ -656,8 +652,7 @@ impl RawBlockTransactions { } fn submit_transactions(&self) -> Result { - let root = calculate_ckb_merkle_root(self.merkle_leaf_hashes.clone()) - .map_err(|err| anyhow!("mock submit transaction error: {}", err))?; + let root = calculate_ckb_merkle_root(self.merkle_leaf_hashes.clone()); let count = self.inner.len() as u32; Ok(SubmitTransactions::new_builder() diff --git a/crates/challenge/src/offchain/mock_tx.rs b/crates/challenge/src/offchain/mock_tx.rs index ae358776b..cf3851c65 100644 --- a/crates/challenge/src/offchain/mock_tx.rs +++ b/crates/challenge/src/offchain/mock_tx.rs @@ -12,10 +12,10 @@ use gw_utils::wallet::Wallet; use anyhow::Result; use arc_swap::Guard; use gw_common::blake2b::new_blake2b; -use gw_common::H256; use gw_config::{BlockProducerConfig, ContractsCellDep}; use gw_generator::types::vm::ChallengeContext; use gw_types::bytes::Bytes; +use gw_types::h256::*; use gw_types::offchain::{CellInfo, InputCellInfo}; use gw_types::packed::{ Byte32, CellDep, CellInput, CellOutput, ChallengeTarget, ChallengeWitness, GlobalState, diff --git a/crates/challenge/src/revert.rs b/crates/challenge/src/revert.rs index dbffdd741..5ee3b4a5c 100644 --- a/crates/challenge/src/revert.rs +++ b/crates/challenge/src/revert.rs @@ -3,9 +3,9 @@ use crate::types::{RevertContext, RevertWitness}; use anyhow::{anyhow, Result}; use ckb_types::prelude::Reader; use ckb_types::prelude::{Builder, Entity}; -use gw_common::smt::Blake2bHasher; -use gw_common::H256; -use gw_types::core::{Status, Timepoint}; +use gw_smt::smt::{Blake2bHasher, SMTH256}; +use gw_types::core::Status; +use gw_types::h256::H256; use gw_types::offchain::CellInfo; use gw_types::packed::BlockMerkleState; use gw_types::packed::ChallengeLockArgsReader; @@ -19,11 +19,10 @@ use gw_types::{ bytes::Bytes, prelude::{Pack, Unpack}, }; -use gw_utils::RollupContext; +use gw_utils::{global_state_finalized_timepoint, RollupContext}; pub struct Revert<'a> { rollup_context: RollupContext, - finality_blocks: u64, reward_burn_rate: u8, prev_global_state: GlobalState, challenge_cell: &'a CellInfo, // capacity and rewards lock @@ -50,17 +49,15 @@ impl<'a> Revert<'a> { revert_context: RevertContext, ) -> Self { let reward_burn_rate = rollup_context.rollup_config.reward_burn_rate().into(); - let finality_blocks = rollup_context.rollup_config.finality_blocks().unpack(); Revert { rollup_context, - finality_blocks, prev_global_state, challenge_cell, stake_cells, burn_lock, reward_burn_rate, - post_reverted_block_root: revert_context.post_reverted_block_root.into(), + post_reverted_block_root: revert_context.post_reverted_block_root, revert_witness: revert_context.revert_witness, } } @@ -86,12 +83,14 @@ impl<'a> Revert<'a> { }; let block_merkle_state = { let leaves = { - let to_leave = |b: RawL2Block| (b.smt_key().into(), H256::zero()); + let to_leave = |b: RawL2Block| (b.smt_key().into(), SMTH256::zero()); let reverted_blocks = self.revert_witness.reverted_blocks.clone(); reverted_blocks.into_iter().map(to_leave) }; let block_merkle_proof = self.revert_witness.block_proof.clone(); - let block_root = block_merkle_proof.compute_root::(leaves.collect())?; + let block_root: H256 = block_merkle_proof + .compute_root::(leaves.collect())? + .into(); let block_count = first_reverted_block.number(); BlockMerkleState::new_builder() @@ -99,26 +98,27 @@ impl<'a> Revert<'a> { .count(block_count) .build() }; - let last_finalized_timepoint = if self - .rollup_context - .fork_config - .use_timestamp_as_timepoint(first_reverted_block.number().unpack()) - { - Timepoint::Timestamp( - first_reverted_block - .timestamp() - .unpack() - .saturating_sub(self.rollup_context.rollup_config.finality_time_in_ms()), - ) - } else { - Timepoint::from_block_number( - first_reverted_block - .number() - .unpack() - .saturating_sub(1) - .saturating_sub(self.finality_blocks), - ) - }; + + // NOTE: When revert in v1, `Fork::use_timestamp_as_timepoint()` is disabled, + // revert the last_finalized_timepoint to the **the previous block that did not revert**; + // when revert in v2, `Fork::use_timestamp_as_timepoint()` is enabled, + // keep the last_finalized_timepoint up to date, which is the last block timestamp + let last_reverted_block = self + .revert_witness + .reverted_blocks + .clone() + .into_iter() + .last() + .ok_or_else(|| anyhow!("no last block"))?; + let last_block_timestamp = last_reverted_block.timestamp().unpack(); + let previous_non_reverted_block_number = + first_reverted_block.number().unpack().saturating_sub(1); + let reverted_last_finalized_timepoint = global_state_finalized_timepoint( + &self.rollup_context.rollup_config, + &self.rollup_context.fork_config, + previous_non_reverted_block_number, + last_block_timestamp, + ); let running_status: u8 = Status::Running.into(); let post_global_state = self @@ -128,7 +128,7 @@ impl<'a> Revert<'a> { .block(block_merkle_state) .tip_block_hash(first_reverted_block.parent_block_hash()) .tip_block_timestamp(self.revert_witness.new_tip_block.timestamp()) - .last_finalized_timepoint(last_finalized_timepoint.full_value().pack()) + .last_finalized_timepoint(reverted_last_finalized_timepoint.full_value().pack()) .reverted_block_root(self.post_reverted_block_root.pack()) .status(running_status.into()) .build(); diff --git a/crates/challenge/src/types.rs b/crates/challenge/src/types.rs index 5d2b5a8f2..95703d8f3 100644 --- a/crates/challenge/src/types.rs +++ b/crates/challenge/src/types.rs @@ -1,4 +1,5 @@ -use gw_common::{sparse_merkle_tree::CompiledMerkleProof, H256}; +use gw_smt::sparse_merkle_tree::CompiledMerkleProof; +use gw_types::h256::*; use gw_types::offchain::RecoverAccount; use gw_types::packed::{ Bytes, CCTransactionSignatureWitness, CCTransactionWitness, CCWithdrawalWitness, RawL2Block, diff --git a/crates/config/Cargo.toml b/crates/config/Cargo.toml index 5b676d7cf..85c7b4b16 100644 --- a/crates/config/Cargo.toml +++ b/crates/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gw-config" -version = "1.8.0-rc1" +version = "1.8.0-rc2" authors = ["Nervos Network"] edition = "2018" diff --git a/crates/config/src/config.rs b/crates/config/src/config.rs index 393978aa3..b76008980 100644 --- a/crates/config/src/config.rs +++ b/crates/config/src/config.rs @@ -79,7 +79,10 @@ pub struct RPCServerConfig { #[derive(Clone, Default, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(deny_unknown_fields)] pub struct RPCClientConfig { - pub indexer_url: String, + /// Specify standalone ckb indexer URL. + /// + /// If this is None we use CKB builtin indexer RPC instead. + pub indexer_url: Option, pub ckb_url: String, } diff --git a/crates/db/Cargo.toml b/crates/db/Cargo.toml index d46859c88..b244bff18 100644 --- a/crates/db/Cargo.toml +++ b/crates/db/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gw-db" -version = "1.8.0-rc1" +version = "1.8.0-rc2" authors = ["Nervos Network"] edition = "2018" diff --git a/crates/dynamic-config/Cargo.toml b/crates/dynamic-config/Cargo.toml index 01b1e64f7..efdd65927 100644 --- a/crates/dynamic-config/Cargo.toml +++ b/crates/dynamic-config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gw-dynamic-config" -version = "1.8.0-rc1" +version = "1.8.0-rc2" authors = ["Nervos Network"] edition = "2018" diff --git a/crates/dynamic-config/src/whitelist_config.rs b/crates/dynamic-config/src/whitelist_config.rs index d2d1ae635..84293c6b3 100644 --- a/crates/dynamic-config/src/whitelist_config.rs +++ b/crates/dynamic-config/src/whitelist_config.rs @@ -58,7 +58,7 @@ fn get_allow_list( rpc_config .sudt_proxy_code_hashes .into_iter() - .map(|hash| hash.0.into()) + .map(|hash| hash.0) .collect(), ); ( diff --git a/crates/generator/Cargo.toml b/crates/generator/Cargo.toml index 04e61f060..a2648b687 100644 --- a/crates/generator/Cargo.toml +++ b/crates/generator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gw-generator" -version = "1.8.0-rc1" +version = "1.8.0-rc2" authors = ["Nervos Network"] edition = "2018" @@ -12,8 +12,9 @@ detect-asm = ["ckb-vm/detect-asm", "ckb-vm-aot"] enable-always-success-lock = [] [dependencies] -gw-types = { path = "../types" } -gw-common = { path = "../common" } +gw-types = { path = "../../gwos/crates/types" } +gw-common = { path = "../../gwos/crates/common" } +gw-smt = { path = "../smt" } gw-config = { path = "../config" } gw-store = { path = "../store" } gw-traits = { path = "../traits" } @@ -25,7 +26,7 @@ ckb-vm-aot = { version = "=0.22.0", optional = true } thiserror = "1.0" lazy_static = "1.4" rlp = "0.5.0" -secp256k1 = { version = "0.20", features = ["recovery"] } +secp256k1 = { version = "0.24", features = ["recovery"] } substrate-bn = { git = "https://github.com/paritytech/bn.git", rev = "63f8c58" } sha3 = "0.10.6" log = "0.4" diff --git a/crates/generator/src/account_lock_manage/always_success.rs b/crates/generator/src/account_lock_manage/always_success.rs index 8e7c613e5..a232f4e9b 100644 --- a/crates/generator/src/account_lock_manage/always_success.rs +++ b/crates/generator/src/account_lock_manage/always_success.rs @@ -1,6 +1,7 @@ -use gw_common::{registry_address::RegistryAddress, H256}; +use gw_common::registry_address::RegistryAddress; use gw_types::{ bytes::Bytes, + h256::*, packed::{L2Transaction, Script}, }; use gw_utils::RollupContext; diff --git a/crates/generator/src/account_lock_manage/eip712/types.rs b/crates/generator/src/account_lock_manage/eip712/types.rs index ce8b91154..780c509bd 100644 --- a/crates/generator/src/account_lock_manage/eip712/types.rs +++ b/crates/generator/src/account_lock_manage/eip712/types.rs @@ -1,9 +1,10 @@ use std::convert::{TryFrom, TryInto}; use anyhow::{anyhow, bail, Result}; -use gw_common::{builtins::ETH_REGISTRY_ACCOUNT_ID, H256}; +use gw_common::builtins::ETH_REGISTRY_ACCOUNT_ID; use gw_types::{ core::ScriptHashType, + h256::*, packed::{RawL2Transaction, RawWithdrawalRequest}, prelude::Unpack, }; @@ -182,7 +183,7 @@ impl L2Transaction { chain_id: data.chain_id().unpack(), nonce: data.nonce().unpack(), from: sender_address, - to: to_script_hash.into(), + to: to_script_hash, args: data.args().unpack(), }; Ok(tx) @@ -466,7 +467,7 @@ mod tests { buf }; let pubkey_hash = Secp256k1Eth::default() - .recover(message.into(), &signature) + .recover(message, &signature) .unwrap(); assert_eq!(hex::encode(mail.from.wallet), hex::encode(pubkey_hash)); } @@ -517,7 +518,7 @@ mod tests { let message = withdrawal.eip712_message(domain_seperator.hash_struct()); let signature: [u8; 65] = hex::decode("22cae59f1bfaf58f423d1a414cbcaefd45a89dd54c9142fccbb2473c74f4741b45f77f1f3680b8c0b6362957c8d79f96a683a859ccbf22a6cfc1ebc311b936d301").unwrap().try_into().unwrap(); let pubkey_hash = Secp256k1Eth::default() - .recover(message.into(), &signature) + .recover(message, &signature) .unwrap(); assert_eq!( "cc3e7fb0176a0e22a7f675306ceeb61d26eb0dc4".to_string(), @@ -555,7 +556,7 @@ mod tests { let message = tx.eip712_message(domain_seperator.hash_struct()); let signature: [u8; 65] = hex::decode("64b164f5303000c283119974d7ba8f050cc7429984af904134d5cda6d3ce045934cc6b6f513ec939c2ae4cfb9cbee249ba8ae86f6274e4035c150f9c8e634a3a1b").unwrap().try_into().unwrap(); let pubkey_hash = Secp256k1Eth::default() - .recover(message.into(), &signature) + .recover(message, &signature) .unwrap(); assert_eq!( "e8ae579256c3b84efb76bbb69cb6bcbef1375f00".to_string(), diff --git a/crates/generator/src/account_lock_manage/mod.rs b/crates/generator/src/account_lock_manage/mod.rs index 2e91d5aff..6dcac0c85 100644 --- a/crates/generator/src/account_lock_manage/mod.rs +++ b/crates/generator/src/account_lock_manage/mod.rs @@ -1,6 +1,7 @@ use std::{collections::HashMap, sync::Arc}; -use gw_common::{registry_address::RegistryAddress, H256}; +use gw_common::registry_address::RegistryAddress; +use gw_types::h256::*; use gw_types::{ bytes::Bytes, packed::{L2Transaction, Script, WithdrawalRequestExtra}, diff --git a/crates/generator/src/account_lock_manage/secp256k1.rs b/crates/generator/src/account_lock_manage/secp256k1.rs index ffc7b9e71..cd84d58ad 100644 --- a/crates/generator/src/account_lock_manage/secp256k1.rs +++ b/crates/generator/src/account_lock_manage/secp256k1.rs @@ -7,17 +7,17 @@ use crate::account_lock_manage::eip712::types::Withdrawal; use crate::error::LockAlgorithmError; use anyhow::bail; use gw_common::registry_address::RegistryAddress; -use gw_common::H256; use gw_types::packed::WithdrawalRequestExtra; use gw_types::prelude::*; use gw_types::{ bytes::Bytes, + h256::*, packed::{L2Transaction, RawL2Transaction, Script}, }; use gw_utils::polyjuice_parser::PolyjuiceParser; use gw_utils::RollupContext; use lazy_static::lazy_static; -use secp256k1::recovery::{RecoverableSignature, RecoveryId}; +use secp256k1::ecdsa::{RecoverableSignature, RecoveryId}; use sha3::{Digest, Keccak256}; lazy_static! { @@ -55,7 +55,7 @@ impl Secp256k1Eth { hasher.update(&rlp_data); let signing_message: [u8; 32] = hasher.finalize().into(); - Ok(signing_message.into()) + Ok(signing_message) } pub fn eip712_signing_message( @@ -71,7 +71,7 @@ impl Secp256k1Eth { )?; let message = typed_tx.eip712_message(Self::domain_with_chain_id(chain_id).hash_struct()); - Ok(message.into()) + Ok(message) } pub fn domain_with_chain_id(chain_id: u64) -> EIP712Domain { @@ -133,7 +133,7 @@ impl LockAlgorithm for Secp256k1Eth { let msg = secp256k1::Message::from_slice(message.as_slice()) .map_err(|err| LockAlgorithmError::InvalidSignature(err.to_string()))?; let pubkey = SECP256K1 - .recover(&msg, &signature) + .recover_ecdsa(&msg, &signature) .map_err(|err| LockAlgorithmError::InvalidSignature(err.to_string()))?; let mut hasher = Keccak256::new(); @@ -164,7 +164,6 @@ impl LockAlgorithm for Secp256k1Eth { let mut hasher = Keccak256::new(); hasher.update(&rlp_data); let signing_message: [u8; 32] = hasher.finalize().into(); - let signing_message = H256::from(signing_message); self.verify_alone( sender_script.args().unpack(), tx.signature().unpack(), @@ -182,7 +181,7 @@ impl LockAlgorithm for Secp256k1Eth { let raw_tx = tx.raw(); let chain_id = raw_tx.chain_id().unpack(); - let to_script_hash = receiver_script.hash().into(); + let to_script_hash = receiver_script.hash(); let typed_tx = crate::account_lock_manage::eip712::types::L2Transaction::from_raw( &raw_tx, @@ -196,7 +195,7 @@ impl LockAlgorithm for Secp256k1Eth { self.verify_alone( sender_script.args().unpack(), tx.signature().unpack(), - message.into(), + message, )?; Ok(()) } @@ -229,7 +228,7 @@ impl LockAlgorithm for Secp256k1Eth { self.verify_alone( sender_script.args().unpack(), withdrawal.request().signature().unpack(), - message.into(), + message, )?; Ok(()) } diff --git a/crates/generator/src/backend_manage.rs b/crates/generator/src/backend_manage.rs index 627bca105..2bcb2b4d2 100644 --- a/crates/generator/src/backend_manage.rs +++ b/crates/generator/src/backend_manage.rs @@ -1,7 +1,8 @@ use anyhow::{bail, Context, Result}; -use gw_common::{blake2b::new_blake2b, H256}; +use gw_common::blake2b::new_blake2b; use gw_config::{BackendConfig, BackendForkConfig, BackendType}; use gw_types::bytes::Bytes; +use gw_types::h256::*; use std::{collections::HashMap, fs}; #[cfg(has_asm)] @@ -44,14 +45,14 @@ impl Backend { hasher.update(&validator); let mut buf = [0u8; 32]; hasher.finalize(&mut buf); - buf.into() + buf }; let generator = { let mut hasher = new_blake2b(); hasher.update(&generator); let mut buf = [0u8; 32]; hasher.finalize(&mut buf); - buf.into() + buf }; BackendCheckSum { @@ -127,13 +128,9 @@ impl BackendManage { format!("load generator from {}", generator_path.to_string_lossy()) })? .into(); - let validator_script_type_hash = { - let hash: [u8; 32] = validator_script_type_hash.into(); - hash.into() - }; let backend = Backend::new( backend_type, - validator_script_type_hash, + validator_script_type_hash.into(), validator, generator, ); @@ -248,24 +245,15 @@ mod tests { }; m.register_backend_fork(config, false).unwrap(); assert!(m.get_backends_at_height(0).is_none(), "no backends at 0"); + assert!(m.get_backend(1, &[42u8; 32]).is_some(), "get backend at 1"); assert!( - m.get_backend(1, &[42u8; 32].into()).is_some(), - "get backend at 1" - ); - assert!( - m.get_backend(100, &[42u8; 32].into()).is_some(), + m.get_backend(100, &[42u8; 32]).is_some(), "get backend at 100" ); + assert!(m.get_backend(0, &[43u8; 32]).is_none(), "get backend at 0"); + assert!(m.get_backend(1, &[43u8; 32]).is_some(), "get backend at 1"); assert!( - m.get_backend(0, &[43u8; 32].into()).is_none(), - "get backend at 0" - ); - assert!( - m.get_backend(1, &[43u8; 32].into()).is_some(), - "get backend at 1" - ); - assert!( - m.get_backend(100, &[43u8; 32].into()).is_some(), + m.get_backend(100, &[43u8; 32]).is_some(), "get backend at 100" ); @@ -290,55 +278,34 @@ mod tests { assert!(m.get_backends_at_height(0).is_none(), "no backends at 0"); // sudt assert_eq!( - m.get_backend(4, &[42u8; 32].into()) - .unwrap() - .generator - .to_vec(), + m.get_backend(4, &[42u8; 32]).unwrap().generator.to_vec(), b"sudt_v0".to_vec(), ); assert_eq!( - m.get_backend(5, &[42u8; 32].into()) - .unwrap() - .generator - .to_vec(), + m.get_backend(5, &[42u8; 32]).unwrap().generator.to_vec(), b"sudt_v1".to_vec(), ); assert_eq!( - m.get_backend(42, &[42u8; 32].into()) - .unwrap() - .generator - .to_vec(), + m.get_backend(42, &[42u8; 32]).unwrap().generator.to_vec(), b"sudt_v1".to_vec(), ); // meta - assert!(m.get_backend(1, &[41u8; 32].into()).is_none()); + assert!(m.get_backend(1, &[41u8; 32]).is_none()); assert_eq!( - m.get_backend(5, &[41u8; 32].into()) - .unwrap() - .generator - .to_vec(), + m.get_backend(5, &[41u8; 32]).unwrap().generator.to_vec(), b"meta_v0".to_vec(), ); assert_eq!( - m.get_backend(42, &[41u8; 32].into()) - .unwrap() - .generator - .to_vec(), + m.get_backend(42, &[41u8; 32]).unwrap().generator.to_vec(), b"meta_v0".to_vec(), ); // addr assert_eq!( - m.get_backend(1, &[43u8; 32].into()) - .unwrap() - .generator - .to_vec(), + m.get_backend(1, &[43u8; 32]).unwrap().generator.to_vec(), b"addr_v0".to_vec(), ); assert_eq!( - m.get_backend(42, &[43u8; 32].into()) - .unwrap() - .generator - .to_vec(), + m.get_backend(42, &[43u8; 32]).unwrap().generator.to_vec(), b"addr_v0".to_vec(), ); } diff --git a/crates/generator/src/error.rs b/crates/generator/src/error.rs index cf7490e76..1a218830f 100644 --- a/crates/generator/src/error.rs +++ b/crates/generator/src/error.rs @@ -1,8 +1,9 @@ use std::borrow::Cow; use ckb_vm::Error as VMError; -use gw_common::{error::Error as StateError, sparse_merkle_tree::error::Error as SMTError, H256}; -use gw_types::{offchain::CycleMeter, packed::Byte32}; +use gw_common::error::Error as StateError; +use gw_smt::sparse_merkle_tree::error::Error as SMTError; +use gw_types::{h256::H256, offchain::CycleMeter, packed::Byte32}; use thiserror::Error; /// Error diff --git a/crates/generator/src/generator.rs b/crates/generator/src/generator.rs index 9ce87b618..9b95bd33d 100644 --- a/crates/generator/src/generator.rs +++ b/crates/generator/src/generator.rs @@ -21,10 +21,8 @@ use arc_swap::ArcSwapOption; use gw_common::{ builtins::{CKB_SUDT_ACCOUNT_ID, ETH_REGISTRY_ACCOUNT_ID}, error::Error as StateError, - h256_ext::H256Ext, registry_address::RegistryAddress, state::{build_account_key, State, SUDT_TOTAL_SUPPLY_KEY}, - H256, }; use gw_config::{ContractLogConfig, ForkConfig, SyscallCyclesConfig}; @@ -36,6 +34,8 @@ use gw_traits::{ChainView, CodeStore}; use gw_types::{ bytes::Bytes, core::{ChallengeTargetType, ScriptHashType}, + h256::H256Ext, + h256::*, offchain::{CycleMeter, RunResult}, packed::{ AccountMerkleState, BlockInfo, ChallengeTarget, DepositInfoVec, L2Block, L2Transaction, @@ -319,19 +319,16 @@ impl Generator { // check signature let account_script = state - .get_script(&account_script_hash.into()) + .get_script(&account_script_hash) .ok_or(StateError::MissingKey)?; let lock_code_hash: [u8; 32] = account_script.code_hash().unpack(); let lock_algo = self .account_lock_manage - .get_lock_algorithm(&lock_code_hash.into()) + .get_lock_algorithm(&lock_code_hash) .ok_or(LockAlgorithmError::UnknownAccountLock)?; let address = state - .get_registry_address_by_script_hash( - raw.registry_id().unpack(), - &account_script_hash.into(), - )? + .get_registry_address_by_script_hash(raw.registry_id().unpack(), &account_script_hash)? .ok_or(AccountError::RegistryAddressNotFound)?; lock_algo.verify_withdrawal(self.rollup_context(), account_script, withdrawal, address)?; @@ -374,7 +371,7 @@ impl Generator { let lock_algo = self .account_lock_manage() - .get_lock_algorithm(&lock_code_hash.into()) + .get_lock_algorithm(&lock_code_hash) .ok_or(LockAlgorithmError::UnknownAccountLock)?; let sender_address = state @@ -416,8 +413,26 @@ impl Generator { } }; - // apply withdrawal to state let block_hash = raw_block.hash(); + let skip_checkpoint_check = skipped_invalid_block_list.contains(&block_hash); + + // check prev state + if !skip_checkpoint_check { + let prev_merkle_root: H256 = raw_block.prev_account().merkle_root().unpack(); + let prev_merkle_count: u32 = raw_block.prev_account().count().unpack(); + assert_eq!( + state.calculate_root().expect("check prev root"), + prev_merkle_root, + "wrong block prev root" + ); + assert_eq!( + state.get_account_count().expect("check prev count"), + prev_merkle_count, + "wrong block prev account count" + ); + } + + // apply withdrawal to state let block_producer_address = { let block_producer: Bytes = block_info.block_producer().unpack(); match RegistryAddress::from_slice(&block_producer) { @@ -448,7 +463,7 @@ impl Generator { let now = Instant::now(); if let Err(error) = self.check_withdrawal_signature(&state, &request) { let target = build_challenge_target( - block_hash.into(), + block_hash, ChallengeTargetType::Withdrawal, wth_idx as u32, ); @@ -510,7 +525,6 @@ impl Generator { // handle transactions let mut offchain_used_cycles: u64 = 0; let mut tx_receipts = Vec::with_capacity(args.l2block.transactions().len()); - let skip_checkpoint_check = skipped_invalid_block_list.contains(&block_hash.into()); if skip_checkpoint_check { log::warn!( "skip the checkpoint check of block: #{} {}", @@ -531,7 +545,7 @@ impl Generator { let now = Instant::now(); if let Err(err) = self.check_transaction_signature(&state, &tx) { let target = build_challenge_target( - block_hash.into(), + block_hash, ChallengeTargetType::TxSignature, tx_index as u32, ); @@ -553,7 +567,7 @@ impl Generator { if actual_nonce != expected_nonce { return ApplyBlockResult::Challenge { target: build_challenge_target( - block_hash.into(), + block_hash, ChallengeTargetType::TxExecution, tx_index as u32, ), @@ -581,7 +595,7 @@ impl Generator { Ok(run_result) => run_result, Err(err) => { let target = build_challenge_target( - block_hash.into(), + block_hash, ChallengeTargetType::TxExecution, tx_index as u32, ); @@ -636,7 +650,7 @@ impl Generator { if !skip_checkpoint_check && block_checkpoint != expected_checkpoint { let target = build_challenge_target( - block_hash.into(), + block_hash, ChallengeTargetType::TxExecution, tx_index as u32, ); @@ -657,7 +671,7 @@ impl Generator { Err(err) => return ApplyBlockResult::Error(err.into()), }; let tx_receipt = - TxReceipt::build_receipt(tx.witness_hash().into(), run_result, post_state); + TxReceipt::build_receipt(tx.witness_hash(), run_result, post_state); tx_receipts.push(tx_receipt); offchain_used_cycles = offchain_used_cycles.saturating_add(used_cycles); @@ -671,12 +685,12 @@ impl Generator { assert_eq!( state.calculate_root().expect("check post root"), post_merkle_root, - "post account merkle root must be consistent" + "wrong block post root" ); assert_eq!( state.get_account_count().expect("check post count"), post_merkle_count, - "post account merkle count must be consistent" + "wrong block post account count" ); } @@ -713,8 +727,7 @@ impl Generator { if script.hash_type() == ScriptHashType::Type.into() { let code_hash: [u8; 32] = script.code_hash().unpack(); log::debug!("load_backend by code_hash: {}", hex::encode(code_hash)); - self.backend_manage - .get_backend(block_number, &code_hash.into()) + self.backend_manage.get_backend(block_number, &code_hash) } else { log::error!( "Found a invalid account script which hash_type is data: {:?}", diff --git a/crates/generator/src/genesis.rs b/crates/generator/src/genesis.rs index 018900fa2..caa3e5707 100644 --- a/crates/generator/src/genesis.rs +++ b/crates/generator/src/genesis.rs @@ -3,11 +3,11 @@ use anyhow::{Context, Result}; use gw_common::{ blake2b::new_blake2b, builtins::{CKB_SUDT_ACCOUNT_ID, ETH_REGISTRY_ACCOUNT_ID, RESERVED_ACCOUNT_ID}, - smt::{H256, SMT}, state::State, CKB_SUDT_SCRIPT_ARGS, }; use gw_config::GenesisConfig; +use gw_smt::smt::{SMT, SMTH256}; use gw_store::{ smt::smt_store::SMTStateStore, state::{ @@ -23,6 +23,7 @@ use gw_traits::CodeStore; use gw_types::{ bytes::Bytes, core::{ScriptHashType, Status}, + h256::*, packed::{ AccountMerkleState, BlockMerkleState, DepositInfoVec, FinalizedCustodianCapacity, GlobalState, L2Block, NumberHash, RawL2Block, Script, SubmitTransactions, @@ -52,10 +53,7 @@ pub fn build_genesis_from_store( secp_data: Bytes, ) -> Result<(StoreTransaction, GenesisWithGlobalState)> { let rollup_context = RollupContext { - rollup_script_hash: { - let rollup_script_hash: [u8; 32] = config.rollup_type_hash.clone().into(); - rollup_script_hash.into() - }, + rollup_script_hash: config.rollup_type_hash.clone().into(), rollup_config: config.rollup_config.clone().into(), // it's safe to give a dummy `fork_config` for genesis, because // we won't use `fork_config` at this phase. @@ -67,7 +65,7 @@ pub fn build_genesis_from_store( // build genesis state tree let mut tree = { - let smt = SMT::new(H256::zero(), SMTStateStore::new(&db)); + let smt = SMT::new(SMTH256::zero(), SMTStateStore::new(&db)); let inner = HistoryState::new(smt, 0, RWConfig::attach_block(0)); StateDB::new(inner) }; @@ -88,8 +86,7 @@ pub fn build_genesis_from_store( ); // setup CKB simple UDT contract - let ckb_sudt_script = - crate::sudt::build_l2_sudt_script(&rollup_context, &CKB_SUDT_SCRIPT_ARGS.into()); + let ckb_sudt_script = crate::sudt::build_l2_sudt_script(&rollup_context, &CKB_SUDT_SCRIPT_ARGS); let ckb_sudt_id = tree.create_account_from_script(ckb_sudt_script)?; assert_eq!( ckb_sudt_id, CKB_SUDT_ACCOUNT_ID, @@ -118,12 +115,12 @@ pub fn build_genesis_from_store( hasher.finalize(&mut hash); hash }; - tree.insert_data(secp_data_hash.into(), secp_data); + tree.insert_data(secp_data_hash, secp_data); // insert data_hash into tree - tree.store_data_hash(secp_data_hash.into())?; + tree.store_data_hash(secp_data_hash)?; tree.finalise()?; - let prev_state_checkpoint: [u8; 32] = tree.calculate_state_checkpoint()?.into(); + let prev_state_checkpoint: [u8; 32] = tree.calculate_state_checkpoint()?; let submit_txs = SubmitTransactions::new_builder() .prev_state_checkpoint(prev_state_checkpoint.pack()) .build(); @@ -207,10 +204,7 @@ pub fn init_genesis( transaction_hash: &[u8; 32], secp_data: Bytes, ) -> Result<()> { - let rollup_script_hash: H256 = { - let rollup_script_hash: [u8; 32] = config.rollup_type_hash.clone().into(); - rollup_script_hash.into() - }; + let rollup_script_hash: H256 = config.rollup_type_hash.clone().into(); if store.has_genesis()? { let chain_id = store.get_chain_id()?; if chain_id == rollup_script_hash { diff --git a/crates/generator/src/sudt.rs b/crates/generator/src/sudt.rs index 430281d4b..c17a30de4 100644 --- a/crates/generator/src/sudt.rs +++ b/crates/generator/src/sudt.rs @@ -1,5 +1,4 @@ -use gw_common::H256; -use gw_types::{bytes::Bytes, core::ScriptHashType, packed::Script, prelude::*}; +use gw_types::{bytes::Bytes, core::ScriptHashType, h256::*, packed::Script, prelude::*}; use gw_utils::RollupContext; pub fn build_l2_sudt_script(rollup_context: &RollupContext, l1_sudt_script_hash: &H256) -> Script { diff --git a/crates/generator/src/syscalls/mod.rs b/crates/generator/src/syscalls/mod.rs index b8b63d17b..10edefc6b 100644 --- a/crates/generator/src/syscalls/mod.rs +++ b/crates/generator/src/syscalls/mod.rs @@ -9,13 +9,11 @@ use ckb_vm::{ }; use gw_common::{ blake2b::new_blake2b, - h256_ext::H256Ext, registry_address::RegistryAddress, state::{ build_account_field_key, build_data_hash_key, build_script_hash_to_account_id_key, State, GW_ACCOUNT_NONCE_TYPE, GW_ACCOUNT_SCRIPT_HASH_TYPE, }, - H256, }; use gw_config::SyscallCyclesConfig; use gw_store::state::traits::JournalDB; @@ -23,6 +21,7 @@ use gw_traits::{ChainView, CodeStore}; use gw_types::{ bytes::Bytes, core::ScriptHashType, + h256::*, offchain::CycleMeter, packed::{BlockInfo, LogItem, RawL2Transaction, Script}, prelude::*, @@ -116,7 +115,7 @@ fn load_data_h256(machine: &mut Mac, addr: u64) -> Result MemStateDB { - let smt = SMT::new(H256::zero(), SMTStateStore::new(MemStore::new(store))); + let smt = SMT::new(SMTH256::zero(), SMTStateStore::new(MemStore::new(store))); let inner = MemStateTree::new(smt, 0); MemStateDB::new(inner) } @@ -46,7 +45,7 @@ fn test_account_with_duplicate_script() { ); // create duplicate account - let err2 = tree.create_account(script.hash().into()).unwrap_err(); + let err2 = tree.create_account(script.hash()).unwrap_err(); assert_eq!(err2, gw_common::error::Error::DuplicatedScriptHash); } @@ -69,13 +68,13 @@ fn test_query_account() { assert_eq!(id, expected_id as u32); assert_eq!(tree.get_account_count().unwrap(), (expected_id + 1) as u32); assert_eq!( - tree.get_account_id_by_script_hash(&script.hash().into()) + tree.get_account_id_by_script_hash(&script.hash()) .unwrap() .unwrap(), id ); - assert_eq!(tree.get_script_hash(id).unwrap(), script.hash().into()); - assert_eq!(&tree.get_script(&script.hash().into()).unwrap(), script); + assert_eq!(tree.get_script_hash(id).unwrap(), script.hash()); + assert_eq!(&tree.get_script(&script.hash()).unwrap(), script); } } @@ -185,7 +184,7 @@ fn test_data_hash() { let mut buf = [0u8; 32]; hasher.update(&data); hasher.finalize(&mut buf); - buf.into() + buf }; tree.insert_data(data_hash, data.to_vec().into()); // query data diff --git a/crates/generator/src/tests/genesis.rs b/crates/generator/src/tests/genesis.rs index 28eaab6ff..eebb9a645 100644 --- a/crates/generator/src/tests/genesis.rs +++ b/crates/generator/src/tests/genesis.rs @@ -1,5 +1,5 @@ use crate::genesis::{build_genesis, init_genesis}; -use gw_common::{sparse_merkle_tree::H256, state::State}; +use gw_common::state::State; use gw_config::GenesisConfig; use gw_store::{ state::{history::history_state::RWConfig, BlockStateDB}, @@ -7,7 +7,7 @@ use gw_store::{ Store, }; use gw_traits::CodeStore; -use gw_types::{bytes::Bytes, core::ScriptHashType, packed::RollupConfig, prelude::*}; +use gw_types::{bytes::Bytes, core::ScriptHashType, h256::*, packed::RollupConfig, prelude::*}; use std::convert::TryInto; const GENESIS_BLOCK_HASH: [u8; 32] = [ @@ -40,7 +40,7 @@ fn test_init_genesis() { assert!(tree.get_account_count().unwrap() > 0); // check prev txs state - let prev_txs_state: [u8; 32] = tree.calculate_state_checkpoint().unwrap().into(); + let prev_txs_state: [u8; 32] = tree.calculate_state_checkpoint().unwrap(); let genesis_prev_state_checkpoint: [u8; 32] = { let txs = genesis.genesis.as_reader().raw().submit_transactions(); txs.prev_state_checkpoint().unpack() diff --git a/crates/generator/src/traits.rs b/crates/generator/src/traits.rs index c4d1f3acc..d3e861538 100644 --- a/crates/generator/src/traits.rs +++ b/crates/generator/src/traits.rs @@ -3,12 +3,13 @@ use crate::sudt::build_l2_sudt_script; use gw_common::ckb_decimal::{CKBCapacity, CKB_DECIMAL_POW_EXP}; use gw_common::registry::context::RegistryContext; use gw_common::registry_address::RegistryAddress; -use gw_common::{builtins::CKB_SUDT_ACCOUNT_ID, state::State, CKB_SUDT_SCRIPT_ARGS, H256}; +use gw_common::{builtins::CKB_SUDT_ACCOUNT_ID, state::State, CKB_SUDT_SCRIPT_ARGS}; use gw_store::state::traits::JournalDB; use gw_traits::CodeStore; use gw_types::U256; use gw_types::{ core::ScriptHashType, + h256::*, packed::{AccountMerkleState, DepositRequest, Script, WithdrawalReceipt, WithdrawalRequest}, prelude::*, }; @@ -47,8 +48,8 @@ impl StateExt for S { return Err(AccountError::UnknownScript.into()); } let script_hash = script.hash(); - self.insert_script(script_hash.into(), script); - let id = self.create_account(script_hash.into())?; + self.insert_script(script_hash, script); + let id = self.create_account(script_hash)?; Ok(id) } @@ -89,7 +90,7 @@ impl StateExt for S { request: &DepositRequest, ) -> Result<(), Error> { // find or create user account - let account_script_hash: H256 = request.script().hash().into(); + let account_script_hash: H256 = request.script().hash(); // mint CKB let capacity: u64 = request.capacity().unpack(); log::debug!("[generator] deposit capacity {}", capacity); @@ -140,15 +141,15 @@ impl StateExt for S { ); let sudt_script_hash = request.sudt_script_hash().unpack(); let amount = request.amount().unpack(); - if sudt_script_hash != CKB_SUDT_SCRIPT_ARGS.into() { + if sudt_script_hash != CKB_SUDT_SCRIPT_ARGS { // find or create Simple UDT account let l2_sudt_script = build_l2_sudt_script(ctx, &sudt_script_hash); let l2_sudt_script_hash: [u8; 32] = l2_sudt_script.hash(); - let sudt_id = match self.get_account_id_by_script_hash(&l2_sudt_script_hash.into())? { + let sudt_id = match self.get_account_id_by_script_hash(&l2_sudt_script_hash)? { Some(id) => id, None => { - self.insert_script(l2_sudt_script_hash.into(), l2_sudt_script); - self.create_account(l2_sudt_script_hash.into())? + self.insert_script(l2_sudt_script_hash, l2_sudt_script); + self.create_account(l2_sudt_script_hash)? } }; // prevent fake CKB SUDT, the caller should filter these invalid deposits @@ -207,7 +208,7 @@ impl StateExt for S { CKBCapacity::from_layer1(capacity).to_layer2(), )?; let sudt_id = self - .get_account_id_by_script_hash(&l2_sudt_script_hash.into())? + .get_account_id_by_script_hash(&l2_sudt_script_hash)? .ok_or(AccountError::UnknownSUDT)?; if sudt_id != CKB_SUDT_ACCOUNT_ID { // burn sudt diff --git a/crates/generator/src/utils.rs b/crates/generator/src/utils.rs index 2d0ec888b..0891ef561 100644 --- a/crates/generator/src/utils.rs +++ b/crates/generator/src/utils.rs @@ -1,13 +1,14 @@ use std::convert::TryInto; use anyhow::{Context, Result}; -use gw_common::{builtins::CKB_SUDT_ACCOUNT_ID, state::State, H256}; +use gw_common::{builtins::CKB_SUDT_ACCOUNT_ID, state::State}; use gw_config::BackendType; use gw_traits::CodeStore; use gw_types::core::Timepoint; use gw_types::{ bytes::Bytes, core::{AllowedContractType, ScriptHashType}, + h256::*, packed::{CellOutput, RawL2Transaction, Script, WithdrawalLockArgs, WithdrawalRequestExtra}, prelude::*, }; @@ -49,7 +50,7 @@ pub fn build_withdrawal_cell_output( rollup_context: &RollupContext, req: &WithdrawalRequestExtra, block_hash: &H256, - block_timepoint: &Timepoint, + finalized_timepoint: &Timepoint, opt_asset_script: Option