diff --git a/.github/testoolScripts/cleanup.sh b/.github/testoolScripts/cleanup.sh index a503363652..6129bb8d76 100755 --- a/.github/testoolScripts/cleanup.sh +++ b/.github/testoolScripts/cleanup.sh @@ -6,7 +6,7 @@ runner_vpc_id="vpc-05dedcb650bd24f8d" # Get runner status runner=$(aws ec2 describe-instances --profile $profile --filters Name=tag:Name,Values=[testool] Name=network-interface.vpc-id,Values=[$runner_vpc_id] --query "Reservations[*].Instances[*][InstanceId]" --output text | xargs) -echo "Reports: http://testool-public.s3-website.eu-central-1.amazonaws.com" +echo "Reports: https://testool.pse.dev" echo "Shuting down instance..." aws ec2 stop-instances --profile $profile --instance-ids $runner diff --git a/.github/workflows/geth-utils.yml b/.github/workflows/geth-utils.yml index 9fc22d6574..2ac5fe0c61 100644 --- a/.github/workflows/geth-utils.yml +++ b/.github/workflows/geth-utils.yml @@ -30,7 +30,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: '1.20' + go-version: '1.21' - name: Format uses: Jerome1337/gofmt-action@v1.0.5 diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index bdfb6b546f..1c027235f3 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -70,19 +70,9 @@ jobs: with: override: false - name: Setup golang - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: - go-version: ~1.19 - # Go cache for building geth-utils - - name: Go cache - uses: actions/cache@v3 - with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- + go-version: ~1.21 - name: Cargo cache uses: actions/cache@v3 with: diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index ad1f9c938d..3f83a0bc5f 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -38,16 +38,10 @@ jobs: with: components: rustfmt, clippy override: false - # Go cache for building geth-utils - - name: Go cache - uses: actions/cache@v3 + - name: Setup golang + uses: actions/setup-go@v4 with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: lint-${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- + go-version: ~1.21 - name: Cargo cache uses: actions/cache@v3 with: diff --git a/.github/workflows/main-tests.yml b/.github/workflows/main-tests.yml index 5a4826347a..2801dc8c9f 100644 --- a/.github/workflows/main-tests.yml +++ b/.github/workflows/main-tests.yml @@ -46,19 +46,9 @@ jobs: with: override: false - name: Setup golang - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: - go-version: ~1.19 - # Go cache for building geth-utils - - name: Go cache - uses: actions/cache@v3 - with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- + go-version: ~1.21 - name: Cargo cache uses: actions/cache@v3 with: @@ -79,7 +69,7 @@ jobs: uses: actions-rs/cargo@v1 with: command: test - args: --verbose --release --all --all-features --exclude integration-tests --exclude circuit-benchmarks + args: --verbose --release --all --all-features --exclude integration-tests --exclude circuit-benchmarks -- --test-threads 24 - name: Run testool internal tests uses: actions-rs/cargo@v1 with: @@ -104,19 +94,9 @@ jobs: with: override: false - name: Setup golang - uses: actions/setup-go@v3 - with: - go-version: ~1.19 - # Go cache for building geth-utils - - name: Go cache - uses: actions/cache@v3 + uses: actions/setup-go@v4 with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- + go-version: ~1.21 - name: Cargo cache uses: actions/cache@v3 with: @@ -155,16 +135,10 @@ jobs: override: false - name: Add target run: rustup target add x86_64-unknown-linux-gnu - # Go cache for building geth-utils - - name: Go cache - uses: actions/cache@v3 + - name: Setup golang + uses: actions/setup-go@v4 with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- + go-version: ~1.21 - name: Cargo cache uses: actions/cache@v3 with: diff --git a/.github/workflows/test-features.yml b/.github/workflows/test-features.yml index 8e98681661..f04075e447 100644 --- a/.github/workflows/test-features.yml +++ b/.github/workflows/test-features.yml @@ -36,16 +36,10 @@ jobs: - uses: actions-rs/toolchain@v1 with: override: false - - # Go cache for building geth-utils - - name: Go cache - uses: actions/cache@v3 + - name: Setup golang + uses: actions/setup-go@v4 with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ github.workflow }}-${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - + go-version: ~1.21 - name: Cargo cache uses: actions/cache@v3 with: diff --git a/Cargo.lock b/Cargo.lock index be30d586ab..a99cb46ac0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,9 +29,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", @@ -40,9 +40,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff" dependencies = [ "cfg-if", "once_cell", @@ -182,14 +182,13 @@ dependencies = [ [[package]] name = "auto_impl" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +checksum = "823b8bb275161044e2ac7a25879cb3e2480cb403e3943022c7c769c599b756aa" dependencies = [ - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -358,7 +357,9 @@ dependencies = [ "lazy_static", "log", "mock", + "num", "pretty_assertions", + "rand", "revm-precompile", "serde", "serde_json", @@ -427,9 +428,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" dependencies = [ "serde", ] @@ -466,9 +467,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.32" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41daef31d7a747c5c847246f36de49ced6f7403b4cdabc807a97b5cc184cda7a" +checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" dependencies = [ "num-traits", ] @@ -629,9 +630,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" +checksum = "18d59688ad0945eaf6b84cb44fedbe93484c81b48970e98f09db8a22832d7961" dependencies = [ "cfg-if", "cpufeatures", @@ -691,9 +692,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] @@ -1000,9 +1001,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "elliptic-curve" @@ -1465,9 +1466,9 @@ dependencies = [ [[package]] name = "eyre" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", @@ -1674,6 +1675,7 @@ dependencies = [ "digest 0.7.6", "eth-types", "halo2_proofs", + "itertools 0.10.5", "rand", "sha3 0.7.3", "strum 0.24.1", @@ -1781,13 +1783,47 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.1.0", + "indexmap 2.2.3", "slab", "tokio", "tokio-util", "tracing", ] +[[package]] +name = "halo2-base" +version = "0.2.2" +source = "git+https://github.com/scroll-tech/halo2-lib?branch=develop#40ba7e3bbf013b55c59283534c9489701f9212d0" +dependencies = [ + "ff", + "halo2_proofs", + "itertools 0.10.5", + "num-bigint", + "num-integer", + "num-traits", + "rand_chacha", + "rustc-hash", +] + +[[package]] +name = "halo2-ecc" +version = "0.2.2" +source = "git+https://github.com/scroll-tech/halo2-lib?branch=develop#40ba7e3bbf013b55c59283534c9489701f9212d0" +dependencies = [ + "ff", + "group", + "halo2-base", + "itertools 0.10.5", + "num-bigint", + "num-integer", + "num-traits", + "rand", + "rand_chacha", + "rand_core", + "serde", + "serde_json", +] + [[package]] name = "halo2_proofs" version = "0.3.0" @@ -1806,9 +1842,9 @@ dependencies = [ [[package]] name = "halo2curves" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3675880dc0cc7cd468943266297198a28f88210ba60ca5e0e04d121edf86b46" +checksum = "db81d01d0bbfec9f624d7590fc6929ee2537a64ec1e080d8f8c9e2d2da291405" dependencies = [ "blake2b_simd", "ff", @@ -1893,9 +1929,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" +checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" [[package]] name = "hex" @@ -2103,9 +2139,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -2154,6 +2190,7 @@ dependencies = [ "ethers-contract-abigen", "glob", "halo2_proofs", + "itertools 0.10.5", "lazy_static", "log", "mock", @@ -2178,12 +2215,12 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is-terminal" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi 0.3.4", - "rustix", + "hermit-abi 0.3.6", + "libc", "windows-sys 0.52.0", ] @@ -2213,18 +2250,18 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" dependencies = [ "wasm-bindgen", ] @@ -2305,9 +2342,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.152" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libm" @@ -2439,9 +2476,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] @@ -2528,28 +2565,33 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" dependencies = [ "autocfg", "num-integer", @@ -2570,9 +2612,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", "libm", @@ -2584,7 +2626,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.4", + "hermit-abi 0.3.6", "libc", ] @@ -2829,9 +2871,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" dependencies = [ "memchr", "thiserror", @@ -2840,9 +2882,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" +checksum = "22e1288dbd7786462961e69bfd4df7848c1e37e8b74303dbdab82c3a9cdd2809" dependencies = [ "pest", "pest_generator", @@ -2850,9 +2892,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" +checksum = "1381c29a877c6d34b8c176e734f35d7f7f5b3adaefe940cb4d1bb7af94678e2e" dependencies = [ "pest", "pest_meta", @@ -2863,9 +2905,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" +checksum = "d0934d6907f148c22a3acbda520c7eed243ad7487a30f51f6ce52b58b7077a8a" dependencies = [ "once_cell", "pest", @@ -2879,7 +2921,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.1.0", + "indexmap 2.2.3", ] [[package]] @@ -2945,18 +2987,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", @@ -2987,9 +3029,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "poseidon" @@ -3091,7 +3133,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_edit 0.21.0", + "toml_edit 0.21.1", ] [[package]] @@ -3251,9 +3293,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b7fa1134405e2ec9353fd416b17f8dacd46c473d7d3fd1cf202706a14eb792a" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ "aho-corasick", "memchr", @@ -3274,9 +3316,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.23" +version = "0.11.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" dependencies = [ "base64 0.21.7", "bytes", @@ -3300,6 +3342,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-rustls", @@ -3460,6 +3503,12 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc-hex" version = "2.1.0" @@ -3477,9 +3526,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.30" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ "bitflags 2.4.2", "errno", @@ -3682,18 +3731,18 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", @@ -3702,9 +3751,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ "itoa", "ryu", @@ -4019,9 +4068,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "svm-rs" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20689c7d03b6461b502d0b95d6c24874c7d24dea2688af80486a130a06af3b07" +checksum = "11297baafe5fa0c99d5722458eac6a5e25c01eb1b8e5cd137f54079093daa7a4" dependencies = [ "dirs", "fs2", @@ -4059,6 +4108,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "system-configuration" version = "0.5.1" @@ -4088,13 +4143,12 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.9.0" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", "rustix", "windows-sys 0.52.0", ] @@ -4162,18 +4216,18 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", @@ -4182,12 +4236,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -4202,10 +4257,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" dependencies = [ + "num-conv", "time-core", ] @@ -4235,9 +4291,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", @@ -4336,7 +4392,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.3", "serde", "serde_spanned", "toml_datetime", @@ -4349,18 +4405,18 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.3", "toml_datetime", "winnow", ] [[package]] name = "toml_edit" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.3", "toml_datetime", "winnow", ] @@ -4585,9 +4641,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -4595,9 +4651,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" dependencies = [ "bumpalo", "log", @@ -4610,9 +4666,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.40" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" dependencies = [ "cfg-if", "js-sys", @@ -4622,9 +4678,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4632,9 +4688,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", @@ -4645,15 +4701,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" [[package]] name = "web-sys" -version = "0.3.67" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" dependencies = [ "js-sys", "wasm-bindgen", @@ -4661,9 +4717,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.3" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "winapi" @@ -4830,9 +4886,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.34" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] @@ -4952,6 +5008,8 @@ dependencies = [ "ethers-signers", "gadgets", "getrandom", + "halo2-base", + "halo2-ecc", "halo2_proofs", "hex", "integer", @@ -5005,3 +5063,8 @@ dependencies = [ "cc", "pkg-config", ] + +[[patch.unused]] +name = "halo2curves" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml index 00da3baf01..0e88d667b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,12 @@ members = [ [patch.crates-io] halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v0.3.0" } +[patch."https://github.com/scroll-tech/halo2.git"] +halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v0.3.0" } + +[patch."https://github.com/privacy-scaling-explorations/halo2curves.git"] +halo2curves = { version = "0.1.0", features = ["derive_serde"] } + # Definition of benchmarks profile to use. [profile.bench] opt-level = 3 diff --git a/Makefile b/Makefile index 274e6555e9..d0eb037d53 100644 --- a/Makefile +++ b/Makefile @@ -77,7 +77,7 @@ stats_evm_circuit: # Print a table with EVM Circuit stats by ExecState/opcode stats_copy_circuit: # Print a table with Copy Circuit stats by ExecState/opcode @cargo run --bin stats --features stats -- copy -evm_exec_steps_occupancy: # Print a table for each EVM-CellManager CellType with the top 10 occupancy ExecutionSteps associated +evm_exec_steps_occupancy: # Print a table for each EVM-CellManager CellType with the top 10 occupancy ExecSteps associated @cargo run --bin stats --features stats -- exec .PHONY: clippy doc fmt test test_benches test-all evm_bench state_bench circuit_benches evm_exec_steps_occupancy stats_state_circuit stats_evm_circuit stats_copy_circuit help diff --git a/bin/mpt-test/src/circuit/state_update.rs b/bin/mpt-test/src/circuit/state_update.rs index 8060959e34..a9271e6339 100644 --- a/bin/mpt-test/src/circuit/state_update.rs +++ b/bin/mpt-test/src/circuit/state_update.rs @@ -57,13 +57,13 @@ pub struct StateUpdateCircuitConfig { /// The MPT table, where the state updates are stored pub pi_mpt: MptTable, - /// Intance column, used to check public inputs + /// Instance column, used to check public inputs pub instance: Column, /// ONE if the first row, ZERO otherwise pub is_first: Column, - /// ONE if row is paddding, ZERO otherwise + /// ONE if row is padding, ZERO otherwise pub is_padding: IsZeroConfig, /// ONE is the last used row, ZERO otherwise @@ -465,7 +465,7 @@ impl Circuit for StateUpdateCircuit { ).unwrap() ); - // at beggining, set the old root and number of proofs + // at beginning, set the old root and number of proofs if offset == 0 { pi.push(Some(old_root_lo)); diff --git a/bus-mapping/Cargo.toml b/bus-mapping/Cargo.toml index d58111b309..bf8dd08b25 100644 --- a/bus-mapping/Cargo.toml +++ b/bus-mapping/Cargo.toml @@ -16,6 +16,8 @@ halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.gi itertools = "0.10" lazy_static = "1.4" log = "0.4.14" +num = "0.4" +rand = { version = "0.8", optional = true } serde = {version = "1.0.130", features = ["derive"] } serde_json = "1.0.66" strum = "0.24" diff --git a/bus-mapping/README.md b/bus-mapping/README.md index e0cbea24da..a1db65fcf5 100644 --- a/bus-mapping/README.md +++ b/bus-mapping/README.md @@ -1,54 +1,36 @@ # ZKEVM Bus-Mapping -![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/appliedzkp/zkevm-circuits/CI%20checks/main?style=for-the-badge) +The `Bus-Mapping` crate is designed to parse EVM execution traces and manipulate the data they provide to obtain structured witness inputs for the EVM Proof and the State Proof. -`Bus-Mapping` is a crate designed to parse EVM execution traces and manipulate -all of the data they provide in order to obtain structured witness inputs -for the EVM Proof and the State Proof. +## Introduction -### Introduction -At the moment every node on ethereum has to validate every transaction in -the ethereum virtual machine. This means that every transaction adds work -that everyone needs to do to verify Ethereum’s history. Worse still is that -each transaction needs to be verified by every new node. Which means the -amount of work a new node needs to do the sync the network is growing -constantly. We want to build a proof of validity for the Ethereum blocks to -avoid this. +Currently, every node on Ethereum must validate every transaction in the Ethereum Virtual Machine (EVM). This means that each transaction adds work that everyone must do to verify Ethereum’s history. Furthermore, each transaction needs to be verified by every new node, leading to a growing amount of work for new nodes to sync the network. To address this, we aim to build a proof of validity for Ethereum blocks. -This means making a proof of validity for the EVM + state reads / writes + -signatures. -To simplify we separate our proofs into two components. +This involves creating a proof of validity for the EVM, including state reads/writes and signatures. To simplify, we divide our proofs into two components: -- State proof: State/memory/stack ops have been performed correctly. This -does not check if the correct location has been read/written. We allow our -prover to pick any location here and in the EVM proof confirm it is correct. +- State Proof: Validates that state/memory/stack operations have been performed correctly. However, it does not verify if the correct location has been read/written. Our prover can select any location here and in the EVM proof confirm its correctness. +- EVM Proof: Validates that the correct opcode is called at the correct time, checking the validity of these opcodes. It also confirms that for each of these opcodes, the state proof performed the correct operation. -- EVM proof: This checks that the correct opcode is called at the correct -time. It checks the validity of these opcodes. It also confirms that for -each of these opcodes the state proof performed the correct operation. +Only after verifying both proofs can we be confident that the Ethereum block is executed correctly. -Only after verifying both proofs are we confident that that Ethereum block -is executed correctly. +## Bus Mapping -### Bus Mapping The goal of this crate is to serve as: -- A parsing lib for EVM execution traces. -- A way to infer some witness data that can only be constructed once we've - analyzed the full exec trace. -- An easy interface to collect all of the data to witness into the circuits - and witness it with few function calls. - -### Parsing -Provided a JSON file or a JSON as a stream of bytes, which contains an -execution trace from an EVM, you can parse it and construct an -`ExecutionTrace` instance from it. That will automatically fill all of the -bus-mapping instances of each -[`ExecutionStep`](crate::exec_trace::ExecutionStep) plus fill in an -[`OperationContainer`](crate::operation::container::OperationContainer) with -all of the Memory, Stack and Storage ops performed by the provided trace. + +- A parsing library for EVM execution traces. +- A way to infer some witness data that can only be constructed once we've analyzed the full exec trace. +- An easy interface to collect all of the data to witness into the circuits and witness it with few function calls. + +## Parsing + +Given a JSON file or a JSON stream containing an execution trace from an EVM, you can parse it and construct a [`GethExecTrace`](eth_types::GethExecTrace) instance from it. This will automatically populate all of the bus-mapping instances of each [`ExecStep`](crate::circuit_input_builder::ExecStep) and fill an [`OperationContainer`](crate::operation::OperationContainer) with all of the memory, stack, and storage operations performed by the provided trace. ```rust -use bus_mapping::{ExecutionTrace, ExecutionStep, BlockConstants, Error, evm::EvmWord}; +use bus_mapping::mock::BlockData; +use eth_types::{ + GethExecTrace, GethExecStep, geth_types::GethData, bytecode +}; +use mock::test_ctx::{TestContext, helpers::*}; let input_trace = r#" [ @@ -98,31 +80,48 @@ let input_trace = r#" ] "#; -let block_ctants = BlockConstants::new( - Word::from(0), - pasta_curves::Fp::zero(), - pasta_curves::Fp::zero(), - pasta_curves::Fp::zero(), - pasta_curves::Fp::zero(), - pasta_curves::Fp::zero(), - pasta_curves::Fp::zero(), - pasta_curves::Fp::zero(), -); - -// Here we have the ExecutionTrace completely formed with all of the data to witness structured. -let obtained_exec_trace = ExecutionTrace::from_trace_bytes( - input_trace.as_bytes(), - block_ctants, -).expect("Error on trace generation"); +// We use the [`TestContext`] struct to mock a block. +let code = bytecode! { + // Write 0x6f to storage slot 0 + PUSH1(0x6fu64) + PUSH1(0x00u64) + SSTORE + // Load storage slot 0 + PUSH1(0x00u64) + SLOAD + STOP +}; +// Get the execution steps from the external tracer +let block: GethData = TestContext::<2, 1>::new( + None, + account_0_code_account_1_no_code(code), + tx_from_1_to_0, + |block, _tx| block.number(0xcafeu64), +) +.unwrap() +.into(); +// Here we update the circuit input with the data from the transaction trace. +let builder = BlockData::new_from_geth_data(block.clone()).new_circuit_input_builder(); +let builder = builder + .handle_block(&block.eth_block, &block.geth_traces) + .unwrap(); +let geth_steps: Vec = serde_json::from_str(input_trace).unwrap(); +let _geth_trace = GethExecTrace { + return_value: "".to_string(), + gas: block.eth_block.transactions[0].gas.as_u64(), + invalid: false, + failed: false, + struct_logs: geth_steps, +}; // Get an ordered vector with all of the Stack operations of this trace. -let stack_ops = obtained_exec_trace.sorted_stack_ops(); - +let _stack_ops = builder.block.container.sorted_stack(); // You can also iterate over the steps of the trace and witness the EVM Proof. -obtained_exec_trace.steps().iter(); +let _ = builder.block.txs()[0].steps().iter(); ``` -Assume we have the following trace: +Assuming we have the following trace: + ```text,ignore pc op stack (top -> down) memory -- -------------- ---------------------------------- --------------------------------------- @@ -148,37 +147,28 @@ pc op stack (top -> down) memory ... ``` -Once you have the trace built (following the code found above) you can -basically: -- Get an iterator/vector over the `Stack`, `Memory` or `Storage` operations - ordered on the way the State Proof needs. +Once you have built the trace (following the code above), you can: + +- Get an iterator/vector over the `Stack`, `Memory`, or `Storage` operations ordered in the way the State Proof needs. + +For the Memory operations, it might look like this: -On that way, we would get something like this for the Memory ops: ```text,ignore -| `key` | `val` | `rw` | `gc` | Note | -|:------:| ------------- | ------- | ---- | ---------------------------------------- | -| `0x40` | `0` | `Write` | | Init | -| `0x40` | `0x80` | `Write` | 0 | Assume written at the begining of `code` | -| `0x40` | `0x80` | `Read` | 4 | `56 MLOAD` | -| - | | | | | -| `0x80` | `0` | `Write` | | Init | -| `0x80` | `0xdeadbeef` | `Write` | 10 | `63 MSTORE` | -| `0x80` | `0xdeadbeef` | `Read` | 16 | `70 MLOAD` | -| `0x80` | `0x1d97c6efb` | `Write` | 24 | `73 MSTORE` | -| - | | | | | -| `0xa0` | `0` | `Write` | | Init | -| `0xa0` | `0xcafeb0ba` | `Write` | 34 | `83 MSTORE` +| `key` | `val` | `rw` | `gc` | Note | +| :----: | ------------- | ------- | ---- | ----------------------------------------- | +| `0x40` | `0` | `Write` | | Init | +| `0x40` | `0x80` | `Write` | 0 | Assume written at the beginning of `code` | +| `0x40` | `0x80` | `Read` | 4 | `56 MLOAD` | +| - | | | | | +| `0x80` | `0` | `Write` | | Init | +| `0x80` | `0xdeadbeef` | `Write` | 10 | `63 MSTORE` | +| `0x80` | `0xdeadbeef` | `Read` | 16 | `70 MLOAD` | +| `0x80` | `0x1d97c6efb` | `Write` | 24 | `73 MSTORE` | +| - | | | | | +| `0xa0` | `0` | `Write` | | Init | +| `0xa0` | `0xcafeb0ba` | `Write` | 34 | `83 MSTORE` | ``` -Where as you see, we group by `memory_address` and then order by -`global_counter`. - -- Iterate over the `ExecutionTrace` itself over -each `ExecutionStep`'s is formed by and check which Stack/Memory&Storage operations are linked to each step. -This is also automatically done via the -[`Opcode`](crate::evm::opcodes::Opcode) trait defined in this crate. +Here, we group by `memory_address` and then order by `global_counter`. -### Documentation -For extra documentation, check the book with the specs written for the -entire ZK-EVM solution. -See: +- Iterate over the [`GethExecTrace`](eth_types::GethExecTrace) itself, over each [`ExecStep`](crate::circuit_input_builder::ExecStep) formed by, and check which Stack/Memory&Storage operations are linked to each step. This is also automatically done via the [`Opcode`](crate::evm::opcodes::Opcode) trait defined in this crate. diff --git a/bus-mapping/src/circuit_input_builder.rs b/bus-mapping/src/circuit_input_builder.rs index 6861a870ae..8f6e1d6a0c 100644 --- a/bus-mapping/src/circuit_input_builder.rs +++ b/bus-mapping/src/circuit_input_builder.rs @@ -4,6 +4,7 @@ mod access; mod block; mod call; +mod chunk; mod execution; mod input_state_ref; #[cfg(test)] @@ -11,17 +12,21 @@ mod tracer_tests; mod transaction; mod withdrawal; -use self::access::gen_state_access_trace; +use self::{access::gen_state_access_trace, chunk::Chunk}; use crate::{ error::Error, evm::opcodes::{gen_associated_ops, gen_associated_steps}, - operation::{CallContextField, Operation, RWCounter, StartOp, RW}, + operation::{ + CallContextField, Op, Operation, OperationContainer, PaddingOp, RWCounter, StartOp, + StepStateField, StepStateOp, RW, + }, rpc::GethClient, state_db::{self, CodeDB, StateDB}, }; pub use access::{Access, AccessSet, AccessValue, CodeSource}; pub use block::{Block, BlockContext}; pub use call::{Call, CallContext, CallKind}; +pub use chunk::ChunkContext; use core::fmt::Debug; use eth_types::{ self, geth_types, @@ -31,6 +36,7 @@ use eth_types::{ use ethers_providers::JsonRpcClient; pub use execution::{ CopyDataType, CopyEvent, CopyStep, ExecState, ExecStep, ExpEvent, ExpStep, NumberOrHash, + PrecompileEvent, PrecompileEvents, N_BYTES_PER_PAIR, N_PAIRING_PER_OP, }; pub use input_state_ref::CircuitInputStateRef; use itertools::Itertools; @@ -42,6 +48,9 @@ use std::{ pub use transaction::{Transaction, TransactionContext}; pub use withdrawal::{Withdrawal, WithdrawalContext}; +/// number of execution state fields +pub const N_EXEC_STATE: usize = 10; + /// Runtime Config /// /// Default to mainnet block @@ -79,11 +88,16 @@ impl FeatureConfig { } } +// RW_BUFFER_SIZE need to set to cover max rwc row contributed by a ExecStep +const RW_BUFFER_SIZE: usize = 30; + /// Circuit Setup Parameters -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct FixedCParams { + /// + pub total_chunks: usize, /// Maximum number of rw operations in the state circuit (RwTable length / - /// nummber of rows). This must be at least the number of rw operations + /// number of rows). This must be at least the number of rw operations /// + 1, in order to allocate at least a Start row. pub max_rws: usize, // TODO: evm_rows: Maximum number of rows in the EVM Circuit @@ -112,6 +126,11 @@ pub struct FixedCParams { /// calculated, so the same circuit will not be able to prove different /// witnesses. pub max_keccak_rows: usize, + /// This number indicate what 100% usage means, for example if we can support up to 2 + /// ecPairing inside circuit, and max_vertical_circuit_rows is set to 1_000_000, + /// then if there is 1 ecPairing in the input, we will return 500_000 as the "row usage" + /// for the ec circuit. + pub max_vertical_circuit_rows: usize, } /// Unset Circuits Parameters @@ -119,29 +138,53 @@ pub struct FixedCParams { /// To reduce the testing overhead, we determine the parameters by the testing inputs. /// A new [`FixedCParams`] will be computed from the generated circuit witness. #[derive(Debug, Clone, Copy)] -pub struct DynamicCParams {} - +pub struct DynamicCParams { + /// Toatal number of chunks + pub total_chunks: usize, +} /// Circuit Setup Parameters. These can be fixed/concrete or unset/dynamic. pub trait CircuitsParams: Debug + Copy { - /// Returns the max number of rws allowed + /// Return the total number of chunks + fn total_chunks(&self) -> usize; + /// Set total number of chunks + fn set_total_chunk(&mut self, total_chunks: usize); + /// Return the maximun Rw fn max_rws(&self) -> Option; } impl CircuitsParams for FixedCParams { + fn total_chunks(&self) -> usize { + self.total_chunks + } + fn set_total_chunk(&mut self, total_chunks: usize) { + self.total_chunks = total_chunks; + } fn max_rws(&self) -> Option { Some(self.max_rws) } } impl CircuitsParams for DynamicCParams { + fn total_chunks(&self) -> usize { + self.total_chunks + } + fn set_total_chunk(&mut self, total_chunks: usize) { + self.total_chunks = total_chunks; + } fn max_rws(&self) -> Option { None } } +impl Default for DynamicCParams { + fn default() -> Self { + DynamicCParams { total_chunks: 1 } + } +} impl Default for FixedCParams { /// Default values for most of the unit tests of the Circuit Parameters fn default() -> Self { FixedCParams { + total_chunks: 1, max_rws: 1000, max_txs: 1, max_withdrawals: 1, @@ -153,6 +196,7 @@ impl Default for FixedCParams { max_bytecode: 512, max_evm_rows: 0, max_keccak_rows: 0, + max_vertical_circuit_rows: 0, } } } @@ -166,7 +210,9 @@ impl Default for FixedCParams { /// the block. 2. For each [`eth_types::Transaction`] in the block, take the /// [`eth_types::GethExecTrace`] to build the circuit input associated with /// each transaction, and the bus-mapping operations associated with each -/// [`eth_types::GethExecStep`] in the [`eth_types::GethExecTrace`]. +/// [`eth_types::GethExecStep`] in the [`eth_types::GethExecTrace`]. 3. If `Rw`s +/// generated during Transactions exceed the `max_rws` threshold, seperate witness +/// into multiple chunks. /// /// The generated bus-mapping operations are: /// [`StackOp`](crate::operation::StackOp)s, @@ -175,7 +221,7 @@ impl Default for FixedCParams { /// [`OpcodeId`](crate::evm::OpcodeId)s used in each `ExecTrace` step so that /// the State Proof witnesses are already generated on a structured manner and /// ready to be added into the State circuit. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct CircuitInputBuilder { /// StateDB key-value DB pub sdb: StateDB, @@ -183,10 +229,14 @@ pub struct CircuitInputBuilder { pub code_db: CodeDB, /// Block pub block: Block, - /// Circuits Setup Paramteres - pub circuits_params: C, + /// Chunk + pub chunks: Vec, /// Block Context pub block_ctx: BlockContext, + /// Chunk Context + pub chunk_ctx: ChunkContext, + /// Circuits Setup Parameters before chunking + pub circuits_params: C, /// Feature config pub feature_config: FeatureConfig, } @@ -201,16 +251,28 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder { params: C, feature_config: FeatureConfig, ) -> Self { + let total_chunks = params.total_chunks(); + let chunks = vec![Chunk::default(); total_chunks]; Self { sdb, code_db, block, - circuits_params: params, + chunks, block_ctx: BlockContext::new(), + chunk_ctx: ChunkContext::new(total_chunks), + circuits_params: params, feature_config, } } + /// Set the total number of chunks for existing CircuitInputBuilder, + /// API for chunking the existing tests then run with a specific chunk + pub fn set_total_chunk(&mut self, total_chunks: usize) { + self.circuits_params.set_total_chunk(total_chunks); + self.chunks = vec![Chunk::default(); total_chunks]; + self.chunk_ctx.total_chunks = total_chunks; + } + /// Obtain a mutable reference to the state that the `CircuitInputBuilder` /// maintains, contextualized to a particular transaction and a /// particular execution step in that transaction. @@ -224,6 +286,7 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder { code_db: &mut self.code_db, block: &mut self.block, block_ctx: &mut self.block_ctx, + chunk_ctx: &mut self.chunk_ctx, tx, tx_ctx, max_rws: self.circuits_params.max_rws(), @@ -281,81 +344,495 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder { } } + // chunking and mutable bumping chunk_ctx once condition match + // return true on bumping to next chunk + fn check_and_chunk( + &mut self, + geth_trace: &GethExecTrace, + tx: Transaction, + tx_ctx: TransactionContext, + next_geth_step: Option<(usize, &GethExecStep)>, + last_call: Option, + ) -> Result { + // we dont chunk if + // 1. on last chunk + // 2. still got some buffer room before max_rws + let Some(max_rws) = self.circuits_params.max_rws() else { + // terminiate earlier due to no max_rws + return Ok(false); + }; + + if self.chunk_ctx.is_last_chunk() || self.chunk_rws() + RW_BUFFER_SIZE < max_rws { + return Ok(false); + }; + + // Optain the first op of the next GethExecStep, for fixed case also lookahead + let (mut cib, mut tx, mut tx_ctx) = (self.clone(), tx, tx_ctx); + let mut cib_ref = cib.state_ref(&mut tx, &mut tx_ctx); + let mut next_ops = if let Some((i, step)) = next_geth_step { + log::trace!("chunk at {}th opcode {:?} ", i, step.op); + gen_associated_ops(&step.op, &mut cib_ref, &geth_trace.struct_logs[i..])?.remove(0) + } else { + log::trace!("chunk at EndTx"); + gen_associated_steps(&mut cib_ref, ExecState::EndTx)? + }; + + let last_copy = self.block.copy_events.len(); + // Generate EndChunk and proceed to the next if it's not the last chunk + // Set next step pre-state as end_chunk state + self.set_end_chunk(&next_ops, Some(&tx)); + + // need to update next_ops.rwc to catch block_ctx.rwc in `set_end_chunk` + next_ops.rwc = self.block_ctx.rwc; + + // tx.id start from 1, so it's equivalent to `next_tx_index` + self.commit_chunk_ctx(true, tx.id as usize, last_copy, last_call); + self.set_begin_chunk(&next_ops, Some(&tx)); + + Ok(true) + } + /// Handle a transaction with its corresponding execution trace to generate /// all the associated operations. Each operation is registered in /// `self.block.container`, and each step stores the /// [`OperationRef`](crate::exec_trace::OperationRef) to each of the /// generated operations. + /// When dynamic builder handles Tx with is_chuncked = false, we don't chunk + /// When fixed builder handles Tx with is_chuncked = true, we chunk fn handle_tx( &mut self, eth_tx: ð_types::Transaction, geth_trace: &GethExecTrace, is_last_tx: bool, tx_index: u64, - ) -> Result<(), Error> { + ) -> Result<(ExecStep, Option), Error> { let mut tx = self.new_tx(tx_index, eth_tx, !geth_trace.failed)?; let mut tx_ctx = TransactionContext::new(eth_tx, geth_trace, is_last_tx)?; - if !geth_trace.invalid { + let res = if !geth_trace.invalid { // Generate BeginTx step let begin_tx_step = gen_associated_steps( &mut self.state_ref(&mut tx, &mut tx_ctx), ExecState::BeginTx, )?; + let mut last_call = Some(tx.calls().get(begin_tx_step.call_index).unwrap().clone()); tx.steps_mut().push(begin_tx_step); - for (index, geth_step) in geth_trace.struct_logs.iter().enumerate() { - let mut state_ref = self.state_ref(&mut tx, &mut tx_ctx); - log::trace!("handle {}th opcode {:?} ", index, geth_step.op); + let mut trace = geth_trace.struct_logs.iter().enumerate().peekable(); + while let Some((peek_i, peek_step)) = trace.peek() { + // Check the peek step and chunk if needed + self.check_and_chunk( + geth_trace, + tx.clone(), + tx_ctx.clone(), + Some((*peek_i, peek_step)), + last_call.clone(), + )?; + // Proceed to the next step + let (i, step) = trace.next().expect("Peeked step should exist"); + log::trace!( + "handle {}th opcode {:?} {:?} rws = {:?}", + i, + step.op, + step, + self.chunk_rws() + ); let exec_steps = gen_associated_ops( - &geth_step.op, - &mut state_ref, - &geth_trace.struct_logs[index..], + &step.op, + &mut self.state_ref(&mut tx, &mut tx_ctx), + &geth_trace.struct_logs[i..], )?; + last_call = exec_steps + .last() + .map(|step| tx.calls().get(step.call_index).unwrap().clone()); tx.steps_mut().extend(exec_steps); } + // Peek the end_tx_step + self.check_and_chunk( + geth_trace, + tx.clone(), + tx_ctx.clone(), + None, + last_call.clone(), + )?; + // Generate EndTx step let end_tx_step = gen_associated_steps(&mut self.state_ref(&mut tx, &mut tx_ctx), ExecState::EndTx)?; - tx.steps_mut().push(end_tx_step); + tx.steps_mut().push(end_tx_step.clone()); + (end_tx_step, last_call) } else if self.feature_config.invalid_tx { // Generate InvalidTx step let invalid_tx_step = gen_associated_steps( &mut self.state_ref(&mut tx, &mut tx_ctx), ExecState::InvalidTx, )?; - tx.steps_mut().push(invalid_tx_step); + tx.steps_mut().push(invalid_tx_step.clone()); + // Peek the end_tx_step + let is_chunk = + self.check_and_chunk(geth_trace, tx.clone(), tx_ctx.clone(), None, None)?; + if is_chunk { + // TODO we dont support chunk after invalid_tx + // becasuse begin_chunk will constraints what next step execution state. + // And for next step either begin_tx or invalid_tx will both failed because + // begin_tx/invalid_tx define new execution state. + unimplemented!("dont support invalid_tx with multiple chunks") + } + + (invalid_tx_step, None) } else { panic!("invalid tx support not enabled") - } + }; self.sdb.commit_tx(); self.block.txs.push(tx); - Ok(()) + Ok(res) + } + + // generate chunk related steps + fn gen_chunk_associated_steps( + &mut self, + step: &mut ExecStep, + rw: RW, + tx: Option<&Transaction>, + ) { + let mut dummy_tx = Transaction::default(); + let mut dummy_tx_ctx = TransactionContext::default(); + + let rw_counters = (0..N_EXEC_STATE) + .map(|_| self.block_ctx.rwc.inc_pre()) + .collect::>(); + // just bump rwc in chunk_ctx as block_ctx rwc to assure same delta apply + let rw_counters_inner_chunk = (0..N_EXEC_STATE) + .map(|_| self.chunk_ctx.rwc.inc_pre()) + .collect::>(); + + let tags = { + let state = self.state_ref(&mut dummy_tx, &mut dummy_tx_ctx); + let last_call = tx + .map(|tx| tx.calls()[step.call_index].clone()) + .or_else(|| state.block.txs.last().map(|tx| tx.calls[0].clone())) + .unwrap(); + [ + (StepStateField::CodeHash, last_call.code_hash.to_word()), + (StepStateField::CallID, Word::from(last_call.call_id)), + (StepStateField::IsRoot, Word::from(last_call.is_root as u64)), + ( + StepStateField::IsCreate, + Word::from(last_call.is_create() as u64), + ), + (StepStateField::ProgramCounter, Word::from(step.pc)), + ( + StepStateField::StackPointer, + Word::from(step.stack_pointer()), + ), + (StepStateField::GasLeft, Word::from(step.gas_left)), + ( + StepStateField::MemoryWordSize, + Word::from(step.memory_word_size()), + ), + ( + StepStateField::ReversibleWriteCounter, + Word::from(step.reversible_write_counter), + ), + (StepStateField::LogID, Word::from(step.log_id)), + ] + }; + + debug_assert_eq!(N_EXEC_STATE, tags.len()); + let state = self.state_ref(&mut dummy_tx, &mut dummy_tx_ctx); + + tags.iter() + .zip_eq(rw_counters) + .zip_eq(rw_counters_inner_chunk) + .for_each(|(((tag, value), rw_counter), inner_rw_counter)| { + push_op( + &mut state.block.container, + step, + rw_counter, + inner_rw_counter, + rw, + StepStateOp { + field: tag.clone(), + value: *value, + }, + ); + }); + } + + /// Set the end status of a chunk including the current globle rwc + /// and commit the current chunk context, proceed to the next chunk + /// if needed + pub fn commit_chunk_ctx( + &mut self, + to_next: bool, + next_tx_index: usize, + next_copy_index: usize, + last_call: Option, + ) { + self.chunk_ctx.end_rwc = self.block_ctx.rwc.0; + self.chunk_ctx.end_tx_index = next_tx_index; + self.chunk_ctx.end_copy_index = next_copy_index; + self.cur_chunk_mut().ctx = self.chunk_ctx.clone(); + if to_next { + // add `-1` to include previous set and deal with transaction cross-chunk case + self.chunk_ctx + .bump(self.block_ctx.rwc.0, next_tx_index - 1, next_copy_index); + self.cur_chunk_mut().prev_last_call = last_call; + } + } + + fn set_begin_chunk(&mut self, first_step: &ExecStep, tx: Option<&Transaction>) { + let mut begin_chunk = ExecStep { + exec_state: ExecState::BeginChunk, + rwc: first_step.rwc, + gas_left: first_step.gas_left, + call_index: first_step.call_index, + ..ExecStep::default() + }; + self.gen_chunk_associated_steps(&mut begin_chunk, RW::READ, tx); + self.chunks[self.chunk_ctx.idx].begin_chunk = Some(begin_chunk); + } + + fn set_end_chunk(&mut self, next_step: &ExecStep, tx: Option<&Transaction>) { + let mut end_chunk = ExecStep { + exec_state: ExecState::EndChunk, + rwc: next_step.rwc, + rwc_inner_chunk: next_step.rwc_inner_chunk, + gas_left: next_step.gas_left, + call_index: next_step.call_index, + ..ExecStep::default() + }; + self.gen_chunk_associated_steps(&mut end_chunk, RW::WRITE, tx); + self.gen_chunk_padding(&mut end_chunk); + self.chunks[self.chunk_ctx.idx].end_chunk = Some(end_chunk); + } + + fn gen_chunk_padding(&mut self, step: &mut ExecStep) { + // rwc index start from 1 + let end_rwc = self.chunk_ctx.rwc.0; + let total_rws = end_rwc - 1; + let max_rws = self.cur_chunk().fixed_param.max_rws; + + assert!( + total_rws < max_rws, + "total_rws <= max_rws, total_rws={}, max_rws={}", + total_rws, + max_rws + ); + + let mut padding = step.clone(); + padding.exec_state = ExecState::Padding; + padding.bus_mapping_instance = vec![]; // there is no rw in padding step + + if self.chunk_ctx.is_first_chunk() { + push_op( + &mut self.block.container, + step, + RWCounter(1), + RWCounter(1), + RW::READ, + StartOp {}, + ); + } + + if max_rws - total_rws > 1 { + let (padding_start, padding_end) = (total_rws + 1, max_rws - 1); + push_op( + &mut self.block.container, + step, + RWCounter(padding_start), + RWCounter(padding_start), + RW::READ, + PaddingOp {}, + ); + if padding_end != padding_start { + push_op( + &mut self.block.container, + step, + RWCounter(padding_end), + RWCounter(padding_end), + RW::READ, + PaddingOp {}, + ); + } + } + self.chunks[self.chunk_ctx.idx].padding = Some(padding); + } + + /// Get the i-th mutable chunk + pub fn get_chunk_mut(&mut self, i: usize) -> &mut Chunk { + self.chunks.get_mut(i).expect("Chunk does not exist") + } + + /// Get the i-th chunk + pub fn get_chunk(&self, i: usize) -> Chunk { + self.chunks.get(i).expect("Chunk does not exist").clone() + } + + /// Get the current chunk + pub fn cur_chunk(&self) -> Chunk { + self.chunks[self.chunk_ctx.idx].clone() + } + + /// Get a mutable reference of current chunk + pub fn cur_chunk_mut(&mut self) -> &mut Chunk { + &mut self.chunks[self.chunk_ctx.idx] + } + + /// Get the previous chunk + pub fn prev_chunk(&self) -> Option { + if self.chunk_ctx.idx == 0 { + return None; + } + self.chunks.get(self.chunk_ctx.idx - 1).cloned() + } + + /// Total Rw in this chunk + pub fn chunk_rws(&self) -> usize { + self.chunk_ctx.rwc.0 - 1 } } impl CircuitInputBuilder { + /// First part of handle_block, only called by fixed Builder + pub fn begin_handle_block( + &mut self, + eth_block: &EthBlock, + geth_traces: &[eth_types::GethExecTrace], + ) -> Result<(Option, Option), Error> { + assert!( + self.circuits_params.max_rws().unwrap_or_default() > self.last_exec_step_rws_reserved(), + "Fixed max_rws not enough for rws reserve" + ); + + // accumulates gas across all txs in the block + let mut res = eth_block + .transactions + .iter() + .enumerate() + .map(|(idx, tx)| { + let geth_trace = &geth_traces[idx]; + // Transaction index starts from 1 + let tx_id = idx + 1; + self.handle_tx( + tx, + geth_trace, + tx_id == eth_block.transactions.len(), + tx_id as u64, + ) + .map(|(exec_step, last_call)| (Some(exec_step), last_call)) + }) + .collect::, Option)>, _>>()?; + // set eth_block + self.block.eth_block = eth_block.clone(); + self.set_value_ops_call_context_rwc_eor(); + if !res.is_empty() { + Ok(res.remove(res.len() - 1)) + } else { + Ok((None, None)) + } + } + /// Handle a block by handling each transaction to generate all the /// associated operations. pub fn handle_block( - &mut self, + mut self, eth_block: &EthBlock, geth_traces: &[eth_types::GethExecTrace], - ) -> Result<&CircuitInputBuilder, Error> { + ) -> Result, Error> { // accumulates gas across all txs in the block - self.begin_handle_block(eth_block, geth_traces)?; - self.set_end_block(self.circuits_params.max_rws)?; + let (last_step, last_call) = self.begin_handle_block(eth_block, geth_traces)?; + // since there is no next step, we cook dummy next step from last step to reuse + // existing field while update its `rwc`. + let mut dummy_next_step = { + let mut dummy_next_step = last_step.unwrap_or_default(); + // raise last step rwc to match with next step + (0..dummy_next_step.rw_indices_len()).for_each(|_| { + dummy_next_step.rwc.inc_pre(); + dummy_next_step.rwc_inner_chunk.inc_pre(); + }); + dummy_next_step + }; + + assert!(self.circuits_params.max_rws().is_some()); + + let last_copy = self.block.copy_events.len(); + + // TODO figure out and resolve generic param type and move fixed_param set inside + // commit_chunk_ctx. After fixed, then we can set fixed_param on all chunks + (0..self.circuits_params.total_chunks()).for_each(|idx| { + self.get_chunk_mut(idx).fixed_param = self.circuits_params; + }); + + // We fill dummy virtual steps: BeginChunk,EndChunk for redundant chunks + let last_process_chunk_id = self.chunk_ctx.idx; + (last_process_chunk_id..self.circuits_params.total_chunks()).try_for_each(|idx| { + if idx == self.circuits_params.total_chunks() - 1 { + self.set_end_block()?; + self.commit_chunk_ctx( + false, + eth_block.transactions.len(), + last_copy, + last_call.clone(), + ); + } else { + self.set_end_chunk(&dummy_next_step, None); + + self.commit_chunk_ctx( + true, + eth_block.transactions.len(), + last_copy, + last_call.clone(), + ); + // update dummy_next_step rwc to be used for next + dummy_next_step.rwc = self.block_ctx.rwc; + dummy_next_step.rwc_inner_chunk = self.chunk_ctx.rwc; + self.set_begin_chunk(&dummy_next_step, None); + dummy_next_step.rwc = self.block_ctx.rwc; + dummy_next_step.rwc_inner_chunk = self.chunk_ctx.rwc; + // update virtual step: end_block/padding so it can carry state context correctly + // TODO: enhance virtual step updating mechanism by having `running_next_step` + // defined in circuit_input_builder, so we dont need to + self.block.end_block = dummy_next_step.clone(); + self.cur_chunk_mut().padding = { + let mut padding = dummy_next_step.clone(); + padding.exec_state = ExecState::Padding; + Some(padding) + }; + } + Ok::<(), Error>(()) + })?; + + let used_chunks = self.chunk_ctx.idx + 1; + assert!( + used_chunks <= self.circuits_params.total_chunks(), + "Used more chunks than given total_chunks" + ); + assert!( + self.chunks.len() == self.chunk_ctx.idx + 1, + "number of chunks {} mis-match with chunk_ctx id {}", + self.chunks.len(), + self.chunk_ctx.idx + 1, + ); + + // Truncate chunks to the actual used amount & correct ctx.total_chunks + // Set length to the actual used amount of chunks + self.chunks.truncate(self.chunk_ctx.idx + 1); + self.chunks.iter_mut().for_each(|chunk| { + chunk.ctx.total_chunks = used_chunks; + }); + Ok(self) } - fn set_end_block(&mut self, max_rws: usize) -> Result<(), Error> { - let mut end_block_not_last = self.block.block_steps.end_block_not_last.clone(); - let mut end_block_last = self.block.block_steps.end_block_last.clone(); - end_block_not_last.rwc = self.block_ctx.rwc; - end_block_last.rwc = self.block_ctx.rwc; + fn set_end_block(&mut self) -> Result<(), Error> { + let mut end_block = self.block.end_block.clone(); + end_block.rwc = self.block_ctx.rwc; + end_block.exec_state = ExecState::EndBlock; + end_block.rwc_inner_chunk = self.chunk_ctx.rwc; let mut dummy_tx = Transaction::default(); let mut dummy_tx_ctx = TransactionContext::default(); @@ -363,65 +840,120 @@ impl CircuitInputBuilder { if let Some(call_id) = state.block.txs.last().map(|tx| tx.calls[0].call_id) { state.call_context_read( - &mut end_block_last, + &mut end_block, call_id, CallContextField::TxId, Word::from(state.block.txs.len() as u64), )?; } - let mut push_op = |step: &mut ExecStep, rwc: RWCounter, rw: RW, op: StartOp| { - let op_ref = state.block.container.insert(Operation::new(rwc, rw, op)); - step.bus_mapping_instance.push(op_ref); + // EndBlock step should also be padded to max_rws similar to EndChunk + self.gen_chunk_padding(&mut end_block); + self.block.end_block = end_block; + Ok(()) + } +} + +fn push_op( + container: &mut OperationContainer, + step: &mut ExecStep, + rwc: RWCounter, + rwc_inner_chunk: RWCounter, + rw: RW, + op: T, +) { + let op_ref = container.insert(Operation::new(rwc, rwc_inner_chunk, rw, op)); + step.bus_mapping_instance.push(op_ref); +} + +impl CircuitInputBuilder { + /// return the rw row reserved for end_block/end_chunk + pub fn last_exec_step_rws_reserved(&self) -> usize { + // rw ops reserved for EndBlock + let end_block_rws = if self.chunk_ctx.is_last_chunk() && self.chunk_rws() > 0 { + 1 + } else { + 0 + }; + // rw ops reserved for EndChunk + let end_chunk_rws = if !self.chunk_ctx.is_last_chunk() { + N_EXEC_STATE + } else { + 0 }; + end_block_rws + end_chunk_rws + 1 + } - // rwc index start from 1 - let total_rws = state.block_ctx.rwc.0 - 1; - // We need at least 1 extra Start row - #[allow(clippy::int_plus_one)] - { - assert!( - total_rws + 1 <= max_rws, - "total_rws + 1 <= max_rws, total_rws={}, max_rws={}", - total_rws, - max_rws - ); - } - let (padding_start, padding_end) = (1, max_rws - total_rws); // rw counter start from 1 - push_op( - &mut end_block_last, - RWCounter(padding_start), - RW::READ, - StartOp {}, - ); - if padding_end != padding_start { - push_op( - &mut end_block_last, - RWCounter(padding_end), - RW::READ, - StartOp {}, - ); - } + fn compute_param(&self, eth_block: &EthBlock) -> FixedCParams { + let max_txs = eth_block.transactions.len(); + let max_withdrawals = eth_block.withdrawals.as_ref().unwrap().len(); + let max_bytecode = self.code_db.num_rows_required_for_bytecode_table(); - self.block.block_steps.end_block_not_last = end_block_not_last; - self.block.block_steps.end_block_last = end_block_last; - Ok(()) + let max_calldata = eth_block + .transactions + .iter() + .fold(0, |acc, tx| acc + tx.input.len()); + let max_exp_steps = self + .block + .exp_events + .iter() + .fold(0usize, |acc, e| acc + e.steps.len()); + // The `+ 2` is used to take into account the two extra empty copy rows needed + // to satisfy the query at `Rotation(2)` performed inside of the + // `rows[2].value == rows[0].value * r + rows[1].value` requirement in the RLC + // Accumulation gate. + let max_copy_rows = self + .block + .copy_events + .iter() + .fold(0, |acc, c| acc + c.bytes.len()) + * 2 + + 4; // disabled and unused rows. + + let max_rws = >::into(self.block_ctx.rwc) - 1 + + self.last_exec_step_rws_reserved(); + + // Computing the number of rows for the EVM circuit requires the size of ExecStep, + // which is determined in the code of zkevm-circuits and cannot be imported here. + // When the evm circuit receives a 0 value it dynamically computes the minimum + // number of rows necessary. + let max_evm_rows = 0; + // Similarly, computing the number of rows for the Keccak circuit requires + // constants that cannot be accessed from here (NUM_ROUNDS and KECCAK_ROWS). + // With a 0 value the keccak circuit computes dynamically the minimum number of rows + // needed. + let max_keccak_rows = 0; + FixedCParams { + total_chunks: self.circuits_params.total_chunks(), + max_rws, + max_txs, + max_withdrawals, + max_calldata, + max_copy_rows, + max_exp_steps, + max_bytecode, + max_evm_rows, + max_keccak_rows, + max_vertical_circuit_rows: 0, + } } } -impl CircuitInputBuilder { - /// First part of handle_block, common for dynamic and static circuit parameters. - pub fn begin_handle_block( - &mut self, +impl CircuitInputBuilder { + fn dry_run( + &self, eth_block: &EthBlock, geth_traces: &[eth_types::GethExecTrace], - ) -> Result<(), Error> { + ) -> Result, Error> { + let mut cib = self.clone(); + cib.circuits_params.total_chunks = 1; + cib.chunk_ctx.total_chunks = 1; // accumulates gas across all txs in the block for (idx, tx) in eth_block.transactions.iter().enumerate() { let geth_trace = &geth_traces[idx]; // Transaction index starts from 1 let tx_id = idx + 1; - self.handle_tx( + cib.handle_tx( tx, geth_trace, tx_id == eth_block.transactions.len(), @@ -429,87 +961,51 @@ impl CircuitInputBuilder { )?; } // set eth_block - self.block.eth_block = eth_block.clone(); - self.set_value_ops_call_context_rwc_eor(); - Ok(()) + cib.block.eth_block = eth_block.clone(); + cib.set_value_ops_call_context_rwc_eor(); + + debug_assert!( + cib.chunk_ctx.idx == 0, + "processing {} > 1 chunk", + cib.chunk_ctx.idx + ); // dry run mode only one chunk + + Ok(cib) } -} -impl CircuitInputBuilder { + /// Handle a block by handling each transaction to generate all the - /// associated operations. From these operations, the optimal circuit parameters - /// are derived and set. + /// associated operations. Dry run the block to determind the target + /// [`FixedCParams`] from to total number of chunks. pub fn handle_block( - mut self, + self, eth_block: &EthBlock, geth_traces: &[eth_types::GethExecTrace], ) -> Result, Error> { - self.begin_handle_block(eth_block, geth_traces)?; - - // Compute subcircuits parameters - let c_params = { - let max_txs = eth_block.transactions.len(); - let max_withdrawals = eth_block.withdrawals.as_ref().unwrap().len(); - let max_bytecode = self.code_db.num_rows_required_for_bytecode_table(); - - let max_calldata = eth_block - .transactions - .iter() - .fold(0, |acc, tx| acc + tx.input.len()); - let max_exp_steps = self - .block - .exp_events - .iter() - .fold(0usize, |acc, e| acc + e.steps.len()); - // The `+ 2` is used to take into account the two extra empty copy rows needed - // to satisfy the query at `Rotation(2)` performed inside of the - // `rows[2].value == rows[0].value * r + rows[1].value` requirement in the RLC - // Accumulation gate. - let max_copy_rows = self - .block - .copy_events - .iter() - .fold(0, |acc, c| acc + c.bytes.len()) - * 2 - + 4; // disabled and unused rows. - - let total_rws_before_padding: usize = - >::into(self.block_ctx.rwc) - 1; // -1 since rwc start from index `1` - let max_rws_after_padding = total_rws_before_padding - + 1 // fill 1 to have exactly one StartOp padding in below `set_end_block` - + if total_rws_before_padding > 0 { 1 /*end_block -> CallContextFieldTag::TxId lookup*/ } else { 0 }; - // Computing the number of rows for the EVM circuit requires the size of ExecStep, - // which is determined in the code of zkevm-circuits and cannot be imported here. - // When the evm circuit receives a 0 value it dynamically computes the minimum - // number of rows necessary. - let max_evm_rows = 0; - // Similarly, computing the number of rows for the Keccak circuit requires - // constants that cannot be accessed from here (NUM_ROUNDS and KECCAK_ROWS). - // With a 0 value the keccak circuit computes dynamically the minimum number of rows - // needed. - let max_keccak_rows = 0; - FixedCParams { - max_rws: max_rws_after_padding, - max_txs, - max_withdrawals, - max_calldata, - max_copy_rows, - max_exp_steps, - max_bytecode, - max_evm_rows, - max_keccak_rows, - } - }; - let mut cib = CircuitInputBuilder:: { + // Run the block without chunking and compute the blockwise params + let mut target_params = self + .dry_run(eth_block, geth_traces) + .expect("Dry run failure") + .compute_param(eth_block); + + // Calculate the chunkwise params from total number of chunks + let total_chunks = self.circuits_params.total_chunks; + target_params.total_chunks = total_chunks; + // count rws buffer here to left some space for extra virtual steps + target_params.max_rws = (target_params.max_rws + 1) / total_chunks + RW_BUFFER_SIZE; + + // Use a new builder with targeted params to handle the block + // chunking context is set to dynamic so for the actual param is update per chunk + let cib = CircuitInputBuilder:: { sdb: self.sdb, code_db: self.code_db, block: self.block, - circuits_params: c_params, + chunks: self.chunks, block_ctx: self.block_ctx, + chunk_ctx: ChunkContext::new(total_chunks), + circuits_params: target_params, feature_config: self.feature_config, }; - - cib.set_end_block(c_params.max_rws)?; - Ok(cib) + cib.handle_block(eth_block, geth_traces) } } @@ -536,7 +1032,7 @@ pub fn keccak_inputs(block: &Block, code_db: &CodeDB) -> Result>, Er } /// Generate the keccak inputs required by the SignVerify Chip from the -/// signature datas. +/// signature data. pub fn keccak_inputs_sign_verify(sigs: &[SignData]) -> Vec> { let mut inputs = Vec::new(); for sig in sigs { @@ -801,14 +1297,14 @@ impl BuilderClient

{ prev_state_root: Word, ) -> Result, Error> { let block = Block::new(self.chain_id, history_hashes, prev_state_root, eth_block)?; - let mut builder = CircuitInputBuilder::new( + let builder = CircuitInputBuilder::new( sdb, code_db, block, self.circuits_params, self.feature_config, ); - builder.handle_block(eth_block, geth_traces)?; + let builder = builder.handle_block(eth_block, geth_traces)?; Ok(builder) } diff --git a/bus-mapping/src/circuit_input_builder/access.rs b/bus-mapping/src/circuit_input_builder/access.rs index 1626d6f97a..086396e749 100644 --- a/bus-mapping/src/circuit_input_builder/access.rs +++ b/bus-mapping/src/circuit_input_builder/access.rs @@ -72,7 +72,7 @@ impl From> for AccessSet { for access in list { match access.value { AccessValue::Account { address } => { - state.entry(address).or_insert_with(HashSet::new); + state.entry(address).or_default(); } AccessValue::Storage { address, key } => match state.entry(address) { Entry::Vacant(entry) => { @@ -85,7 +85,7 @@ impl From> for AccessSet { } }, AccessValue::Code { address } => { - state.entry(address).or_insert_with(HashSet::new); + state.entry(address).or_default(); code.insert(address); } } diff --git a/bus-mapping/src/circuit_input_builder/block.rs b/bus-mapping/src/circuit_input_builder/block.rs index d2d97f4a0b..eb592a73ec 100644 --- a/bus-mapping/src/circuit_input_builder/block.rs +++ b/bus-mapping/src/circuit_input_builder/block.rs @@ -1,7 +1,8 @@ //! Block-related utility module use super::{ - execution::ExecState, transaction::Transaction, CopyEvent, ExecStep, ExpEvent, Withdrawal, + execution::ExecState, transaction::Transaction, CopyEvent, ExecStep, ExpEvent, PrecompileEvent, + PrecompileEvents, Withdrawal, }; use crate::{ operation::{OperationContainer, RWCounter}, @@ -42,24 +43,14 @@ impl BlockContext { } } -/// Block-wise execution steps that don't belong to any Transaction. -#[derive(Debug)] -pub struct BlockSteps { - /// EndBlock step that is repeated after the last transaction and before - /// reaching the last EVM row. - pub end_block_not_last: ExecStep, - /// Last EndBlock step that appears in the last EVM row. - pub end_block_last: ExecStep, -} - // TODO: Remove fields that are duplicated in`eth_block` /// Circuit Input related to a block. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Block { /// chain id pub chain_id: Word, /// history hashes contains most recent 256 block hashes in history, where - /// the lastest one is at history_hashes[history_hashes.len() - 1]. + /// the latest one is at history_hashes[history_hashes.len() - 1]. pub history_hashes: Vec, /// coinbase pub coinbase: Address, @@ -79,14 +70,20 @@ pub struct Block { pub container: OperationContainer, /// Transactions contained in the block pub txs: Vec, - /// Block-wise steps - pub block_steps: BlockSteps, + /// End block step + pub end_block: ExecStep, + + // /// Chunk context + // pub chunk_context: ChunkContext, /// Copy events in this block. pub copy_events: Vec, - /// Inputs to the SHA3 opcode + /// Inputs to the SHA3 opcode as well as data hashed during the EVM execution like init code + /// and address creation inputs. pub sha3_inputs: Vec>, /// Exponentiation events in the block. pub exp_events: Vec, + /// IO to/from the precompiled contract calls. + pub precompile_events: PrecompileEvents, /// Original block from geth pub eth_block: eth_types::Block, } @@ -132,19 +129,14 @@ impl Block { prev_state_root, container: OperationContainer::new(), txs: Vec::new(), - block_steps: BlockSteps { - end_block_not_last: ExecStep { - exec_state: ExecState::EndBlock, - ..ExecStep::default() - }, - end_block_last: ExecStep { - exec_state: ExecState::EndBlock, - ..ExecStep::default() - }, + end_block: ExecStep { + exec_state: ExecState::EndBlock, + ..ExecStep::default() }, copy_events: Vec::new(), exp_events: Vec::new(), sha3_inputs: Vec::new(), + precompile_events: PrecompileEvents { events: Vec::new() }, eth_block: eth_block.clone(), }) } @@ -191,4 +183,9 @@ impl Block { pub fn add_exp_event(&mut self, event: ExpEvent) { self.exp_events.push(event); } + + /// Push a precompile event to the block. + pub fn add_precompile_event(&mut self, event: PrecompileEvent) { + self.precompile_events.events.push(event); + } } diff --git a/bus-mapping/src/circuit_input_builder/call.rs b/bus-mapping/src/circuit_input_builder/call.rs index 564444d536..2052e2c1ea 100644 --- a/bus-mapping/src/circuit_input_builder/call.rs +++ b/bus-mapping/src/circuit_input_builder/call.rs @@ -63,7 +63,7 @@ pub struct Call { pub kind: CallKind, /// This call is being executed without write access (STATIC) pub is_static: bool, - /// This call generated implicity by a Transaction. + /// This call generated implicitly by a Transaction. pub is_root: bool, /// This call is persistent or call stack reverts at some point pub is_persistent: bool, @@ -123,7 +123,7 @@ impl Call { } /// Context of a [`Call`]. -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone)] pub struct CallContext { /// Index of call pub index: usize, @@ -151,7 +151,7 @@ impl CallContext { /// [`Operation::reversible`](crate::operation::Operation::reversible) that /// happened in them, that will be reverted at once when the call that initiated /// this reversion group eventually ends with failure (and thus reverts). -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone)] pub struct ReversionGroup { /// List of `index` and `reversible_write_counter_offset` of calls belong to /// this group. `reversible_write_counter_offset` is the number of diff --git a/bus-mapping/src/circuit_input_builder/chunk.rs b/bus-mapping/src/circuit_input_builder/chunk.rs new file mode 100644 index 0000000000..30ace0d91b --- /dev/null +++ b/bus-mapping/src/circuit_input_builder/chunk.rs @@ -0,0 +1,107 @@ +use super::{Call, ExecStep, FixedCParams}; +use crate::operation::RWCounter; + +#[derive(Debug, Default, Clone)] +pub struct Chunk { + /// current context + pub ctx: ChunkContext, + /// fixed param for the chunk + pub fixed_param: FixedCParams, + /// Begin op of a chunk + pub begin_chunk: Option, + /// End op of a chunk + pub end_chunk: Option, + /// Padding step that is repeated after the last transaction and before + /// reaching the last EVM row. + pub padding: Option, + /// + pub prev_last_call: Option, +} + +/// Context of chunking, used to track the current chunk index and inner rw counter +/// also the global rw counter from start to end. +#[derive(Debug, Clone)] +pub struct ChunkContext { + /// Index of current chunk, start from 0 + pub idx: usize, + /// Used to track the inner chunk counter in every operation in the chunk. + /// it will be reset for every new chunk. + /// Contains the next available value. + pub rwc: RWCounter, + /// Number of chunks + pub total_chunks: usize, + /// Initial global rw counter + pub initial_rwc: usize, + /// End global rw counter + pub end_rwc: usize, + /// tx range in block: [initial_tx_index, end_tx_index) + pub initial_tx_index: usize, + /// + pub end_tx_index: usize, + /// copy range in block: [initial_copy_index, end_copy_index) + pub initial_copy_index: usize, + /// + pub end_copy_index: usize, +} + +impl Default for ChunkContext { + fn default() -> Self { + Self::new(1) + } +} + +impl ChunkContext { + /// Create a new Self + pub fn new(total_chunks: usize) -> Self { + Self { + rwc: RWCounter::new(), + idx: 0, + total_chunks, + initial_rwc: 1, // rw counter start from 1 + end_rwc: 0, // end_rwc should be set in later phase + initial_tx_index: 0, + end_tx_index: 0, + initial_copy_index: 0, + end_copy_index: 0, + } + } + + /// New chunking context with one chunk + pub fn new_one_chunk() -> Self { + Self { + rwc: RWCounter::new(), + idx: 0, + total_chunks: 1, + initial_rwc: 1, // rw counter start from 1 + end_rwc: 0, // end_rwc should be set in later phase + initial_tx_index: 0, + end_tx_index: 0, + initial_copy_index: 0, + end_copy_index: 0, + } + } + + /// Proceed the context to next chunk, record the initial rw counter + /// update the chunk idx and reset the inner rw counter + pub fn bump(&mut self, initial_rwc: usize, initial_tx: usize, initial_copy: usize) { + assert!(self.idx + 1 < self.total_chunks, "Exceed total chunks"); + self.idx += 1; + self.rwc = RWCounter::new(); + self.initial_rwc = initial_rwc; + self.initial_tx_index = initial_tx; + self.initial_copy_index = initial_copy; + self.end_rwc = 0; + self.end_tx_index = 0; + self.end_copy_index = 0; + } + + /// Is first chunk + pub fn is_first_chunk(&self) -> bool { + self.idx == 0 + } + + /// Is last chunk + pub fn is_last_chunk(&self) -> bool { + self.total_chunks - self.idx - 1 == 0 + } +} diff --git a/bus-mapping/src/circuit_input_builder/execution.rs b/bus-mapping/src/circuit_input_builder/execution.rs index f23e80f7f2..fd5fc4310c 100644 --- a/bus-mapping/src/circuit_input_builder/execution.rs +++ b/bus-mapping/src/circuit_input_builder/execution.rs @@ -5,9 +5,9 @@ use crate::{ error::{ExecError, OogError}, exec_trace::OperationRef, operation::RWCounter, - precompile::PrecompileCalls, + precompile::{PrecompileAuxData, PrecompileCalls}, }; -use eth_types::{evm_types::OpcodeId, GethExecStep, Word, H256}; +use eth_types::{evm_types::OpcodeId, sign_types::SignData, GethExecStep, Word, H256}; use gadgets::impl_expr; use halo2_proofs::plonk::Expression; use strum_macros::EnumIter; @@ -35,6 +35,8 @@ pub struct ExecStep { pub call_index: usize, /// The global counter when this step was executed. pub rwc: RWCounter, + /// The inner chunk counter when this step was executed. + pub rwc_inner_chunk: RWCounter, /// Reversible Write Counter. Counter of write operations in the call that /// will need to be undone in case of a revert. Value at the beginning of /// the step. @@ -49,6 +51,8 @@ pub struct ExecStep { pub copy_rw_counter_delta: u64, /// Error generated by this step pub error: Option, + /// Optional auxiliary data that is attached to precompile call internal states. + pub aux_data: Option, } impl ExecStep { @@ -57,6 +61,7 @@ impl ExecStep { step: &GethExecStep, call_ctx: &CallContext, rwc: RWCounter, + rwc_inner_chunk: RWCounter, reversible_write_counter: usize, log_id: usize, ) -> Self { @@ -71,12 +76,14 @@ impl ExecStep { gas_refund: step.refund, call_index: call_ctx.index, rwc, + rwc_inner_chunk, reversible_write_counter, reversible_write_counter_delta: 0, log_id, bus_mapping_instance: Vec::new(), copy_rw_counter_delta: 0, error: None, + aux_data: None, } } @@ -140,12 +147,18 @@ pub enum ExecState { Op(OpcodeId), /// Precompile call Precompile(PrecompileCalls), + /// Virtual step Begin Chunk + BeginChunk, /// Virtual step Begin Tx BeginTx, /// Virtual step End Tx EndTx, + /// Virtual step Padding + Padding, /// Virtual step End Block EndBlock, + /// Virtual step End Chunk + EndChunk, /// Invalid Tx InvalidTx, } @@ -334,7 +347,7 @@ impl From<(Word, Word, Word)> for ExpStep { } } -/// Event representating an exponentiation `a ^ b == d (mod 2^256)`. +/// Event representing an exponentiation `a ^ b == d (mod 2^256)`. #[derive(Clone, Debug)] pub struct ExpEvent { /// Identifier for the exponentiation trace. @@ -364,3 +377,44 @@ impl Default for ExpEvent { } } } + +/// I/Os from all precompiled contract calls in a block. +#[derive(Clone, Debug, Default)] +pub struct PrecompileEvents { + /// All events. + pub events: Vec, +} + +impl PrecompileEvents { + /// Get all ecrecover events. + pub fn get_ecrecover_events(&self) -> Vec { + self.events + .iter() + .map(|e| { + let PrecompileEvent::Ecrecover(sign_data) = e; + sign_data + }) + .cloned() + .collect() + } +} + +/// I/O from a precompiled contract call. +#[derive(Clone, Debug)] +pub enum PrecompileEvent { + /// Represents the I/O from Ecrecover call. + Ecrecover(SignData), +} + +impl Default for PrecompileEvent { + fn default() -> Self { + Self::Ecrecover(SignData::default()) + } +} + +/// The number of pairing inputs per pairing operation. If the inputs provided to the precompile +/// call are < 4, we append (G1::infinity, G2::generator) until we have the required no. of inputs. +pub const N_PAIRING_PER_OP: usize = 4; + +/// The number of bytes taken to represent a pair (G1, G2). +pub const N_BYTES_PER_PAIR: usize = 192; diff --git a/bus-mapping/src/circuit_input_builder/input_state_ref.rs b/bus-mapping/src/circuit_input_builder/input_state_ref.rs index 38c0db5e30..214564d7a5 100644 --- a/bus-mapping/src/circuit_input_builder/input_state_ref.rs +++ b/bus-mapping/src/circuit_input_builder/input_state_ref.rs @@ -2,8 +2,8 @@ use super::{ get_call_memory_offset_length, get_create_init_code, Block, BlockContext, Call, CallContext, - CallKind, CodeSource, CopyEvent, ExecState, ExecStep, ExpEvent, Transaction, - TransactionContext, + CallKind, ChunkContext, CodeSource, CopyEvent, ExecState, ExecStep, ExpEvent, PrecompileEvent, + Transaction, TransactionContext, }; use crate::{ error::{DepthError, ExecError, InsufficientBalanceError, NonceUintOverflowError}, @@ -37,6 +37,8 @@ pub struct CircuitInputStateRef<'a> { pub block: &'a mut Block, /// Block Context pub block_ctx: &'a mut BlockContext, + /// Chunk Context + pub chunk_ctx: &'a mut ChunkContext, /// Transaction pub tx: &'a mut Transaction, /// Transaction Context @@ -49,11 +51,11 @@ impl<'a> CircuitInputStateRef<'a> { /// Create a new step from a `GethExecStep` pub fn new_step(&self, geth_step: &GethExecStep) -> Result { let call_ctx = self.tx_ctx.call_ctx()?; - Ok(ExecStep::new( geth_step, call_ctx, self.block_ctx.rwc, + self.chunk_ctx.rwc, call_ctx.reversible_write_counter, self.tx_ctx.log_id, )) @@ -65,6 +67,7 @@ impl<'a> CircuitInputStateRef<'a> { exec_state: ExecState::InvalidTx, gas_left: self.tx.gas(), rwc: self.block_ctx.rwc, + rwc_inner_chunk: self.chunk_ctx.rwc, ..Default::default() } } @@ -75,6 +78,7 @@ impl<'a> CircuitInputStateRef<'a> { exec_state: ExecState::BeginTx, gas_left: self.tx.gas(), rwc: self.block_ctx.rwc, + rwc_inner_chunk: self.chunk_ctx.rwc, ..Default::default() } } @@ -110,6 +114,7 @@ impl<'a> CircuitInputStateRef<'a> { 0 }, rwc: self.block_ctx.rwc, + rwc_inner_chunk: self.chunk_ctx.rwc, // For tx without code execution reversible_write_counter: if let Some(call_ctx) = self.tx_ctx.calls().last() { call_ctx.reversible_write_counter @@ -121,7 +126,7 @@ impl<'a> CircuitInputStateRef<'a> { } } - /// Push an [`Operation`](crate::operation::Operation) into the + /// Push an [`Operation`] into the /// [`OperationContainer`](crate::operation::OperationContainer) with the /// next [`RWCounter`](crate::operation::RWCounter) and then adds a /// reference to the stored operation ([`OperationRef`]) inside the @@ -131,10 +136,12 @@ impl<'a> CircuitInputStateRef<'a> { if let OpEnum::Account(op) = op.clone().into_enum() { self.check_update_sdb_account(rw, &op) } - let op_ref = - self.block - .container - .insert(Operation::new(self.block_ctx.rwc.inc_pre(), rw, op)); + let op_ref = self.block.container.insert(Operation::new( + self.block_ctx.rwc.inc_pre(), + self.chunk_ctx.rwc.inc_pre(), + rw, + op, + )); step.bus_mapping_instance.push(op_ref); self.check_rw_num_limit() } @@ -142,9 +149,13 @@ impl<'a> CircuitInputStateRef<'a> { /// Check whether rws will overflow circuit limit. pub fn check_rw_num_limit(&self) -> Result<(), Error> { if let Some(max_rws) = self.max_rws { - let rwc = self.block_ctx.rwc.0; + let rwc = self.chunk_ctx.rwc.0; if rwc > max_rws { - log::error!("rwc > max_rws, rwc={}, max_rws={}", rwc, max_rws); + log::error!( + "chunk inner rwc > max_rws, rwc={}, max_rws={}", + rwc, + max_rws + ); return Err(Error::RwsNotEnough(max_rws, rwc)); }; } @@ -196,8 +207,7 @@ impl<'a> CircuitInputStateRef<'a> { self.push_op(step, RW::WRITE, op) } - /// Push an [`Operation`](crate::operation::Operation) with reversible to be - /// true into the + /// Push an [`Operation`] with reversible to be true into the /// [`OperationContainer`](crate::operation::OperationContainer) with the /// next [`RWCounter`](crate::operation::RWCounter) and then adds a /// reference to the stored operation @@ -211,6 +221,7 @@ impl<'a> CircuitInputStateRef<'a> { self.check_apply_op(&op.clone().into_enum()); let op_ref = self.block.container.insert(Operation::new_reversible( self.block_ctx.rwc.inc_pre(), + self.chunk_ctx.rwc.inc_pre(), RW::WRITE, op, )); @@ -560,13 +571,13 @@ impl<'a> CircuitInputStateRef<'a> { /// balance by `value`. If `fee` is existing (not None), also need to push 1 /// non-reversible [`AccountOp`] to update `sender` balance by `fee`. #[allow(clippy::too_many_arguments)] - pub fn transfer_with_fee( + pub fn transfer( &mut self, step: &mut ExecStep, sender: Address, receiver: Address, receiver_exists: bool, - must_create: bool, + is_create: bool, value: Word, fee: Option, ) -> Result<(), Error> { @@ -609,82 +620,35 @@ impl<'a> CircuitInputStateRef<'a> { sender_balance_prev, sender_balance ); - // If receiver doesn't exist, create it - if !receiver_exists && (!value.is_zero() || must_create) { + + if !value.is_zero() { self.push_op_reversible( step, AccountOp { - address: receiver, - field: AccountField::CodeHash, - value: CodeDB::empty_code_hash().to_word(), - value_prev: Word::zero(), + address: sender, + field: AccountField::Balance, + value: sender_balance, + value_prev: sender_balance_prev, }, )?; } - if value.is_zero() { - // Skip transfer if value == 0 - return Ok(()); - } - self.push_op_reversible( - step, - AccountOp { - address: sender, - field: AccountField::Balance, - value: sender_balance, - value_prev: sender_balance_prev, - }, - )?; - - let (_found, receiver_account) = self.sdb.get_account(&receiver); - let receiver_balance_prev = receiver_account.balance; - let receiver_balance = receiver_account.balance + value; - self.push_op_reversible( - step, - AccountOp { - address: receiver, - field: AccountField::Balance, - value: receiver_balance, - value_prev: receiver_balance_prev, - }, - )?; + self.transfer_to(step, receiver, receiver_exists, is_create, value, true)?; Ok(()) } - /// Same functionality with `transfer_with_fee` but with `fee` set zero. - pub fn transfer( - &mut self, - step: &mut ExecStep, - sender: Address, - receiver: Address, - receiver_exists: bool, - must_create: bool, - value: Word, - ) -> Result<(), Error> { - self.transfer_with_fee( - step, - sender, - receiver, - receiver_exists, - must_create, - value, - None, - ) - } - /// Transfer to an address. Create an account if it is not existed before. pub fn transfer_to( &mut self, step: &mut ExecStep, receiver: Address, receiver_exists: bool, - must_create: bool, + is_create: bool, value: Word, reversible: bool, ) -> Result<(), Error> { - // If receiver doesn't exist, create it - if (!receiver_exists && !value.is_zero()) || must_create { + if !receiver_exists && (!value.is_zero() || is_create) { self.account_write( step, receiver, @@ -1057,6 +1021,7 @@ impl<'a> CircuitInputStateRef<'a> { self.check_apply_op(&op); let rev_op_ref = self.block.container.insert_op_enum( self.block_ctx.rwc.inc_pre(), + self.chunk_ctx.rwc.inc_pre(), RW::WRITE, false, op, @@ -1225,7 +1190,7 @@ impl<'a> CircuitInputStateRef<'a> { ) -> Result<(), Error> { let call = self.call()?.clone(); let geth_step = steps - .get(0) + .first() .ok_or(Error::InternalError("invalid index 0"))?; let is_revert_or_return_call_success = (geth_step.op == OpcodeId::REVERT || geth_step.op == OpcodeId::RETURN) @@ -1404,6 +1369,11 @@ impl<'a> CircuitInputStateRef<'a> { self.block.add_exp_event(event) } + /// Push an event representing auxiliary data for a precompile call to the state. + pub fn push_precompile_event(&mut self, event: PrecompileEvent) { + self.block.add_precompile_event(event) + } + pub(crate) fn get_step_err( &self, step: &GethExecStep, @@ -1419,7 +1389,7 @@ impl<'a> CircuitInputStateRef<'a> { let call = self.call()?; - if matches!(next_step, None) { + if next_step.is_none() { // enumerating call scope successful cases // case 1: call with normal halt opcode termination if matches!( @@ -1614,7 +1584,6 @@ impl<'a> CircuitInputStateRef<'a> { PrecompileCalls::Sha256 | PrecompileCalls::Ripemd160 | PrecompileCalls::Blake2F - | PrecompileCalls::ECRecover | PrecompileCalls::Bn128Add | PrecompileCalls::Bn128Mul | PrecompileCalls::Bn128Pairing diff --git a/bus-mapping/src/circuit_input_builder/tracer_tests.rs b/bus-mapping/src/circuit_input_builder/tracer_tests.rs index 0855d491eb..9ce73c4599 100644 --- a/bus-mapping/src/circuit_input_builder/tracer_tests.rs +++ b/bus-mapping/src/circuit_input_builder/tracer_tests.rs @@ -146,7 +146,7 @@ fn check_err_depth(step: &GethExecStep, next_step: Option<&GethExecStep>) -> boo #[test] fn tracer_err_depth() { - // Recursive CALL will exaust the call depth + // Recursive CALL will exhaust the call depth let code = bytecode! { PUSH1(0x0) // retLength PUSH1(0x0) // retOffset diff --git a/bus-mapping/src/circuit_input_builder/transaction.rs b/bus-mapping/src/circuit_input_builder/transaction.rs index 9b86e197e1..6783a78191 100644 --- a/bus-mapping/src/circuit_input_builder/transaction.rs +++ b/bus-mapping/src/circuit_input_builder/transaction.rs @@ -12,7 +12,7 @@ use crate::{ use super::{call::ReversionGroup, Call, CallContext, CallKind, CodeSource, ExecStep}; -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone)] /// Context of a [`Transaction`] which can mutate in an [`ExecStep`]. pub struct TransactionContext { /// Unique identifier of transaction of the block. The value is `index + 1`. @@ -182,7 +182,7 @@ pub struct Transaction { /// The transaction id pub id: u64, /// The raw transaction fields - tx: geth_types::Transaction, + pub tx: geth_types::Transaction, /// Calls made in the transaction pub(crate) calls: Vec, /// Execution steps @@ -190,6 +190,16 @@ pub struct Transaction { } impl Transaction { + /// Create a dummy Transaction with zero values + pub fn dummy() -> Self { + Self { + id: 0, + calls: Vec::new(), + steps: Vec::new(), + tx: geth_types::Transaction::dummy(), + } + } + /// Create a new Self. pub fn new( id: u64, diff --git a/bus-mapping/src/error.rs b/bus-mapping/src/error.rs index 313ed43652..a125fdb421 100644 --- a/bus-mapping/src/error.rs +++ b/bus-mapping/src/error.rs @@ -105,7 +105,7 @@ pub enum OogError { SelfDestruct, } -// Given OpCodeId, returns correponding OogError. +// Given OpCodeId, returns corresponding OogError. impl From<&OpcodeId> for OogError { fn from(op: &OpcodeId) -> Self { match op { diff --git a/bus-mapping/src/evm/opcodes.rs b/bus-mapping/src/evm/opcodes.rs index 7e2812351a..3be582fc20 100644 --- a/bus-mapping/src/evm/opcodes.rs +++ b/bus-mapping/src/evm/opcodes.rs @@ -115,8 +115,7 @@ pub use crate::precompile::PrecompileCallArgs; /// Generic opcode trait which defines the logic of the /// [`Operation`](crate::operation::Operation) that should be generated for one -/// or multiple [`ExecStep`](crate::circuit_input_builder::ExecStep) depending -/// of the [`OpcodeId`] it contains. +/// or multiple [`ExecStep`] depending of the [`OpcodeId`] it contains. pub trait Opcode: Debug { /// Generate the associated [`MemoryOp`](crate::operation::MemoryOp)s, /// [`StackOp`](crate::operation::StackOp)s, and diff --git a/bus-mapping/src/evm/opcodes/begin_end_tx.rs b/bus-mapping/src/evm/opcodes/begin_end_tx.rs index 1b6c79a5c8..69ad7432f0 100644 --- a/bus-mapping/src/evm/opcodes/begin_end_tx.rs +++ b/bus-mapping/src/evm/opcodes/begin_end_tx.rs @@ -1,6 +1,8 @@ use super::TxExecSteps; use crate::{ - circuit_input_builder::{Call, CircuitInputStateRef, ExecState, ExecStep}, + circuit_input_builder::{ + Call, CircuitInputStateRef, CopyDataType, CopyEvent, ExecState, ExecStep, NumberOrHash, + }, operation::{AccountField, AccountOp, CallContextField, TxReceiptField, TxRefundOp, RW}, state_db::CodeDB, Error, @@ -122,7 +124,7 @@ fn gen_begin_tx_steps(state: &mut CircuitInputStateRef) -> Result Result 0 { + state.push_copy( + &mut exec_step, + CopyEvent { + src_addr: 0, + src_addr_end: state.tx.call_data.len() as u64, + src_type: CopyDataType::TxCalldata, + src_id: NumberOrHash::Number(state.tx.id as usize), + dst_addr: 0, + dst_type: CopyDataType::RlcAcc, + dst_id: NumberOrHash::Number(0), + log_id: None, + rw_counter_start: state.block_ctx.rwc, + bytes: state.tx.call_data.iter().map(|b| (*b, false)).collect(), + }, + ); + } } // There are 4 branches from here. diff --git a/bus-mapping/src/evm/opcodes/callop.rs b/bus-mapping/src/evm/opcodes/callop.rs index 316bfe454d..d1acfbd9fd 100644 --- a/bus-mapping/src/evm/opcodes/callop.rs +++ b/bus-mapping/src/evm/opcodes/callop.rs @@ -170,7 +170,7 @@ impl Opcode for CallOpcode { // read balance of caller to compare to value for insufficient_balance checking // in circuit, also use for callcode successful case check balance is // indeed larger than transfer value. for call opcode, it does in - // tranfer gadget implicitly. + // transfer gadget implicitly. state.account_read( &mut exec_step, call.caller_address, @@ -195,6 +195,7 @@ impl Opcode for CallOpcode { callee_exists, false, call.value, + None, )?; } @@ -362,7 +363,7 @@ impl Opcode for CallOpcode { // insert a copy event (input) for this step and generate memory op let rw_counter_start = state.block_ctx.rwc; - if call.call_data_length > 0 { + let input_bytes = if call.call_data_length > 0 { let n_input_bytes = if let Some(input_len) = precompile_call.input_len() { min(input_len, call.call_data_length as usize) } else { @@ -390,11 +391,14 @@ impl Opcode for CallOpcode { bytes: input_bytes.iter().map(|s| (*s, false)).collect(), }, ); - } + Some(input_bytes) + } else { + None + }; // write the result in the callee's memory let rw_counter_start = state.block_ctx.rwc; - if call.is_success && !result.is_empty() { + let output_bytes = if call.is_success && !result.is_empty() { let (output_bytes, _prev_bytes) = state .gen_copy_steps_for_precompile_callee_memory(&mut exec_step, &result)?; @@ -413,11 +417,14 @@ impl Opcode for CallOpcode { bytes: output_bytes.iter().map(|s| (*s, false)).collect(), }, ); - } + Some(output_bytes) + } else { + None + }; // insert another copy event (output) for this step. let rw_counter_start = state.block_ctx.rwc; - if call.is_success && length > 0 { + let return_bytes = if call.is_success && length > 0 { let return_bytes = state.gen_copy_steps_for_precompile_returndata( &mut exec_step, call.return_data_offset, @@ -439,7 +446,10 @@ impl Opcode for CallOpcode { bytes: return_bytes.iter().map(|s| (*s, false)).collect(), }, ); - } + Some(return_bytes) + } else { + None + }; if has_oog_err { let mut oog_step = ErrorOOGPrecompile::gen_associated_ops( @@ -462,6 +472,9 @@ impl Opcode for CallOpcode { geth_steps[1].clone(), call.clone(), precompile_call, + &input_bytes.unwrap_or_default(), + &output_bytes.unwrap_or_default(), + &return_bytes.unwrap_or_default(), )?; // Set gas left and gas cost for precompile step. diff --git a/bus-mapping/src/evm/opcodes/create.rs b/bus-mapping/src/evm/opcodes/create.rs index 51b399b099..c1a0bbf940 100644 --- a/bus-mapping/src/evm/opcodes/create.rs +++ b/bus-mapping/src/evm/opcodes/create.rs @@ -217,8 +217,9 @@ impl Opcode for Create { caller.address, callee.address, callee_exists, - !callee_exists, + true, callee.value, + None, )?; // EIP 161, increase callee's nonce diff --git a/bus-mapping/src/evm/opcodes/error_oog_exp.rs b/bus-mapping/src/evm/opcodes/error_oog_exp.rs index 23d7d7c76d..c8ae7f4960 100644 --- a/bus-mapping/src/evm/opcodes/error_oog_exp.rs +++ b/bus-mapping/src/evm/opcodes/error_oog_exp.rs @@ -7,7 +7,7 @@ use crate::{ use eth_types::GethExecStep; /// Placeholder structure used to implement [`Opcode`] trait over it -/// corresponding to the [`OogError::Exp`](crate::error::OogError::Exp). +/// corresponding to the [`OogError::Exp`]. #[derive(Clone, Copy, Debug)] pub(crate) struct OOGExp; diff --git a/bus-mapping/src/evm/opcodes/error_oog_memory_copy.rs b/bus-mapping/src/evm/opcodes/error_oog_memory_copy.rs index 50327115ba..ef1b35c916 100644 --- a/bus-mapping/src/evm/opcodes/error_oog_memory_copy.rs +++ b/bus-mapping/src/evm/opcodes/error_oog_memory_copy.rs @@ -8,8 +8,7 @@ use crate::{ use eth_types::{evm_types::OpcodeId, GethExecStep, ToAddress}; /// Placeholder structure used to implement [`Opcode`] trait over it -/// corresponding to the -/// [`OogError::MemoryCopy`](crate::error::OogError::MemoryCopy). +/// corresponding to the [`OogError::MemoryCopy`]. #[derive(Clone, Copy, Debug)] pub(crate) struct OOGMemoryCopy; diff --git a/bus-mapping/src/evm/opcodes/error_oog_sload_sstore.rs b/bus-mapping/src/evm/opcodes/error_oog_sload_sstore.rs index 285ba59607..4ab139d39b 100644 --- a/bus-mapping/src/evm/opcodes/error_oog_sload_sstore.rs +++ b/bus-mapping/src/evm/opcodes/error_oog_sload_sstore.rs @@ -8,8 +8,7 @@ use crate::{ use eth_types::{GethExecStep, ToWord}; /// Placeholder structure used to implement [`Opcode`] trait over it -/// corresponding to the -/// [`OogError::SloadSstore`](crate::error::OogError::SloadSstore). +/// corresponding to the [`OogError::SloadSstore`]. #[derive(Clone, Copy, Debug)] pub(crate) struct OOGSloadSstore; diff --git a/bus-mapping/src/evm/opcodes/error_write_protection.rs b/bus-mapping/src/evm/opcodes/error_write_protection.rs index 2c9bd0b87e..65c3cb9eee 100644 --- a/bus-mapping/src/evm/opcodes/error_write_protection.rs +++ b/bus-mapping/src/evm/opcodes/error_write_protection.rs @@ -44,7 +44,7 @@ impl Opcode for ErrorWriteProtection { .contains(&geth_step.op)); if geth_step.op == OpcodeId::CALL { - // get only the frist three stack elements since the third one is the value we + // get only the first three stack elements since the third one is the value we // want to check. for i in 0..3 { state.stack_read( diff --git a/bus-mapping/src/evm/opcodes/precompiles/mod.rs b/bus-mapping/src/evm/opcodes/precompiles.rs similarity index 56% rename from bus-mapping/src/evm/opcodes/precompiles/mod.rs rename to bus-mapping/src/evm/opcodes/precompiles.rs index 70e62ce54c..ac16d21f6b 100644 --- a/bus-mapping/src/evm/opcodes/precompiles/mod.rs +++ b/bus-mapping/src/evm/opcodes/precompiles.rs @@ -3,15 +3,22 @@ use eth_types::{GethExecStep, ToWord, Word}; use crate::{ circuit_input_builder::{Call, CircuitInputStateRef, ExecState, ExecStep}, operation::CallContextField, - precompile::PrecompileCalls, + precompile::{PrecompileAuxData, PrecompileCalls}, Error, }; +mod ecrecover; + +use ecrecover::opt_data as opt_data_ecrecover; + pub fn gen_associated_ops( state: &mut CircuitInputStateRef, geth_step: GethExecStep, call: Call, precompile: PrecompileCalls, + input_bytes: &[u8], + output_bytes: &[u8], + return_bytes: &[u8], ) -> Result { assert_eq!(call.code_address(), Some(precompile.into())); let mut exec_step = state.new_step(&geth_step)?; @@ -19,6 +26,35 @@ pub fn gen_associated_ops( common_call_ctx_reads(state, &mut exec_step, &call)?; + let (opt_event, aux_data) = match precompile { + PrecompileCalls::Ecrecover => opt_data_ecrecover(input_bytes, output_bytes, return_bytes), + PrecompileCalls::Identity => ( + None, + Some(PrecompileAuxData::Base { + input_bytes: input_bytes.to_vec(), + output_bytes: output_bytes.to_vec(), + return_bytes: return_bytes.to_vec(), + }), + ), + _ => { + log::warn!("precompile {:?} unsupported in circuits", precompile); + ( + None, + Some(PrecompileAuxData::Base { + input_bytes: input_bytes.to_vec(), + output_bytes: output_bytes.to_vec(), + return_bytes: return_bytes.to_vec(), + }), + ) + } + }; + log::trace!("precompile event {opt_event:?}, aux data {aux_data:?}"); + + if let Some(event) = opt_event { + state.push_precompile_event(event); + } + exec_step.aux_data = aux_data; + Ok(exec_step) } diff --git a/bus-mapping/src/evm/opcodes/precompiles/ecrecover.rs b/bus-mapping/src/evm/opcodes/precompiles/ecrecover.rs new file mode 100644 index 0000000000..6bcf5f36ca --- /dev/null +++ b/bus-mapping/src/evm/opcodes/precompiles/ecrecover.rs @@ -0,0 +1,60 @@ +use eth_types::{ + sign_types::{biguint_to_32bytes_le, recover_pk, SignData, SECP256K1_Q}, + ToBigEndian, ToLittleEndian, +}; +use halo2_proofs::halo2curves::{ + group::{ff::PrimeField, prime::PrimeCurveAffine}, + secp256k1::{Fq, Secp256k1Affine}, +}; +use num::{BigUint, Integer}; + +use crate::{ + circuit_input_builder::PrecompileEvent, + precompile::{EcrecoverAuxData, PrecompileAuxData}, +}; + +pub(crate) fn opt_data( + input_bytes: &[u8], + output_bytes: &[u8], + return_bytes: &[u8], +) -> (Option, Option) { + let aux_data = EcrecoverAuxData::new(input_bytes, output_bytes, return_bytes); + + // We skip the validation through sig circuit if r or s was not in canonical form. + let opt_sig_r: Option = Fq::from_bytes(&aux_data.sig_r.to_le_bytes()).into(); + let opt_sig_s: Option = Fq::from_bytes(&aux_data.sig_s.to_le_bytes()).into(); + if opt_sig_r.zip(opt_sig_s).is_none() { + return (None, Some(PrecompileAuxData::Ecrecover(aux_data))); + } + + if let Some(sig_v) = aux_data.recovery_id() { + let recovered_pk = recover_pk( + sig_v, + &aux_data.sig_r, + &aux_data.sig_s, + &aux_data.msg_hash.to_be_bytes(), + ) + .unwrap_or(Secp256k1Affine::identity()); + let sign_data = SignData { + signature: ( + Fq::from_bytes(&aux_data.sig_r.to_le_bytes()).unwrap(), + Fq::from_bytes(&aux_data.sig_s.to_le_bytes()).unwrap(), + sig_v, + ), + pk: recovered_pk, + msg: aux_data.input_bytes.clone().into(), + msg_hash: { + let msg_hash = BigUint::from_bytes_be(&aux_data.msg_hash.to_be_bytes()); + let msg_hash = msg_hash.mod_floor(&*SECP256K1_Q); + let msg_hash_le = biguint_to_32bytes_le(msg_hash); + Fq::from_repr(msg_hash_le).unwrap() + }, + }; + ( + Some(PrecompileEvent::Ecrecover(sign_data)), + Some(PrecompileAuxData::Ecrecover(aux_data)), + ) + } else { + (None, Some(PrecompileAuxData::Ecrecover(aux_data))) + } +} diff --git a/bus-mapping/src/exec_trace.rs b/bus-mapping/src/exec_trace.rs index 41e405c1cd..28c886240b 100644 --- a/bus-mapping/src/exec_trace.rs +++ b/bus-mapping/src/exec_trace.rs @@ -5,7 +5,7 @@ use std::fmt; #[derive(Clone, Copy, PartialEq, Eq)] /// The target and index of an `Operation` in the context of an -/// `ExecutionTrace`. +/// [`GethExecTrace`](eth_types::GethExecTrace). pub struct OperationRef(pub Target, pub usize); impl fmt::Debug for OperationRef { @@ -14,6 +14,7 @@ impl fmt::Debug for OperationRef { "OperationRef{{ {}, {} }}", match self.0 { Target::Start => "Start", + Target::Padding => "Padding", Target::Memory => "Memory", Target::Stack => "Stack", Target::Storage => "Storage", @@ -24,6 +25,7 @@ impl fmt::Debug for OperationRef { Target::CallContext => "CallContext", Target::TxReceipt => "TxReceipt", Target::TxLog => "TxLog", + Target::StepState => "StepState", }, self.1 )) diff --git a/bus-mapping/src/lib.rs b/bus-mapping/src/lib.rs index abd38f9141..dfa5675791 100644 --- a/bus-mapping/src/lib.rs +++ b/bus-mapping/src/lib.rs @@ -1,219 +1,8 @@ -//! ![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/appliedzkp/zkevm-circuits/CI%20checks/main?style=for-the-badge) -//! Bus-Mapping is a crate designed to parse EVM execution traces and manipulate -//! all of the data they provide in order to obtain structured witness inputs -//! for the EVM Proof and the State Proof. -//! -//! ## Introduction -//! At the moment every node on ethereum has to validate every transaction in -//! the ethereum virtual machine. This means that every transaction adds work -//! that everyone needs to do to verify Ethereum’s history. Worse still is that -//! each transaction needs to be verified by every new node. Which means the -//! amount of work a new node needs to do the sync the network is growing -//! constantly. We want to build a proof of validity for the Ethereum blocks to -//! avoid this. -//! -//! This means making a proof of validity for the EVM + state reads / writes + -//! signatures. -//! To simplify we separate our proofs into two components. -//! -//! - State proof: State/memory/stack ops have been performed correctly. This -//! does not check if the correct location has been read/written. We allow our -//! prover to pick any location here and in the EVM proof confirm it is correct. -//! -//! - EVM proof: This checks that the correct opcode is called at the correct -//! time. It checks the validity of these opcodes. It also confirms that for -//! each of these opcodes the state proof performed the correct operation. -//! -//! Only after verifying both proofs are we confident that that Ethereum block -//! is executed correctly. -//! -//! ## Bus Mapping -//! The goal of this crate is to serve as: -//! - A parsing lib for EVM execution traces. -//! - A way to infer some witness data that can only be constructed once we've analyzed the full -//! exec trace. -//! - An easy interface to collect all of the data to witness into the circuits and witness it with -//! few function calls. -//! -//! ## Parsing -//! Provided a JSON file or a JSON as a stream of bytes, which contains an -//! execution trace from an EVM, you can parse it and construct an -//! `ExecutionTrace` instance from it. That will automatically fill all of the -//! bus-mapping instances of each -//! [`GethExecStep`](eth_types::GethExecStep). Then the -//! [`CircuitInputBuilder`](crate::circuit_input_builder::CircuitInputBuilder) -//! will fill in an -//! [`OperationContainer`](crate::operation::container::OperationContainer) -//! with all of the Memory, Stack and Storage ops performed -//! by the provided trace. -//! -//! ```rust -//! use bus_mapping::{Error, mock::BlockData}; -//! use bus_mapping::state_db::{self, StateDB, CodeDB}; -//! use eth_types::{ -//! self, address, Address, Word, Hash, U64, GethExecTrace, GethExecStep, geth_types::GethData, bytecode -//! }; -//! use mock::test_ctx::{TestContext, helpers::*}; -//! use bus_mapping::circuit_input_builder::{Block, CircuitInputBuilder}; -//! -//! let input_trace = r#" -//! [ -//! { -//! "pc": 5, -//! "op": "PUSH1", -//! "gas": 82, -//! "gasCost": 3, -//! "refund": 0, -//! "depth": 1, -//! "stack": [], -//! "memory": [ -//! "0000000000000000000000000000000000000000000000000000000000000000", -//! "0000000000000000000000000000000000000000000000000000000000000000", -//! "0000000000000000000000000000000000000000000000000000000000000080" -//! ] -//! }, -//! { -//! "pc": 7, -//! "op": "MLOAD", -//! "gas": 79, -//! "gasCost": 3, -//! "refund": 0, -//! "depth": 1, -//! "stack": [ -//! "40" -//! ], -//! "memory": [ -//! "0000000000000000000000000000000000000000000000000000000000000000", -//! "0000000000000000000000000000000000000000000000000000000000000000", -//! "0000000000000000000000000000000000000000000000000000000000000080" -//! ] -//! }, -//! { -//! "pc": 8, -//! "op": "STOP", -//! "gas": 76, -//! "gasCost": 0, -//! "refund": 0, -//! "depth": 1, -//! "stack": [ -//! "80" -//! ], -//! "memory": [ -//! "0000000000000000000000000000000000000000000000000000000000000000", -//! "0000000000000000000000000000000000000000000000000000000000000000", -//! "0000000000000000000000000000000000000000000000000000000000000080" -//! ] -//! } -//! ] -//! "#; -//! -//! // We use the [`TestContext`] struct to mock a block. -//! let code = bytecode! { -//! // Write 0x6f to storage slot 0 -//! PUSH1(0x6fu64) -//! PUSH1(0x00u64) -//! SSTORE -//! // Load storage slot 0 -//! PUSH1(0x00u64) -//! SLOAD -//! STOP -//! }; -//! -//! // Get the execution steps from the external tracer -//! let block: GethData = TestContext::<2, 1>::new( -//! None, -//! account_0_code_account_1_no_code(code), -//! tx_from_1_to_0, -//! |block, _tx| block.number(0xcafeu64), -//! ) -//! .unwrap() -//! .into(); -//! -//! // Here we update the circuit input with the data from the transaction trace. -//! let builder = BlockData::new_from_geth_data(block.clone()).new_circuit_input_builder(); -//! let builder = builder -//! .handle_block(&block.eth_block, &block.geth_traces) -//! .unwrap(); -//! -//! let geth_steps: Vec = serde_json::from_str(input_trace).unwrap(); -//! let geth_trace = GethExecTrace { -//! return_value: "".to_string(), -//! gas: block.eth_block.transactions[0].gas.as_u64(), -//! invalid: false, -//! failed: false, -//! struct_logs: geth_steps, -//! }; -//! -//! // Get an ordered vector with all of the Stack operations of this trace. -//! let stack_ops = builder.block.container.sorted_stack(); -//! -//! // You can also iterate over the steps of the trace and witness the EVM Proof. -//! builder.block.txs()[0].steps().iter(); -//! ``` -//! -//! Assume we have the following trace: -//! ```text,ignore -//! pc op stack (top -> down) memory -//! -- -------------- ---------------------------------- --------------------------------------- -//! ... -//! 53 JUMPDEST [ , , , ] {40: 80, 80: , a0: } -//! 54 PUSH1 40 [ , , , 40] {40: 80, 80: , a0: } -//! 56 MLOAD [ , , , 80] {40: 80, 80: , a0: } -//! 57 PUSH4 deadbeaf [ , , deadbeef, 80] {40: 80, 80: , a0: } -//! 62 DUP2 [ , 80, deadbeef, 80] {40: 80, 80: , a0: } -//! 63 MSTORE [ , , , 80] {40: 80, 80: deadbeef, a0: } -//! 64 PUSH4 faceb00c [ , , faceb00c, 80] {40: 80, 80: deadbeef, a0: } -//! 69 DUP2 [ , 80, faceb00c, 80] {40: 80, 80: deadbeef, a0: } -//! 70 MLOAD [ , deadbeef, faceb00c, 80] {40: 80, 80: deadbeef, a0: } -//! 71 ADD [ , , 1d97c6efb, 80] {40: 80, 80: deadbeef, a0: } -//! 72 DUP2 [ , 80, 1d97c6efb, 80] {40: 80, 80: deadbeef, a0: } -//! 73 MSTORE [ , , , 80] {40: 80, 80: 1d97c6efb, a0: } -//! 74 PUSH4 cafeb0ba [ , , cafeb0ba, 80] {40: 80, 80: 1d97c6efb, a0: } -//! 79 PUSH1 20 [ , 20, cafeb0ba, 80] {40: 80, 80: 1d97c6efb, a0: } -//! 81 DUP3 [ 80, 20, cafeb0ba, 80] {40: 80, 80: 1d97c6efb, a0: } -//! 82 ADD [ , a0, cafeb0ba, 80] {40: 80, 80: 1d97c6efb, a0: } -//! 83 MSTORE [ , , , 80] {40: 80, 80: 1d97c6efb, a0: cafeb0ba} -//! 84 POP [ , , , ] {40: 80, 80: 1d97c6efb, a0: cafeb0ba} -//! ... -//! ``` -//! -//! Once you have the trace built (following the code found above) you can -//! basically: -//! - Get an iterator/vector over the `Stack`, `Memory` or `Storage` operations ordered on the way -//! the State Proof needs. -//! -//! On that way, we would get something like this for the Memory ops: -//! ```text,ignore -//! | `key` | `val` | `rw` | `gc` | Note | -//! |:------:| ------------- | ------- | ---- | ---------------------------------------- | -//! | `0x40` | `0` | `Write` | | Init | -//! | `0x40` | `0x80` | `Write` | 0 | Assume written at the begining of `code` | -//! | `0x40` | `0x80` | `Read` | 4 | `56 MLOAD` | -//! | - | | | | | -//! | `0x80` | `0` | `Write` | | Init | -//! | `0x80` | `0xdeadbeef` | `Write` | 10 | `63 MSTORE` | -//! | `0x80` | `0xdeadbeef` | `Read` | 16 | `70 MLOAD` | -//! | `0x80` | `0x1d97c6efb` | `Write` | 24 | `73 MSTORE` | -//! | - | | | | | -//! | `0xa0` | `0` | `Write` | | Init | -//! | `0xa0` | `0xcafeb0ba` | `Write` | 34 | `83 MSTORE` -//! ``` -//! -//! Where as you see, we group by `memory_address` and then order by -//! `global_counter`. -//! -//! - Iterate over the `ExecutionTrace` itself over -//! each `ExecutionStep`'s is formed by and check which Stack/Memory&Storage -//! operations are linked to each step. This is also automatically done via the -//! [`Opcode`](crate::evm::opcodes::Opcode) trait defined in this crate. -//! -//! ## Documentation -//! For extra documentation, check the book with the specs written for the -//! entire ZK-EVM solution. -//! See: - +#![doc = include_str!("../README.md")] +// doc test attr +#![doc(test(attr(deny(warnings))))] #![cfg_attr(docsrs, feature(doc_cfg))] -// We want to have UPPERCASE idents sometimes. +// We want to have UPPERCASE indents sometimes. #![allow(non_snake_case)] // Catch documentation errors caused by code changes. #![deny(rustdoc::broken_intra_doc_links)] diff --git a/bus-mapping/src/mock.rs b/bus-mapping/src/mock.rs index 08a581e318..892eb41c3f 100644 --- a/bus-mapping/src/mock.rs +++ b/bus-mapping/src/mock.rs @@ -20,7 +20,7 @@ pub struct BlockData { /// chain id pub chain_id: Word, /// history hashes contains most recent 256 block hashes in history, where - /// the lastest one is at history_hashes[history_hashes.len() - 1]. + /// the latest one is at history_hashes[history_hashes.len() - 1]. pub history_hashes: Vec, /// Block from geth pub eth_block: eth_types::Block, @@ -96,8 +96,15 @@ impl BlockData { } impl BlockData { - /// Create a new block from the given Geth data with default CircuitsParams. + /// Create a new block with one chunk + /// from the given Geth data with default CircuitsParams. pub fn new_from_geth_data(geth_data: GethData) -> Self { + Self::new_from_geth_data_chunked(geth_data, 1) + } + + /// Create a new block with given number of chunks + /// from the given Geth data with default CircuitsParams. + pub fn new_from_geth_data_chunked(geth_data: GethData, total_chunks: usize) -> Self { let (sdb, code_db) = Self::init_dbs(&geth_data); Self { @@ -107,7 +114,7 @@ impl BlockData { history_hashes: geth_data.history_hashes, eth_block: geth_data.eth_block, geth_traces: geth_data.geth_traces, - circuits_params: DynamicCParams {}, + circuits_params: DynamicCParams { total_chunks }, } } } diff --git a/bus-mapping/src/operation.rs b/bus-mapping/src/operation.rs index 26469c77b5..c0b4ab4e78 100644 --- a/bus-mapping/src/operation.rs +++ b/bus-mapping/src/operation.rs @@ -90,11 +90,11 @@ impl RWCounter { } } -/// Enum used to differenciate between EVM Stack, Memory and Storage operations. +/// Enum used to differentiate between EVM Stack, Memory and Storage operations. /// This is also used as the RwTableTag for the RwTable. #[derive(Debug, Clone, PartialEq, Eq, Copy, EnumIter, Hash)] pub enum Target { - /// Start is a padding operation. + /// Start operation in the first row Start = 1, /// Means the target of the operation is the Memory. Memory, @@ -116,6 +116,11 @@ pub enum Target { TxReceipt, /// Means the target of the operation is the TxLog. TxLog, + + /// Chunking: StepState + StepState, + /// Chunking: padding operation. + Padding, } impl_expr!(Target); @@ -886,6 +891,116 @@ impl Op for StartOp { } } +/// Represents a field parameter of the StepStateField. +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub enum StepStateField { + /// caller id field + CallID, + /// is_root field + IsRoot, + /// is_create field + IsCreate, + /// code_hash field + CodeHash, + /// program_counter field + ProgramCounter, + /// stack_pointer field + StackPointer, + /// gas_left field + GasLeft, + /// memory_word_size field + MemoryWordSize, + /// reversible_write_counter field + ReversibleWriteCounter, + /// log_id field + LogID, +} + +/// StepStateOp represents exec state store and load +#[derive(Clone, PartialEq, Eq)] +pub struct StepStateOp { + /// field of CallContext + pub field: StepStateField, + /// value of CallContext + pub value: Word, +} + +impl fmt::Debug for StepStateOp { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("StepStateOp { ")?; + f.write_fmt(format_args!( + "field: {:?}, value: {:?}", + self.field, self.value, + ))?; + f.write_str(" }") + } +} + +impl PartialOrd for StepStateOp { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for StepStateOp { + fn cmp(&self, other: &Self) -> Ordering { + self.field.cmp(&other.field) + } +} + +impl Op for StepStateOp { + fn into_enum(self) -> OpEnum { + OpEnum::StepState(self) + } + + fn reverse(&self) -> Self { + unreachable!("StepStateOp can't be reverted") + } +} + +impl StepStateOp { + /// Create a new instance of a `StepStateOp` from it's components. + pub const fn new(field: StepStateField, value: Word) -> StepStateOp { + StepStateOp { field, value } + } + + /// Returns the [`Target`] (operation type) of this operation. + pub const fn target(&self) -> Target { + Target::StepState + } + + /// Returns the [`Word`] read or written by this operation. + pub const fn value(&self) -> &Word { + &self.value + } +} + +/// Represent a Padding padding operation +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct PaddingOp {} + +impl PartialOrd for PaddingOp { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for PaddingOp { + fn cmp(&self, _other: &Self) -> Ordering { + Ordering::Equal + } +} + +impl Op for PaddingOp { + fn into_enum(self) -> OpEnum { + OpEnum::Padding(self) + } + + fn reverse(&self) -> Self { + unreachable!("Padding can't be reverted") + } +} + /// Represents TxReceipt read/write operation. #[derive(Clone, PartialEq, Eq)] pub struct TxReceiptOp { @@ -956,12 +1071,17 @@ pub enum OpEnum { TxLog(TxLogOp), /// Start Start(StartOp), + /// Padding + Padding(PaddingOp), + /// StepState + StepState(StepStateOp), } /// Operation is a Wrapper over a type that implements Op with a RWCounter. #[derive(Debug, Clone)] pub struct Operation { rwc: RWCounter, + rwc_inner_chunk: RWCounter, rw: RW, /// True when this Operation should be reverted or not when /// handle_reversion. @@ -994,9 +1114,10 @@ impl Ord for Operation { impl Operation { /// Create a new Operation from an `op` with a `rwc` - pub fn new(rwc: RWCounter, rw: RW, op: T) -> Self { + pub fn new(rwc: RWCounter, rwc_inner_chunk: RWCounter, rw: RW, op: T) -> Self { Self { rwc, + rwc_inner_chunk, rw, reversible: false, op, @@ -1004,9 +1125,10 @@ impl Operation { } /// Create a new reversible Operation from an `op` with a `rwc` - pub fn new_reversible(rwc: RWCounter, rw: RW, op: T) -> Self { + pub fn new_reversible(rwc: RWCounter, rwc_inner_chunk: RWCounter, rw: RW, op: T) -> Self { Self { rwc, + rwc_inner_chunk, rw, reversible: true, op, @@ -1018,6 +1140,11 @@ impl Operation { self.rwc } + /// Return this `Operation` `rwc_inner_chunk` + pub fn rwc_inner_chunk(&self) -> RWCounter { + self.rwc_inner_chunk + } + /// Return this `Operation` `rw` pub fn rw(&self) -> RW { self.rw @@ -1038,7 +1165,7 @@ impl Operation { &mut self.op } - // /// Matches over an `Operation` returning the [`Target`] of the iternal + // /// Matches over an `Operation` returning the [`Target`] of the internal // op /// it stores inside. // pub const fn target(&self) -> Target { // self.op.target() @@ -1101,11 +1228,13 @@ mod operation_tests { fn unchecked_op_transmutations_are_safe() { let stack_op = StackOp::new(1, StackAddress::from(1024), Word::from(0x40)); - let stack_op_as_operation = Operation::new(RWCounter(1), RW::WRITE, stack_op.clone()); + let stack_op_as_operation = + Operation::new(RWCounter(1), RWCounter(1), RW::WRITE, stack_op.clone()); let memory_op = MemoryOp::new(1, MemoryAddress(0x40), 0x40); - let memory_op_as_operation = Operation::new(RWCounter(1), RW::WRITE, memory_op.clone()); + let memory_op_as_operation = + Operation::new(RWCounter(1), RWCounter(1), RW::WRITE, memory_op.clone()); assert_eq!(stack_op, stack_op_as_operation.op); assert_eq!(memory_op, memory_op_as_operation.op) diff --git a/bus-mapping/src/operation/container.rs b/bus-mapping/src/operation/container.rs index 21d1918895..2ccac336cd 100644 --- a/bus-mapping/src/operation/container.rs +++ b/bus-mapping/src/operation/container.rs @@ -1,7 +1,7 @@ use super::{ - AccountOp, CallContextOp, MemoryOp, Op, OpEnum, Operation, RWCounter, StackOp, StartOp, - StorageOp, Target, TxAccessListAccountOp, TxAccessListAccountStorageOp, TxLogOp, TxReceiptOp, - TxRefundOp, RW, + AccountOp, CallContextOp, MemoryOp, Op, OpEnum, Operation, PaddingOp, RWCounter, StackOp, + StartOp, StepStateOp, StorageOp, Target, TxAccessListAccountOp, TxAccessListAccountStorageOp, + TxLogOp, TxReceiptOp, TxRefundOp, RW, }; use crate::exec_trace::OperationRef; use itertools::Itertools; @@ -16,7 +16,7 @@ use itertools::Itertools; /// [`ExecStep`](crate::circuit_input_builder::ExecStep). /// /// Finally, the container also provides the capability of retrieving all of the -/// `Stack`, `Memory` or `Storage` operations ordered according to the criterias +/// `Stack`, `Memory` or `Storage` operations ordered according to the criteria /// they have specified. /// That serves as a way to get an input with which is easy to work with in /// order to construct the State proof. @@ -44,6 +44,10 @@ pub struct OperationContainer { pub tx_log: Vec>, /// Operations of Start pub start: Vec>, + /// Operations of Padding + pub padding: Vec>, + /// Operations of StepState + pub step_state: Vec>, } impl Default for OperationContainer { @@ -68,6 +72,8 @@ impl OperationContainer { tx_receipt: Vec::new(), tx_log: Vec::new(), start: Vec::new(), + padding: Vec::new(), + step_state: Vec::new(), } } @@ -77,9 +83,10 @@ impl OperationContainer { /// vector. pub fn insert(&mut self, op: Operation) -> OperationRef { let rwc = op.rwc(); + let rwc_inner_chunk = op.rwc_inner_chunk(); let rw = op.rw(); let reversible = op.reversible(); - self.insert_op_enum(rwc, rw, reversible, op.op.into_enum()) + self.insert_op_enum(rwc, rwc_inner_chunk, rw, reversible, op.op.into_enum()) } /// Inserts an [`OpEnum`] into the container returning a lightweight @@ -89,32 +96,35 @@ impl OperationContainer { pub fn insert_op_enum( &mut self, rwc: RWCounter, + rwc_inner_chunk: RWCounter, rw: RW, reversible: bool, op_enum: OpEnum, ) -> OperationRef { match op_enum { OpEnum::Memory(op) => { - self.memory.push(Operation::new(rwc, rw, op)); + self.memory + .push(Operation::new(rwc, rwc_inner_chunk, rw, op)); OperationRef::from((Target::Memory, self.memory.len() - 1)) } OpEnum::Stack(op) => { - self.stack.push(Operation::new(rwc, rw, op)); + self.stack + .push(Operation::new(rwc, rwc_inner_chunk, rw, op)); OperationRef::from((Target::Stack, self.stack.len() - 1)) } OpEnum::Storage(op) => { self.storage.push(if reversible { - Operation::new_reversible(rwc, rw, op) + Operation::new_reversible(rwc, rwc_inner_chunk, rw, op) } else { - Operation::new(rwc, rw, op) + Operation::new(rwc, rwc_inner_chunk, rw, op) }); OperationRef::from((Target::Storage, self.storage.len() - 1)) } OpEnum::TxAccessListAccount(op) => { self.tx_access_list_account.push(if reversible { - Operation::new_reversible(rwc, rw, op) + Operation::new_reversible(rwc, rwc_inner_chunk, rw, op) } else { - Operation::new(rwc, rw, op) + Operation::new(rwc, rwc_inner_chunk, rw, op) }); OperationRef::from(( Target::TxAccessListAccount, @@ -123,9 +133,9 @@ impl OperationContainer { } OpEnum::TxAccessListAccountStorage(op) => { self.tx_access_list_account_storage.push(if reversible { - Operation::new_reversible(rwc, rw, op) + Operation::new_reversible(rwc, rwc_inner_chunk, rw, op) } else { - Operation::new(rwc, rw, op) + Operation::new(rwc, rwc_inner_chunk, rw, op) }); OperationRef::from(( Target::TxAccessListAccountStorage, @@ -134,36 +144,50 @@ impl OperationContainer { } OpEnum::TxRefund(op) => { self.tx_refund.push(if reversible { - Operation::new_reversible(rwc, rw, op) + Operation::new_reversible(rwc, rwc_inner_chunk, rw, op) } else { - Operation::new(rwc, rw, op) + Operation::new(rwc, rwc_inner_chunk, rw, op) }); OperationRef::from((Target::TxRefund, self.tx_refund.len() - 1)) } OpEnum::Account(op) => { self.account.push(if reversible { - Operation::new_reversible(rwc, rw, op) + Operation::new_reversible(rwc, rwc_inner_chunk, rw, op) } else { - Operation::new(rwc, rw, op) + Operation::new(rwc, rwc_inner_chunk, rw, op) }); OperationRef::from((Target::Account, self.account.len() - 1)) } OpEnum::CallContext(op) => { - self.call_context.push(Operation::new(rwc, rw, op)); + self.call_context + .push(Operation::new(rwc, rwc_inner_chunk, rw, op)); OperationRef::from((Target::CallContext, self.call_context.len() - 1)) } OpEnum::TxReceipt(op) => { - self.tx_receipt.push(Operation::new(rwc, rw, op)); + self.tx_receipt + .push(Operation::new(rwc, rwc_inner_chunk, rw, op)); OperationRef::from((Target::TxReceipt, self.tx_receipt.len() - 1)) } OpEnum::TxLog(op) => { - self.tx_log.push(Operation::new(rwc, rw, op)); + self.tx_log + .push(Operation::new(rwc, rwc_inner_chunk, rw, op)); OperationRef::from((Target::TxLog, self.tx_log.len() - 1)) } OpEnum::Start(op) => { - self.start.push(Operation::new(rwc, rw, op)); + self.start + .push(Operation::new(rwc, rwc_inner_chunk, rw, op)); OperationRef::from((Target::Start, self.start.len() - 1)) } + OpEnum::Padding(op) => { + self.padding + .push(Operation::new(rwc, rwc_inner_chunk, rw, op)); + OperationRef::from((Target::Padding, self.padding.len() - 1)) + } + OpEnum::StepState(op) => { + self.step_state + .push(Operation::new(rwc, rwc_inner_chunk, rw, op)); + OperationRef::from((Target::StepState, self.step_state.len() - 1)) + } } } @@ -198,20 +222,25 @@ mod container_test { #[test] fn operation_container_test() { + // global counter same as intra_chunk_counter in single chunk let mut global_counter = RWCounter::default(); + let mut intra_chunk_counter = RWCounter::default(); let mut operation_container = OperationContainer::default(); let stack_operation = Operation::new( global_counter.inc_pre(), + intra_chunk_counter.inc_pre(), RW::WRITE, StackOp::new(1, StackAddress(1023), Word::from(0x100)), ); let memory_operation = Operation::new( global_counter.inc_pre(), + intra_chunk_counter.inc_pre(), RW::WRITE, MemoryOp::new(1, MemoryAddress::from(1), 1), ); let storage_operation = Operation::new( global_counter.inc_pre(), + intra_chunk_counter.inc_pre(), RW::WRITE, StorageOp::new( Address::zero(), diff --git a/bus-mapping/src/precompile.rs b/bus-mapping/src/precompile.rs index 2792fa4d5b..3ccc940964 100644 --- a/bus-mapping/src/precompile.rs +++ b/bus-mapping/src/precompile.rs @@ -2,7 +2,7 @@ use eth_types::{ evm_types::{GasCost, OpcodeId}, - Address, Bytecode, Word, + Address, Bytecode, ToBigEndian, Word, }; #[cfg(not(target_arch = "wasm32"))] use revm_precompile::{Precompile, PrecompileError, Precompiles}; @@ -36,8 +36,9 @@ pub(crate) fn execute_precompiled( #[cfg(not(target_arch = "wasm32"))] { - let Some(Precompile::Standard(precompile_fn)) = Precompiles::berlin() - .get(address.as_fixed_bytes()) else { + let Some(Precompile::Standard(precompile_fn)) = + Precompiles::berlin().get(address.as_fixed_bytes()) + else { panic!("calling non-exist precompiled contract address") }; let (return_data, gas_cost, is_oog, is_ok) = match precompile_fn(input, gas) { @@ -62,7 +63,7 @@ pub(crate) fn execute_precompiled( #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum PrecompileCalls { /// Elliptic Curve Recovery - ECRecover = 0x01, + Ecrecover = 0x01, /// SHA2-256 hash function Sha256 = 0x02, /// Ripemd-160 hash function @@ -81,6 +82,12 @@ pub enum PrecompileCalls { Blake2F = 0x09, } +impl Default for PrecompileCalls { + fn default() -> Self { + Self::Ecrecover + } +} + impl From for Address { fn from(value: PrecompileCalls) -> Self { let mut addr = [0u8; 20]; @@ -104,7 +111,7 @@ impl From for usize { impl From for PrecompileCalls { fn from(value: u8) -> Self { match value { - 0x01 => Self::ECRecover, + 0x01 => Self::Ecrecover, 0x02 => Self::Sha256, 0x03 => Self::Ripemd160, 0x04 => Self::Identity, @@ -122,7 +129,7 @@ impl PrecompileCalls { /// Get the base gas cost for the precompile call. pub fn base_gas_cost(&self) -> u64 { match self { - Self::ECRecover => GasCost::PRECOMPILE_ECRECOVER_BASE, + Self::Ecrecover => GasCost::PRECOMPILE_ECRECOVER_BASE, Self::Sha256 => GasCost::PRECOMPILE_SHA256_BASE, Self::Ripemd160 => GasCost::PRECOMPILE_RIPEMD160_BASE, Self::Identity => GasCost::PRECOMPILE_IDENTITY_BASE, @@ -142,7 +149,7 @@ impl PrecompileCalls { /// Maximum length of input bytes considered for the precompile call. pub fn input_len(&self) -> Option { match self { - Self::ECRecover | Self::Bn128Add => Some(128), + Self::Ecrecover | Self::Bn128Add => Some(128), Self::Bn128Mul => Some(96), _ => None, } @@ -220,3 +227,82 @@ impl PrecompileCallArgs { code } } + +/// Auxiliary data for Ecrecover +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct EcrecoverAuxData { + /// Keccak hash of the message being signed. + pub msg_hash: Word, + /// v-component of signature. + pub sig_v: Word, + /// r-component of signature. + pub sig_r: Word, + /// s-component of signature. + pub sig_s: Word, + /// Address that was recovered. + pub recovered_addr: Address, + /// Input bytes to the ecrecover call. + pub input_bytes: Vec, + /// Output bytes from the ecrecover call. + pub output_bytes: Vec, + /// Bytes returned to the caller from the ecrecover call. + pub return_bytes: Vec, +} + +impl EcrecoverAuxData { + /// Create a new instance of ecrecover auxiliary data. + pub fn new(input: &[u8], output: &[u8], return_bytes: &[u8]) -> Self { + let mut resized_input = input.to_vec(); + resized_input.resize(128, 0u8); + let mut resized_output = output.to_vec(); + resized_output.resize(32, 0u8); + + // assert that recovered address is 20 bytes. + assert!(resized_output[0x00..0x0c].iter().all(|&b| b == 0)); + let recovered_addr = Address::from_slice(&resized_output[0x0c..0x20]); + + Self { + msg_hash: Word::from_big_endian(&resized_input[0x00..0x20]), + sig_v: Word::from_big_endian(&resized_input[0x20..0x40]), + sig_r: Word::from_big_endian(&resized_input[0x40..0x60]), + sig_s: Word::from_big_endian(&resized_input[0x60..0x80]), + recovered_addr, + input_bytes: input.to_vec(), + output_bytes: output.to_vec(), + return_bytes: return_bytes.to_vec(), + } + } + + /// Sanity check and returns recovery ID. + pub fn recovery_id(&self) -> Option { + let sig_v_bytes = self.sig_v.to_be_bytes(); + let sig_v = sig_v_bytes[31]; + if sig_v_bytes.iter().take(31).all(|&b| b == 0) && (sig_v == 27 || sig_v == 28) { + Some(sig_v - 27) + } else { + None + } + } +} + +/// Auxiliary data attached to an internal state for precompile verification. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum PrecompileAuxData { + /// Base precompile (used for Identity, SHA256, RIPEMD-160 and BLAKE2F). + Base { + /// input bytes to the identity call. + input_bytes: Vec, + /// output bytes from the identity call. + output_bytes: Vec, + /// bytes returned back to the caller from the identity call. + return_bytes: Vec, + }, + /// Ecrecover. + Ecrecover(EcrecoverAuxData), +} + +impl Default for PrecompileAuxData { + fn default() -> Self { + Self::Ecrecover(EcrecoverAuxData::default()) + } +} diff --git a/circuit-benchmarks/src/copy_circuit.rs b/circuit-benchmarks/src/copy_circuit.rs index d77155f8bc..8638b1a1e1 100644 --- a/circuit-benchmarks/src/copy_circuit.rs +++ b/circuit-benchmarks/src/copy_circuit.rs @@ -26,7 +26,7 @@ mod tests { use std::env::var; use zkevm_circuits::{ copy_circuit::TestCopyCircuit, - evm_circuit::witness::{block_convert, Block}, + evm_circuit::witness::{block_convert, chunk_convert, Block, Chunk}, util::SubCircuit, }; @@ -51,10 +51,11 @@ mod tests { ]); // Create the circuit - let mut block = generate_full_events_block(degree); + let (mut block, chunk) = generate_full_events_block(degree); block.circuits_params.max_rws = 10_000; block.circuits_params.max_copy_rows = 10_000; - let circuit = TestCopyCircuit::::new_from_block(&block); + let circuit = TestCopyCircuit::::new_from_block(&block, &chunk); + // Bench setup generation let setup_message = format!("{} {} with degree = {}", BENCHMARK_ID, setup_prfx, degree); let start1 = start_timer!(|| setup_message); @@ -109,7 +110,7 @@ mod tests { } /// generate enough copy events to fillup copy circuit - fn generate_full_events_block(degree: u32) -> Block { + fn generate_full_events_block(degree: u32) -> (Block, Chunk) { // A empiric value 55 here to let the code generate enough copy event without // exceed the max_rws limit. let copy_event_num = (1 << degree) / 55; @@ -144,19 +145,19 @@ mod tests { ) .unwrap(); let block: GethData = test_ctx.into(); - let mut builder = BlockData::new_from_geth_data_with_params( + let builder = BlockData::new_from_geth_data_with_params( block.clone(), FixedCParams { max_rws: 1 << (degree - 1), ..Default::default() }, ) - .new_circuit_input_builder(); - builder - .handle_block(&block.eth_block, &block.geth_traces) - .unwrap(); + .new_circuit_input_builder() + .handle_block(&block.eth_block, &block.geth_traces) + .unwrap(); let block = block_convert(&builder).unwrap(); + let chunk = chunk_convert(&block, &builder).unwrap().remove(0); assert_eq!(block.copy_events.len(), copy_event_num); - block + (block, chunk) } } diff --git a/circuit-benchmarks/src/evm_circuit.rs b/circuit-benchmarks/src/evm_circuit.rs index 7ceeb80f8f..10af1a3e10 100644 --- a/circuit-benchmarks/src/evm_circuit.rs +++ b/circuit-benchmarks/src/evm_circuit.rs @@ -24,7 +24,10 @@ mod evm_circ_benches { use rand::SeedableRng; use rand_xorshift::XorShiftRng; use std::env::var; - use zkevm_circuits::evm_circuit::{witness::block_convert, TestEvmCircuit}; + use zkevm_circuits::evm_circuit::{ + witness::{block_convert, chunk_convert}, + TestEvmCircuit, + }; #[cfg_attr(not(feature = "benches"), ignore)] #[test] @@ -44,17 +47,16 @@ mod evm_circ_benches { .unwrap() .into(); - let mut builder = + let builder = BlockData::new_from_geth_data_with_params(empty_data.clone(), FixedCParams::default()) - .new_circuit_input_builder(); - - builder - .handle_block(&empty_data.eth_block, &empty_data.geth_traces) - .unwrap(); + .new_circuit_input_builder() + .handle_block(&empty_data.eth_block, &empty_data.geth_traces) + .unwrap(); let block = block_convert(&builder).unwrap(); + let chunk = chunk_convert(&block, &builder).unwrap().remove(0); - let circuit = TestEvmCircuit::::new(block); + let circuit = TestEvmCircuit::::new(block, chunk); let mut rng = XorShiftRng::from_seed([ 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc, 0xe5, diff --git a/circuit-benchmarks/src/exp_circuit.rs b/circuit-benchmarks/src/exp_circuit.rs index 8b3d6830a3..11d91b69dc 100644 --- a/circuit-benchmarks/src/exp_circuit.rs +++ b/circuit-benchmarks/src/exp_circuit.rs @@ -26,7 +26,7 @@ mod tests { use rand_xorshift::XorShiftRng; use std::env::var; use zkevm_circuits::{ - evm_circuit::witness::{block_convert, Block}, + evm_circuit::witness::{block_convert, chunk_convert, Block, Chunk}, exp_circuit::TestExpCircuit, }; @@ -49,11 +49,8 @@ mod tests { let base = Word::from(132); let exponent = Word::from(27); - let block = generate_full_events_block(degree, base, exponent); - let circuit = TestExpCircuit::::new( - block.exp_events.clone(), - block.circuits_params.max_exp_steps, - ); + let (block, chunk) = generate_full_events_block(degree, base, exponent); + let circuit = TestExpCircuit::::new(block.exp_events, chunk.fixed_param.max_exp_steps); // Initialize the polynomial commitment parameters let mut rng = XorShiftRng::from_seed([ @@ -121,7 +118,11 @@ mod tests { end_timer!(start3); } - fn generate_full_events_block(degree: u32, base: Word, exponent: Word) -> Block { + fn generate_full_events_block( + degree: u32, + base: Word, + exponent: Word, + ) -> (Block, Chunk) { let code = bytecode! { PUSH32(exponent) PUSH32(base) @@ -137,17 +138,18 @@ mod tests { ) .unwrap(); let block: GethData = test_ctx.into(); - let mut builder = BlockData::new_from_geth_data_with_params( + let builder = BlockData::new_from_geth_data_with_params( block.clone(), FixedCParams { max_rws: 1 << (degree - 1), ..Default::default() }, ) - .new_circuit_input_builder(); - builder - .handle_block(&block.eth_block, &block.geth_traces) - .unwrap(); - block_convert(&builder).unwrap() + .new_circuit_input_builder() + .handle_block(&block.eth_block, &block.geth_traces) + .unwrap(); + let block = block_convert(&builder).unwrap(); + let chunk = chunk_convert(&block, &builder).unwrap().remove(0); + (block, chunk) } } diff --git a/circuit-benchmarks/src/state_circuit.rs b/circuit-benchmarks/src/state_circuit.rs index 2235930f7d..251a4089ad 100644 --- a/circuit-benchmarks/src/state_circuit.rs +++ b/circuit-benchmarks/src/state_circuit.rs @@ -21,9 +21,7 @@ mod tests { use rand::SeedableRng; use rand_xorshift::XorShiftRng; use std::env::var; - use zkevm_circuits::{ - evm_circuit::witness::RwMap, state_circuit::StateCircuit, util::SubCircuit, - }; + use zkevm_circuits::{state_circuit::StateCircuit, util::SubCircuit, witness::Chunk}; #[cfg_attr(not(feature = "benches"), ignore)] #[test] @@ -39,7 +37,7 @@ mod tests { .parse() .expect("Cannot parse DEGREE env var as u32"); - let empty_circuit = StateCircuit::::new(RwMap::default(), 1 << 16); + let empty_circuit = StateCircuit::::new(&Chunk::default()); // Initialize the polynomial commitment parameters let mut rng = XorShiftRng::from_seed([ diff --git a/circuit-benchmarks/src/super_circuit.rs b/circuit-benchmarks/src/super_circuit.rs index 450a912d94..e800ec5806 100644 --- a/circuit-benchmarks/src/super_circuit.rs +++ b/circuit-benchmarks/src/super_circuit.rs @@ -80,6 +80,7 @@ mod tests { block.sign(&wallets); let circuits_params = FixedCParams { + total_chunks: 1, max_txs: 1, max_withdrawals: 1, max_calldata: 32, @@ -89,9 +90,11 @@ mod tests { max_bytecode: 512, max_evm_rows: 0, max_keccak_rows: 0, + max_vertical_circuit_rows: 0, }; - let (_, circuit, instance, _) = + let (_, mut circuits, mut instances, _) = SuperCircuit::build(block, circuits_params, Fr::from(0x100)).unwrap(); + let (circuit, instance) = (circuits.remove(0), instances.remove(0)); let instance_refs: Vec<&[Fr]> = instance.iter().map(|v| &v[..]).collect(); // Bench setup generation diff --git a/eth-types/src/bytecode.rs b/eth-types/src/bytecode.rs index 627ff10eae..09160e274e 100644 --- a/eth-types/src/bytecode.rs +++ b/eth-types/src/bytecode.rs @@ -1,7 +1,6 @@ //! EVM byte code generator use crate::{evm_types::OpcodeId, keccak256, Bytes, Hash, ToBigEndian, ToWord, Word}; -use std::{collections::HashMap, iter, str::FromStr}; - +use std::{collections::HashMap, fmt::Display, iter, str::FromStr}; /// Error type for Bytecode related failures #[derive(Debug)] pub enum Error { @@ -254,12 +253,13 @@ impl FromStr for OpcodeWithData { } } -impl ToString for OpcodeWithData { - fn to_string(&self) -> String { - match self { +impl Display for OpcodeWithData { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let str = match self { OpcodeWithData::Opcode(opcode) => format!("{:?}", opcode), OpcodeWithData::PushWithData(n, word) => format!("PUSH{}({})", n, word), - } + }; + f.write_str(&str) } } @@ -576,6 +576,6 @@ mod tests { POP STOP }; - assert_eq!(Bytecode::try_from(code.code()).unwrap(), code); + assert_eq!(Bytecode::from(code.code()), code); } } diff --git a/eth-types/src/evm_types.rs b/eth-types/src/evm_types.rs index d9fa5ec40b..39adaa4a17 100644 --- a/eth-types/src/evm_types.rs +++ b/eth-types/src/evm_types.rs @@ -34,8 +34,7 @@ mod gas_create { // [gasCreate2Eip3860](https://github.com/ethereum/go-ethereum/blob/eb83e7c54021573eaceb14236af3a7a8c64f6027/core/vm/gas_table.go#L321) // (similar for CREATE). // 1. size <= 49152 (MaxInitCodeSize) - // 2. gasCost = memoryGasCost + (2 + 6) * ((size + 31) / 32) should not - // overflow for Uint64. + // 2. gasCost = memoryGasCost + (2 + 6) * ((size + 31) / 32) should not overflow for Uint64. // No need to constrain the second condition, since the maximum gas cost // cannot overflow for Uint64 (36028809887100925 calculated by // `memorySize = 0x1FFFFFFFE0` and `size = 49152`) if the first condition is diff --git a/eth-types/src/geth_types.rs b/eth-types/src/geth_types.rs index b606d8547b..c95475a5bc 100644 --- a/eth-types/src/geth_types.rs +++ b/eth-types/src/geth_types.rs @@ -5,10 +5,13 @@ use crate::{ keccak256, sign_types::{biguint_to_32bytes_le, ct_option_ok_or, recover_pk, SignData, SECP256K1_Q}, AccessList, Address, Block, Bytecode, Bytes, Error, GethExecTrace, Hash, ToBigEndian, - ToLittleEndian, ToWord, Word, U64, + ToLittleEndian, ToWord, Word, H256, U64, }; use ethers_core::{ - types::{transaction::response, NameOrAddress, TransactionRequest}, + types::{ + transaction::{eip2718::TypedTransaction, response}, + Eip1559TransactionRequest, Eip2930TransactionRequest, NameOrAddress, TransactionRequest, + }, utils::get_contract_address, }; use ethers_signers::{LocalWallet, Signer}; @@ -18,6 +21,117 @@ use num_bigint::BigUint; use serde::{Serialize, Serializer}; use serde_with::serde_as; use std::collections::HashMap; +use strum_macros::EnumIter; + +/// Tx type +#[derive(Default, Debug, Copy, Clone, EnumIter, Serialize, PartialEq, Eq)] +pub enum TxType { + /// EIP 155 tx + #[default] + Eip155 = 0, + /// Pre EIP 155 tx + PreEip155, + /// EIP 1559 tx + Eip1559, + /// EIP 2930 tx + Eip2930, +} + +impl From for usize { + fn from(value: TxType) -> Self { + value as usize + } +} + +impl From for u64 { + fn from(value: TxType) -> Self { + value as u64 + } +} + +impl TxType { + /// If this type is PreEip155 + pub fn is_pre_eip155(&self) -> bool { + matches!(*self, TxType::PreEip155) + } + + /// If this type is EIP155 or not + pub fn is_eip155(&self) -> bool { + matches!(*self, TxType::Eip155) + } + + /// If this type is Eip1559 or not + pub fn is_eip1559(&self) -> bool { + matches!(*self, TxType::Eip1559) + } + + /// If this type is Eip2930 or not + pub fn is_eip2930(&self) -> bool { + matches!(*self, TxType::Eip2930) + } + + /// Get the type of transaction + pub fn get_tx_type(tx: &crate::Transaction) -> Self { + match tx.transaction_type { + Some(x) if x == U64::from(1) => Self::Eip2930, + Some(x) if x == U64::from(2) => Self::Eip1559, + _ => match tx.v.as_u64() { + 0 | 1 | 27 | 28 => Self::PreEip155, + _ => Self::Eip155, + }, + } + } + + /// Return the recovery id of signature for recovering the signing pk + pub fn get_recovery_id(&self, v: u64) -> u8 { + let recovery_id = match *self { + TxType::Eip155 => (v + 1) % 2, + TxType::PreEip155 => { + assert!(v == 0x1b || v == 0x1c, "v: {v}"); + v - 27 + } + TxType::Eip1559 => { + assert!(v <= 1); + v + } + TxType::Eip2930 => { + assert!(v <= 1); + v + } + }; + + recovery_id as u8 + } +} + +/// Get the RLP bytes for signing +pub fn get_rlp_unsigned(tx: &crate::Transaction) -> Vec { + let sig_v = tx.v; + match TxType::get_tx_type(tx) { + TxType::Eip155 => { + let mut tx: TransactionRequest = tx.into(); + tx.chain_id = Some(tx.chain_id.unwrap_or_else(|| { + let recv_v = TxType::Eip155.get_recovery_id(sig_v.as_u64()) as u64; + (sig_v - recv_v - 35) / 2 + })); + tx.rlp().to_vec() + } + TxType::PreEip155 => { + let tx: TransactionRequest = tx.into(); + tx.rlp_unsigned().to_vec() + } + TxType::Eip1559 => { + let tx: Eip1559TransactionRequest = tx.into(); + let typed_tx: TypedTransaction = tx.into(); + typed_tx.rlp().to_vec() + } + TxType::Eip2930 => { + let tx: Eip2930TransactionRequest = tx.into(); + let typed_tx: TypedTransaction = tx.into(); + typed_tx.rlp().to_vec() + } + } +} /// Definition of all of the data related to an account. #[serde_as] @@ -156,6 +270,8 @@ pub struct Withdrawal { /// Definition of all of the constants related to an Ethereum transaction. #[derive(Debug, Default, Clone, Serialize)] pub struct Transaction { + /// Tx type + pub tx_type: TxType, /// Sender address pub from: Address, /// Recipient address (None for contract creation) @@ -167,14 +283,14 @@ pub struct Transaction { /// Gas Limit / Supplied gas /// U64 type is required to serialize into proper hex with 0x prefix pub gas_limit: U64, - /// Transfered value + /// Transferred value pub value: Word, /// Gas Price pub gas_price: Word, /// Gas fee cap - pub gas_fee_cap: Word, + pub gas_fee_cap: Option, /// Gas tip cap - pub gas_tip_cap: Word, + pub gas_tip_cap: Option, /// The compiled code of a contract OR the first 4 bytes of the hash of the /// invoked method signature and encoded parameters. For details see /// Ethereum Contract ABI @@ -188,6 +304,14 @@ pub struct Transaction { pub r: Word, /// "s" value of the transaction signature pub s: Word, + + /// RLP bytes + pub rlp_bytes: Vec, + /// RLP unsigned bytes + pub rlp_unsigned_bytes: Vec, + + /// Transaction hash + pub hash: H256, } impl From<&Transaction> for crate::Transaction { @@ -199,8 +323,8 @@ impl From<&Transaction> for crate::Transaction { gas: tx.gas_limit.to_word(), value: tx.value, gas_price: Some(tx.gas_price), - max_priority_fee_per_gas: Some(tx.gas_tip_cap), - max_fee_per_gas: Some(tx.gas_fee_cap), + max_priority_fee_per_gas: tx.gas_tip_cap, + max_fee_per_gas: tx.gas_fee_cap, input: tx.call_data.clone(), access_list: tx.access_list.clone(), v: tx.v.into(), @@ -214,19 +338,23 @@ impl From<&Transaction> for crate::Transaction { impl From<&crate::Transaction> for Transaction { fn from(tx: &crate::Transaction) -> Transaction { Transaction { + tx_type: TxType::get_tx_type(tx), from: tx.from, to: tx.to, nonce: tx.nonce.as_u64().into(), gas_limit: tx.gas.as_u64().into(), value: tx.value, gas_price: tx.gas_price.unwrap_or_default(), - gas_tip_cap: tx.max_priority_fee_per_gas.unwrap_or_default(), - gas_fee_cap: tx.max_fee_per_gas.unwrap_or_default(), + gas_tip_cap: tx.max_priority_fee_per_gas, + gas_fee_cap: tx.max_fee_per_gas, call_data: tx.input.clone(), access_list: tx.access_list.clone(), v: tx.v.as_u64(), r: tx.r, s: tx.s, + rlp_bytes: tx.rlp().to_vec(), + rlp_unsigned_bytes: get_rlp_unsigned(tx), + hash: tx.hash, } } } @@ -247,6 +375,25 @@ impl From<&Transaction> for TransactionRequest { } impl Transaction { + /// Create a dummy Transaction with zero values + pub fn dummy() -> Self { + Self { + from: Address::zero(), + to: Some(Address::zero()), + nonce: U64::zero(), + gas_limit: U64::zero(), + value: Word::zero(), + gas_price: Word::zero(), + gas_tip_cap: Some(Word::zero()), + gas_fee_cap: Some(Word::zero()), + call_data: Bytes::new(), + access_list: None, + v: 0, + r: Word::zero(), + s: Word::zero(), + ..Default::default() + } + } /// Return the SignData associated with this Transaction. pub fn sign_data(&self, chain_id: u64) -> Result { let sig_r_le = self.r.to_le_bytes(); @@ -277,8 +424,9 @@ impl Transaction { libsecp256k1::Error::InvalidMessage, )?; Ok(SignData { - signature: (sig_r, sig_s), + signature: (sig_r, sig_s, v), pk, + msg, msg_hash, }) } @@ -336,11 +484,14 @@ impl Transaction { s: self.s, v: U64::from(self.v), block_number: Some(block_number), + transaction_type: Some(U64::from(self.tx_type as u64)), + max_priority_fee_per_gas: self.gas_tip_cap, + max_fee_per_gas: self.gas_fee_cap, chain_id: Some(chain_id), ..response::Transaction::default() } } - /// Convinient method for gas limit + /// Convenient method for gas limit pub fn gas(&self) -> u64 { self.gas_limit.as_u64() } diff --git a/eth-types/src/keccak.rs b/eth-types/src/keccak.rs index 3bef09e94a..b697a5743c 100644 --- a/eth-types/src/keccak.rs +++ b/eth-types/src/keccak.rs @@ -253,7 +253,7 @@ impl Sponge { } } -/// Convinient method to get 32 bytes digest +/// Convenient method to get 32 bytes digest pub fn keccak256(msg: &[u8]) -> [u8; 32] { let mut keccak = Keccak::default(); keccak.update(msg); diff --git a/eth-types/src/lib.rs b/eth-types/src/lib.rs index afa4569187..9bebdc63d2 100644 --- a/eth-types/src/lib.rs +++ b/eth-types/src/lib.rs @@ -8,7 +8,11 @@ #![deny(missing_docs)] //#![deny(unsafe_code)] Allowed now until we find a // better way to handle downcasting from Operation into it's variants. -#![allow(clippy::upper_case_acronyms)] // Too pedantic + +// Too pedantic +#![allow(clippy::upper_case_acronyms)] +// Clippy is buggy on this one. Remove after https://github.com/rust-lang/rust-clippy/issues/12101 is resolved. +#![allow(clippy::useless_vec)] #[macro_use] pub mod macros; @@ -37,7 +41,10 @@ use ethers_core::types; pub use ethers_core::{ abi::ethereum_types::{BigEndianHash, U512}, types::{ - transaction::{eip2930::AccessList, response::Transaction}, + transaction::{ + eip2930::{AccessList, AccessListItem}, + response::Transaction, + }, Address, Block, Bytes, Signature, H160, H256, H64, U256, U64, }, }; @@ -472,14 +479,14 @@ impl<'de> Deserialize<'de> for GethExecStep { } /// Helper type built to deal with the weird `result` field added between -/// `GethExecutionTrace`s in `debug_traceBlockByHash` and +/// [`GethExecTrace`]s in `debug_traceBlockByHash` and /// `debug_traceBlockByNumber` Geth JSON-RPC calls. #[derive(Clone, Debug, Eq, PartialEq, Deserialize)] #[doc(hidden)] pub struct ResultGethExecTraces(pub Vec); /// Helper type built to deal with the weird `result` field added between -/// `GethExecutionTrace`s in `debug_traceBlockByHash` and +/// [`GethExecTrace`]s in `debug_traceBlockByHash` and /// `debug_traceBlockByNumber` Geth JSON-RPC calls. #[derive(Clone, Debug, Eq, PartialEq, Deserialize)] #[doc(hidden)] diff --git a/eth-types/src/sign_types.rs b/eth-types/src/sign_types.rs index c93245af29..c3104903fd 100644 --- a/eth-types/src/sign_types.rs +++ b/eth-types/src/sign_types.rs @@ -1,13 +1,15 @@ //! secp256k1 signature types and helper functions. use crate::{ToBigEndian, Word}; +use ethers_core::{ + types::{Address, Bytes}, + utils::keccak256, +}; use halo2_proofs::{ arithmetic::{CurveAffine, Field}, halo2curves::{ - group::{ - ff::{FromUniformBytes, PrimeField}, - Curve, - }, + ff::FromUniformBytes, + group::{ff::PrimeField, prime::PrimeCurveAffine, Curve}, secp256k1::{self, Secp256k1Affine}, Coordinates, }, @@ -21,7 +23,7 @@ pub fn sign( randomness: secp256k1::Fq, sk: secp256k1::Fq, msg_hash: secp256k1::Fq, -) -> (secp256k1::Fq, secp256k1::Fq) { +) -> (secp256k1::Fq, secp256k1::Fq, u8) { let randomness_inv = Option::::from(randomness.invert()).expect("cannot invert randomness"); let generator = Secp256k1Affine::generator(); @@ -38,34 +40,51 @@ pub fn sign( let sig_r = secp256k1::Fq::from_uniform_bytes(&x_bytes); // get x coordinate (E::Base) on E::Scalar let sig_s = randomness_inv * (msg_hash + sig_r * sk); - (sig_r, sig_s) + let sig_v = sig_point.to_affine().y.is_odd().unwrap_u8(); + (sig_r, sig_s, sig_v) } /// Signature data required by the SignVerify Chip as input to verify a /// signature. #[derive(Clone, Debug)] pub struct SignData { - /// Secp256k1 signature point - pub signature: (secp256k1::Fq, secp256k1::Fq), + /// Secp256k1 signature point (r, s, v) + /// v must be 0 or 1 + pub signature: (secp256k1::Fq, secp256k1::Fq, u8), /// Secp256k1 public key pub pk: Secp256k1Affine, + /// Message being hashed before signing. + pub msg: Bytes, /// Hash of the message that is being signed pub msg_hash: secp256k1::Fq, } +impl SignData { + /// Recover address of the signature + pub fn get_addr(&self) -> Address { + if self.pk == Secp256k1Affine::identity() { + return Address::zero(); + } + let pk_hash = keccak256(pk_bytes_swap_endianness(&pk_bytes_le(&self.pk))); + Address::from_slice(&pk_hash[12..]) + } +} + lazy_static! { static ref SIGN_DATA_DEFAULT: SignData = { let generator = Secp256k1Affine::generator(); let sk = secp256k1::Fq::ONE; let pk = generator * sk; let pk = pk.to_affine(); + let msg = Bytes::new(); let msg_hash = secp256k1::Fq::ONE; let randomness = secp256k1::Fq::ONE; - let (sig_r, sig_s) = sign(randomness, sk, msg_hash); + let (sig_r, sig_s, sig_v) = sign(randomness, sk, msg_hash); SignData { - signature: (sig_r, sig_s), + signature: (sig_r, sig_s, sig_v), pk, + msg, msg_hash, } }; @@ -121,7 +140,7 @@ pub fn recover_pk( } lazy_static! { - /// Secp256k1 Curve Scalar. Referece: Section 2.4.1 (parameter `n`) in "SEC 2: Recommended + /// Secp256k1 Curve Scalar. Reference: Section 2.4.1 (parameter `n`) in "SEC 2: Recommended /// Elliptic Curve Domain Parameters" document at http://www.secg.org/sec2-v2.pdf pub static ref SECP256K1_Q: BigUint = BigUint::from_bytes_le(&(secp256k1::Fq::ZERO - secp256k1::Fq::ONE).to_repr()) + 1u64; } @@ -135,9 +154,7 @@ pub fn ct_option_ok_or(v: CtOption, err: E) -> Result { /// Return a copy of the serialized public key with swapped Endianness. pub fn pk_bytes_swap_endianness(pk: &[T]) -> [T; 64] { assert_eq!(pk.len(), 64); - let mut pk_swap = <&[T; 64]>::try_from(pk) - .map(|r| r.clone()) - .expect("pk.len() != 64"); + let mut pk_swap = <&[T; 64]>::try_from(pk).cloned().expect("pk.len() != 64"); pk_swap[..32].reverse(); pk_swap[32..].reverse(); pk_swap diff --git a/external-tracer/src/lib.rs b/external-tracer/src/lib.rs index d144cc515e..7bb5c27db5 100644 --- a/external-tracer/src/lib.rs +++ b/external-tracer/src/lib.rs @@ -5,7 +5,7 @@ use eth_types::{ Address, Error, GethExecTrace, Word, }; use serde::Serialize; -use std::collections::HashMap; +use std::collections::BTreeMap; /// Configuration structure for `geth_utils::trace` #[derive(Debug, Default, Clone, Serialize)] @@ -18,7 +18,7 @@ pub struct TraceConfig { /// block constants pub block_constants: BlockConstants, /// accounts - pub accounts: HashMap, + pub accounts: BTreeMap, /// transaction pub transactions: Vec, /// withdrawal @@ -78,7 +78,8 @@ pub fn trace(config: &TraceConfig) -> Result, Error> { let allowed_cases = error.starts_with("nonce too low") || error.starts_with("nonce too high") || error.starts_with("intrinsic gas too low") - || error.starts_with("insufficient funds for gas * price + value"); + || error.starts_with("insufficient funds for gas * price + value") + || error.starts_with("insufficient funds for transfer"); if trace.invalid && !allowed_cases { return Err(Error::TracingError(error.clone())); } diff --git a/gadgets/Cargo.toml b/gadgets/Cargo.toml index e1869999d5..c156da2c78 100644 --- a/gadgets/Cargo.toml +++ b/gadgets/Cargo.toml @@ -11,6 +11,7 @@ sha3 = "0.7.2" eth-types = { path = "../eth-types" } digest = "0.7.6" strum = "0.24" +itertools = "0.10" [dev-dependencies] rand = "0.8" diff --git a/gadgets/src/binary_number.rs b/gadgets/src/binary_number.rs index 788074c5fd..68a3dd2e86 100644 --- a/gadgets/src/binary_number.rs +++ b/gadgets/src/binary_number.rs @@ -9,7 +9,7 @@ use halo2_proofs::{ plonk::{Advice, Column, ConstraintSystem, Error, Expression, Fixed, VirtualCells}, poly::Rotation, }; -use std::{collections::BTreeSet, marker::PhantomData}; +use std::{collections::BTreeSet, marker::PhantomData, ops::Deref}; use strum::IntoEnumIterator; /// Helper trait that implements functionality to represent a generic type as @@ -34,11 +34,66 @@ where } } +/// Columns of the binary number chip. This can be instantiated without the associated constraints +/// of the BinaryNumberChip in order to be used as part of a shared table for unit tests. +#[derive(Clone, Copy, Debug)] +pub struct BinaryNumberBits( + /// Must be constrained to be binary for correctness. + pub [Column; N], +); + +impl Deref for BinaryNumberBits { + type Target = [Column; N]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl BinaryNumberBits { + /// Construct a new BinaryNumberBits without adding any constraints. + pub fn construct(meta: &mut ConstraintSystem) -> Self { + Self([0; N].map(|_| meta.advice_column())) + } + + /// Assign a value to the binary number bits. A generic type that implements + /// the AsBits trait can be provided for assignment. + pub fn assign>( + &self, + region: &mut Region<'_, F>, + offset: usize, + value: &T, + ) -> Result<(), Error> { + for (&bit, &column) in value.as_bits().iter().zip(self.iter()) { + region.assign_advice( + || format!("binary number {:?}", column), + column, + offset, + || Value::known(F::from(bit as u64)), + )?; + } + Ok(()) + } + + /// Returns the expression value of the bits at the given rotation. + pub fn value( + &self, + rotation: Rotation, + ) -> impl FnOnce(&mut VirtualCells<'_, F>) -> Expression { + let bits = self.0; + move |meta: &mut VirtualCells<'_, F>| { + let bits = bits.map(|bit| meta.query_advice(bit, rotation)); + bits.iter() + .fold(0.expr(), |result, bit| bit.clone() + result * 2.expr()) + } + } +} + /// Config for the binary number chip. #[derive(Clone, Copy, Debug)] pub struct BinaryNumberConfig { /// Must be constrained to be binary for correctness. - pub bits: [Column; N], + pub bits: BinaryNumberBits, _marker: PhantomData, } @@ -51,12 +106,7 @@ where &self, rotation: Rotation, ) -> impl FnOnce(&mut VirtualCells<'_, F>) -> Expression { - let bits = self.bits; - move |meta: &mut VirtualCells<'_, F>| { - let bits = bits.map(|bit| meta.query_advice(bit, rotation)); - bits.iter() - .fold(0.expr(), |result, bit| bit.clone() + result * 2.expr()) - } + self.bits.value(rotation) } /// Return the constant that represents a given value. To be compared with the value expression. @@ -140,10 +190,10 @@ where /// Configure constraints for the binary number chip. pub fn configure( meta: &mut ConstraintSystem, + bits: BinaryNumberBits, selector: Column, value: Option>, ) -> BinaryNumberConfig { - let bits = [0; N].map(|_| meta.advice_column()); bits.map(|bit| { meta.create_gate("bit column is 0 or 1", |meta| { let selector = meta.query_fixed(selector, Rotation::cur()); @@ -194,15 +244,7 @@ where offset: usize, value: &T, ) -> Result<(), Error> { - for (&bit, &column) in value.as_bits().iter().zip(&self.config.bits) { - region.assign_advice( - || format!("binary number {:?}", column), - column, - offset, - || Value::known(F::from(bit as u64)), - )?; - } - Ok(()) + self.config.bits.assign(region, offset, value) } } diff --git a/gadgets/src/is_zero.rs b/gadgets/src/is_zero.rs index ed44aa56a0..db89ff28ba 100644 --- a/gadgets/src/is_zero.rs +++ b/gadgets/src/is_zero.rs @@ -52,7 +52,7 @@ impl IsZeroConfig { } #[derive(Debug, Clone)] -/// Wrapper arround [`IsZeroConfig`] for which [`Chip`] is implemented. +/// Wrapper around [`IsZeroConfig`] for which [`Chip`] is implemented. pub struct IsZeroChip { config: IsZeroConfig, } diff --git a/gadgets/src/lib.rs b/gadgets/src/lib.rs index a7150262ee..fea14604d0 100644 --- a/gadgets/src/lib.rs +++ b/gadgets/src/lib.rs @@ -16,6 +16,7 @@ pub mod binary_number; pub mod is_zero; pub mod less_than; pub mod mul_add; +pub mod permutation; pub mod util; use eth_types::Field; diff --git a/gadgets/src/permutation.rs b/gadgets/src/permutation.rs new file mode 100644 index 0000000000..796086cb35 --- /dev/null +++ b/gadgets/src/permutation.rs @@ -0,0 +1,358 @@ +//! Chip that implements permutation fingerprints +//! fingerprints &= \prod_{row_j} \left ( \alpha - \sum_k (\gamma^k \cdot cell_j(k)) \right ) +//! power of gamma are defined in columns to trade more columns with less degrees +use std::iter; +#[rustfmt::skip] +// | q_row_non_first | q_row_enable | q_row_last | alpha | gamma | gamma power 2 | ... | row fingerprint | accumulated fingerprint | +// |-----------------|--------------|------------|-----------|-----------|-----------------| | --------------- | ---------------------- | +// | 0 |1 |0 |alpha | gamma | gamma **2 | ... | F | F | +// | 1 |1 |0 |alpha | gamma | gamma **2 | ... | F | F | +// | 1 |1 |1 |alpha | gamma | gamma **2 | ... | F | F | + +use std::marker::PhantomData; + +use crate::util::Expr; +use eth_types::Field; +use halo2_proofs::{ + circuit::{AssignedCell, Region, Value}, + plonk::{Advice, Column, ConstraintSystem, Error, Expression, Selector}, + poly::Rotation, +}; +use itertools::Itertools; + +/// Config for PermutationChipConfig +#[derive(Clone, Debug)] +pub struct PermutationChipConfig { + /// acc_fingerprints + pub acc_fingerprints: Column, + row_fingerprints: Column, + alpha: Column, + power_of_gamma: Vec>, + /// q_row_non_first + pub q_row_non_first: Selector, // 1 between (first, end], exclude first + /// q_row_enable + pub q_row_enable: Selector, // 1 for all rows (including first) + /// q_row_last + pub q_row_last: Selector, // 1 in the last row + + _phantom: PhantomData, + + row_fingerprints_cur_expr: Expression, + acc_fingerprints_cur_expr: Expression, +} + +/// (alpha, gamma, row_fingerprints_prev_cell, row_fingerprints_next_cell, prev_acc_fingerprints, +/// next_acc_fingerprints) +type PermutationAssignedCells = ( + AssignedCell, + AssignedCell, + AssignedCell, + AssignedCell, + AssignedCell, + AssignedCell, +); + +impl PermutationChipConfig { + /// assign + pub fn assign( + &self, + region: &mut Region<'_, F>, + alpha: Value, + gamma: Value, + acc_fingerprints_prev: Value, + col_values: &[Vec>], + prefix: &'static str, + ) -> Result, Error> { + self.annotate_columns_in_region(region, prefix); + + // get accumulated fingerprints of each row + let fingerprints = + get_permutation_fingerprints(col_values, alpha, gamma, acc_fingerprints_prev); + + // power_of_gamma start from gamma**1 + let power_of_gamma = { + let num_of_col = col_values.first().map(|row| row.len()).unwrap_or_default(); + std::iter::successors(Some(gamma), |prev| (*prev * gamma).into()) + .take(num_of_col.saturating_sub(1)) + .collect::>>() + }; + + let mut alpha_first_cell = None; + let mut gamma_first_cell = None; + let mut acc_fingerprints_prev_cell = None; + let mut acc_fingerprints_next_cell = None; + + let mut row_fingerprints_prev_cell = None; + let mut row_fingerprints_next_cell = None; + + for (offset, (row_acc_fingerprints, row_fingerprints)) in fingerprints.iter().enumerate() { + // skip first fingerprint for its prev_fingerprint + if offset != 0 { + self.q_row_non_first.enable(region, offset)?; + } + + self.q_row_enable.enable(region, offset)?; + + let row_acc_fingerprint_cell = region.assign_advice( + || format!("acc_fingerprints at index {}", offset), + self.acc_fingerprints, + offset, + || *row_acc_fingerprints, + )?; + + let row_fingerprints_cell = region.assign_advice( + || format!("row_fingerprints at index {}", offset), + self.row_fingerprints, + offset, + || *row_fingerprints, + )?; + + let alpha_cell = region.assign_advice( + || format!("alpha at index {}", offset), + self.alpha, + offset, + || alpha, + )?; + let gamma_cells = self + .power_of_gamma + .iter() + .zip_eq(power_of_gamma.iter()) + .map(|(col, value)| { + region.assign_advice( + || format!("gamma at index {}", offset), + *col, + offset, + || *value, + ) + }) + .collect::>, Error>>()?; + + if offset == 0 { + alpha_first_cell = Some(alpha_cell); + gamma_first_cell = Some(gamma_cells[0].clone()); + acc_fingerprints_prev_cell = Some(row_acc_fingerprint_cell.clone()); + row_fingerprints_prev_cell = Some(row_fingerprints_cell.clone()) + } + // last offset + if offset == fingerprints.len() - 1 { + self.q_row_last.enable(region, offset)?; + acc_fingerprints_next_cell = Some(row_acc_fingerprint_cell); + row_fingerprints_next_cell = Some(row_fingerprints_cell) + } + } + + Ok(( + alpha_first_cell.unwrap(), + gamma_first_cell.unwrap(), + row_fingerprints_prev_cell.unwrap(), + row_fingerprints_next_cell.unwrap(), + acc_fingerprints_prev_cell.unwrap(), + acc_fingerprints_next_cell.unwrap(), + )) + } + + /// Annotates columns of this gadget embedded within a circuit region. + pub fn annotate_columns_in_region(&self, region: &mut Region, prefix: &str) { + [ + ( + self.acc_fingerprints, + "GADGETS_PermutationChipConfig_acc_fingerprints".to_string(), + ), + ( + self.row_fingerprints, + "GADGETS_PermutationChipConfig_row_fingerprints".to_string(), + ), + ( + self.alpha, + "GADGETS_PermutationChipConfig_alpha".to_string(), + ), + ] + .iter() + .cloned() + .chain(self.power_of_gamma.iter().enumerate().map(|(i, col)| { + ( + *col, + format!("GADGETS_PermutationChipConfig_gamma_{}", i + 1), + ) + })) + .for_each(|(col, ann)| region.name_column(|| format!("{}_{}", prefix, ann), col)); + } + + /// acc_fingerprints_cur_expr + pub fn acc_fingerprints_cur_expr(&self) -> Expression { + self.acc_fingerprints_cur_expr.clone() + } + + /// row_fingerprints_cur_expr + pub fn row_fingerprints_cur_expr(&self) -> Expression { + self.row_fingerprints_cur_expr.clone() + } +} + +/// permutation fingerprint gadget +#[derive(Debug, Clone)] +pub struct PermutationChip { + /// config + pub config: PermutationChipConfig, +} + +impl PermutationChip { + /// configure + pub fn configure( + meta: &mut ConstraintSystem, + cols: Vec>, + ) -> PermutationChipConfig { + let acc_fingerprints = meta.advice_column(); + let row_fingerprints = meta.advice_column(); + let alpha = meta.advice_column(); + + // trade more columns with less degrees + let power_of_gamma = (0..cols.len() - 1) + .map(|_| meta.advice_column()) + .collect::>>(); // first element is gamma**1 + + let q_row_non_first = meta.complex_selector(); + let q_row_enable = meta.complex_selector(); + let q_row_last = meta.selector(); + + meta.enable_equality(acc_fingerprints); + meta.enable_equality(row_fingerprints); + meta.enable_equality(alpha); + meta.enable_equality(power_of_gamma[0]); + + let mut acc_fingerprints_cur_expr: Expression = 0.expr(); + let mut row_fingerprints_cur_expr: Expression = 0.expr(); + + meta.create_gate( + "acc_fingerprints_cur = acc_fingerprints_prev * row_fingerprints_cur", + |meta| { + let q_row_non_first = meta.query_selector(q_row_non_first); + let acc_fingerprints_prev = meta.query_advice(acc_fingerprints, Rotation::prev()); + let acc_fingerprints_cur = meta.query_advice(acc_fingerprints, Rotation::cur()); + let row_fingerprints_cur = meta.query_advice(row_fingerprints, Rotation::cur()); + + acc_fingerprints_cur_expr = acc_fingerprints_cur.clone(); + + [q_row_non_first + * (acc_fingerprints_cur - acc_fingerprints_prev * row_fingerprints_cur)] + }, + ); + + meta.create_gate( + "row_fingerprints_cur = fingerprints(column_exprs)", + |meta| { + let alpha = meta.query_advice(alpha, Rotation::cur()); + let row_fingerprints_cur = meta.query_advice(row_fingerprints, Rotation::cur()); + + row_fingerprints_cur_expr = row_fingerprints_cur.clone(); + + let power_of_gamma = iter::once(1.expr()) + .chain( + power_of_gamma + .iter() + .map(|column| meta.query_advice(*column, Rotation::cur())), + ) + .collect::>>(); + + let q_row_enable = meta.query_selector(q_row_enable); + let cols_cur_exprs = cols + .iter() + .map(|col| meta.query_advice(*col, Rotation::cur())) + .collect::>>(); + + let perf_term = cols_cur_exprs + .iter() + .zip_eq(power_of_gamma.iter()) + .map(|(a, b)| a.clone() * b.clone()) + .fold(0.expr(), |a, b| a + b); + [q_row_enable * (row_fingerprints_cur - (alpha - perf_term))] + }, + ); + + meta.create_gate("challenges consistency", |meta| { + let q_row_non_first = meta.query_selector(q_row_non_first); + let alpha_prev = meta.query_advice(alpha, Rotation::prev()); + let alpha_cur = meta.query_advice(alpha, Rotation::cur()); + + [ + vec![q_row_non_first.clone() * (alpha_prev - alpha_cur)], + power_of_gamma + .iter() + .map(|col| { + let gamma_prev = meta.query_advice(*col, Rotation::prev()); + let gamma_cur = meta.query_advice(*col, Rotation::cur()); + q_row_non_first.clone() * (gamma_prev - gamma_cur) + }) + .collect(), + ] + .concat() + }); + + meta.create_gate("power of gamma", |meta| { + let q_row_non_first = meta.query_selector(q_row_non_first); + let gamma = meta.query_advice(power_of_gamma[0], Rotation::cur()); + power_of_gamma + .iter() + .tuple_windows() + .map(|(col1, col2)| { + let col1_cur = meta.query_advice(*col1, Rotation::cur()); + let col2_cur = meta.query_advice(*col2, Rotation::cur()); + q_row_non_first.clone() * (col2_cur - col1_cur * gamma.clone()) + }) + .collect::>>() + }); + + PermutationChipConfig { + acc_fingerprints, + acc_fingerprints_cur_expr, + row_fingerprints, + row_fingerprints_cur_expr, + q_row_non_first, + q_row_enable, + q_row_last, + alpha, + power_of_gamma, + _phantom: PhantomData:: {}, + } + } +} + +impl PermutationChip {} + +/// get permutation fingerprint of rows +pub fn get_permutation_fingerprints( + col_values: &[Vec>], + alpha: Value, + gamma: Value, + acc_fingerprints_prev: Value, +) -> Vec<(Value, Value)> { + let power_of_gamma = { + let num_of_col = col_values.first().map(|row| row.len()).unwrap_or_default(); + std::iter::successors(Some(Value::known(F::ONE)), |prev| (*prev * gamma).into()) + .take(num_of_col) + .collect::>>() + }; + let mut result = vec![]; + col_values + .iter() + .map(|row| { + // row = alpha - (gamma^1 x1 + gamma^2 x2 + ...) + let tmp = row + .iter() + .zip_eq(power_of_gamma.iter()) + .map(|(a, b)| *a * b) + .fold(Value::known(F::ZERO), |prev, cur| prev + cur); + alpha - tmp + }) + .enumerate() + .for_each(|(i, value)| { + // fingerprint = row0 * row1 * ... rowi + // (fingerprinti, rowi) + if i == 0 { + result.push((acc_fingerprints_prev, value)); + } else { + result.push((result[result.len() - 1].0 * value, value)); + } + }); + result +} diff --git a/geth-utils/gethutil/mpt/state/statedb.go b/geth-utils/gethutil/mpt/state/statedb.go index 68619e8547..51f1f53115 100644 --- a/geth-utils/gethutil/mpt/state/statedb.go +++ b/geth-utils/gethutil/mpt/state/statedb.go @@ -785,7 +785,7 @@ func (s *StateDB) Copy() *StateDB { // nil if object, exist := s.stateObjects[addr]; exist { // Even though the original object is dirty, we are not copying the journal, - // so we need to make sure that anyside effect the journal would have caused + // so we need to make sure that any side effect the journal would have caused // during a commit (or similar op) is already applied to the copy. state.stateObjects[addr] = object.deepCopy(state) @@ -834,7 +834,7 @@ func (s *StateDB) Copy() *StateDB { } if s.snaps != nil { // In order for the miner to be able to use and make additions - // to the snapshot tree, we need to copy that aswell. + // to the snapshot tree, we need to copy that as well. // Otherwise, any block mined by ourselves will cause gaps in the tree, // and force the miner to operate trie-backed only state.snaps = s.snaps diff --git a/geth-utils/gethutil/mpt/trie/hasher.go b/geth-utils/gethutil/mpt/trie/hasher.go index c96677415b..4904340b7b 100644 --- a/geth-utils/gethutil/mpt/trie/hasher.go +++ b/geth-utils/gethutil/mpt/trie/hasher.go @@ -40,7 +40,7 @@ func (b *sliceBuffer) Reset() { type hasher struct { sha crypto.KeccakState tmp sliceBuffer - parallel bool // Whether to use paralallel threads when hashing + parallel bool // Whether to use parallel threads when hashing } // hasherPool holds pureHashers @@ -189,7 +189,7 @@ func (h *hasher) HashData(data []byte) HashNode { } // ProofHash is used to construct trie proofs, and returns the 'collapsed' -// node (for later RLP encoding) aswell as the hashed node -- unless the +// node (for later RLP encoding) as well as the hashed node -- unless the // node is smaller than 32 bytes, in which case it will be returned as is. // This method does not do anything on value- or hash-nodes. func (h *hasher) ProofHash(original Node) (collapsed, hashed Node) { diff --git a/geth-utils/gethutil/mpt/trie/stacktrie.go b/geth-utils/gethutil/mpt/trie/stacktrie.go index c5a04e5926..0b214071f3 100644 --- a/geth-utils/gethutil/mpt/trie/stacktrie.go +++ b/geth-utils/gethutil/mpt/trie/stacktrie.go @@ -24,6 +24,7 @@ import ( "fmt" "io" "main/gethutil/mpt/types" + "slices" "sync" "github.com/ethereum/go-ethereum/common" @@ -230,9 +231,6 @@ func (st *StackTrie) getDiffIndex(key []byte) int { // Helper function to that inserts a (key, value) pair into // the trie. func (st *StackTrie) insert(key, value []byte) { - if key[0] == 1 && key[1] == 0 { - fmt.Println("d") - } switch st.nodeType { case branchNode: /* Branch */ idx := int(key[st.keyOffset]) @@ -245,16 +243,17 @@ func (st *StackTrie) insert(key, value []byte) { break } } + // Add new child if st.children[idx] == nil { - st.children[idx] = stackTrieFromPool(st.db) - st.children[idx].keyOffset = st.keyOffset + 1 + st.children[idx] = newLeaf(st.keyOffset+1, key, value, st.db) + } else { + st.children[idx].insert(key, value) } - st.children[idx].insert(key, value) + case extNode: /* Ext */ // Compare both key chunks and see where they differ diffidx := st.getDiffIndex(key) - // Check if chunks are identical. If so, recurse into // the child node. Otherwise, the key has to be split // into 1) an optional common prefix, 2) the fullnode @@ -553,50 +552,70 @@ func (st *StackTrie) Commit() (common.Hash, error) { return common.BytesToHash(st.val), nil } -func (st *StackTrie) getNodeFromBranchRLP(branch []byte, ind byte) []byte { - start := 2 // when branch[0] == 248 - if branch[0] == 249 { - start = 3 - } - - i := 0 - insideInd := -1 - cInd := byte(0) - for { - if start+i == len(branch)-1 { // -1 because of the last 128 (branch value) - return []byte{0} - } - b := branch[start+i] - if insideInd == -1 && b == 128 { - if cInd == ind { +const RLP_SHORT_STR_FLAG = 128 +const RLP_SHORT_LIST_FLAG = 192 +const RLP_LONG_LIST_FLAG = 248 +const LEN_OF_HASH = 32 + +// Note: +// In RLP encoding, if the value is between [0x80, 0xb7] ([128, 183]), +// it means following data is a short string (0 - 55bytes). +// Which implies if the value is 128, it's an empty string. +func (st *StackTrie) getNodeFromBranchRLP(branch []byte, idx int) []byte { + + start := int(branch[0]) + start_idx := 0 + if start >= RLP_SHORT_LIST_FLAG && start < RLP_LONG_LIST_FLAG { + // In RLP encoding, length in the range of [192 248] is a short list. + // In stack trie, it usually means an extension node and the first byte is nibble + // and that's why we start from 2 + start_idx = 2 + } else if start >= RLP_LONG_LIST_FLAG { + // In RLP encoding, length in the range of [248 ~ ] is a long list. + // The RLP byte minus 248 (branch[0] - 248) is the length in bytes of the length of the payload + // and the payload is right after the length. + // That's why we add 2 here + // e.g. [248 81 128 160 ...] + // `81` is the length of the payload and payload starts from `128` + start_idx = start - RLP_LONG_LIST_FLAG + 2 + } + + // If 1st node is neither 128(empty node) nor 160, it should be a leaf + b := int(branch[start_idx]) + if b != RLP_SHORT_STR_FLAG && b != (RLP_SHORT_STR_FLAG+LEN_OF_HASH) { + return []byte{0} + } + + current_idx := 0 + for i := start_idx; i < len(branch); i++ { + b = int(branch[i]) + switch b { + case RLP_SHORT_STR_FLAG: // 128 + // if the current index is we're looking for, return an empty node directly + if current_idx == idx { return []byte{128} - } else { - cInd += 1 } - } else if insideInd == -1 && b != 128 { - if b == 160 { - if cInd == ind { - return branch[start+i+1 : start+i+1+32] - } - insideInd = 32 - } else { - // non-hashed node - if cInd == ind { - return branch[start+i+1 : start+i+1+int(b)-192] - } - insideInd = int(b) - 192 + current_idx++ + case RLP_SHORT_STR_FLAG + LEN_OF_HASH: // 160 + if current_idx == idx { + return branch[i+1 : i+1+LEN_OF_HASH] } - cInd += 1 - } else { - if insideInd == 1 { - insideInd = -1 - } else { - insideInd-- + // jump to next encoded element + i += LEN_OF_HASH + current_idx++ + default: + if b >= 192 && b < 248 { + length := b - 192 + if current_idx == idx { + return branch[i+1 : i+1+length] + } + i += length + current_idx++ } } - - i++ } + + return []byte{0} } type StackProof struct { @@ -604,6 +623,14 @@ type StackProof struct { proofC [][]byte } +func (sp *StackProof) GetProofS() [][]byte { + return sp.proofS +} + +func (sp *StackProof) GetProofC() [][]byte { + return sp.proofC +} + func (st *StackTrie) UpdateAndGetProof(db ethdb.KeyValueReader, indexBuf, value []byte) (StackProof, error) { proofS, err := st.GetProof(db, indexBuf) if err != nil { @@ -620,6 +647,8 @@ func (st *StackTrie) UpdateAndGetProof(db ethdb.KeyValueReader, indexBuf, value return StackProof{proofS, proofC}, nil } +// We refer to the link below for this function. +// https://github.com/ethereum/go-ethereum/blob/00905f7dc406cfb67f64cd74113777044fb886d8/core/types/hashing.go#L105-L134 func (st *StackTrie) UpdateAndGetProofs(db ethdb.KeyValueReader, list types.DerivableList) ([]StackProof, error) { valueBuf := types.EncodeBufferPool.Get().(*bytes.Buffer) defer types.EncodeBufferPool.Put(valueBuf) @@ -633,25 +662,33 @@ func (st *StackTrie) UpdateAndGetProofs(db ethdb.KeyValueReader, list types.Deri for i := 1; i < list.Len() && i <= 0x7f; i++ { indexBuf = rlp.AppendUint64(indexBuf[:0], uint64(i)) value := types.EncodeForDerive(list, i, valueBuf) - proof, err := st.UpdateAndGetProof(db, indexBuf, value) if err != nil { return nil, err } - proofs = append(proofs, proof) } + + // special case when index is 0 + // rlp.AppendUint64() encodes index 0 to [128] if list.Len() > 0 { indexBuf = rlp.AppendUint64(indexBuf[:0], 0) value := types.EncodeForDerive(list, 0, valueBuf) - // TODO: get proof - st.Update(indexBuf, value) + proof, err := st.UpdateAndGetProof(db, indexBuf, value) + if err != nil { + return nil, err + } + proofs = append(proofs, proof) } + for i := 0x80; i < list.Len(); i++ { indexBuf = rlp.AppendUint64(indexBuf[:0], uint64(i)) value := types.EncodeForDerive(list, i, valueBuf) - // TODO: get proof - st.Update(indexBuf, value) + proof, err := st.UpdateAndGetProof(db, indexBuf, value) + if err != nil { + return nil, err + } + proofs = append(proofs, proof) } return proofs, nil @@ -659,8 +696,6 @@ func (st *StackTrie) UpdateAndGetProofs(db ethdb.KeyValueReader, list types.Deri func (st *StackTrie) GetProof(db ethdb.KeyValueReader, key []byte) ([][]byte, error) { k := KeybytesToHex(key) - i := 0 - if st.nodeType == emptyNode { return [][]byte{}, nil } @@ -678,16 +713,15 @@ func (st *StackTrie) GetProof(db ethdb.KeyValueReader, key []byte) ([][]byte, er } var proof [][]byte - var nodes []*StackTrie - c := st isHashed := false - for i < len(k) { + for i := 0; i < len(k); i++ { if c.nodeType == extNode { nodes = append(nodes, c) - c = st.children[0] + c = c.children[0] + } else if c.nodeType == branchNode { nodes = append(nodes, c) c = c.children[k[i]] @@ -701,33 +735,19 @@ func (st *StackTrie) GetProof(db ethdb.KeyValueReader, key []byte) ([][]byte, er isHashed = true c_rlp, error := db.Get(c.val) if error != nil { - fmt.Println(error) panic(error) } - fmt.Println(c_rlp) proof = append(proof, c_rlp) + branchChild := st.getNodeFromBranchRLP(c_rlp, int(k[i])) - for i < len(k)-1 { - node := st.getNodeFromBranchRLP(c_rlp, k[i]) - i += 1 - fmt.Println(node) - - if len(node) == 1 && node[0] == 128 { // no child at this position - break - } - - c_rlp, error = db.Get(node) - if error != nil { - fmt.Println(error) - panic(error) - } - fmt.Println(c_rlp) - - proof = append(proof, c_rlp) + // branchChild is of length 1 when there is no child at this position in the branch + // (`branchChild = [128]` in this case), but it is also of length 1 when `c_rlp` is a leaf. + if len(branchChild) == 1 && (branchChild[0] == 128 || branchChild[0] == 0) { + // no child at this position - 128 is RLP encoding for nil object + break } - - break + c.val = branchChild } } @@ -740,7 +760,6 @@ func (st *StackTrie) GetProof(db ethdb.KeyValueReader, key []byte) ([][]byte, er lNodes := len(nodes) for i := lNodes - 1; i >= 0; i-- { node := nodes[i] - fmt.Println(node) if node.nodeType == leafNode { rlp, error := db.Get(node.val) @@ -760,11 +779,9 @@ func (st *StackTrie) GetProof(db ethdb.KeyValueReader, key []byte) ([][]byte, er } } - } - - fmt.Println("----------") - for i := 0; i < len(proof); i++ { - fmt.Println(proof[i]) + // The proof is now reversed (only for non-hashed), + // let's reverse it back to have the leaf at the bottom: + slices.Reverse(proof) } return proof, nil diff --git a/geth-utils/gethutil/mpt/types/block.go b/geth-utils/gethutil/mpt/types/block.go index 360f1eb47c..b22efb6692 100644 --- a/geth-utils/gethutil/mpt/types/block.go +++ b/geth-utils/gethutil/mpt/types/block.go @@ -314,7 +314,7 @@ func (b *Block) Header() *Header { return CopyHeader(b.header) } func (b *Block) Body() *Body { return &Body{b.transactions, b.uncles} } // Size returns the true RLP encoded storage size of the block, either by encoding -// and returning it, or returning a previsouly cached value. +// and returning it, or returning a previously cached value. func (b *Block) Size() common.StorageSize { if size := b.size.Load(); size != nil { return size.(common.StorageSize) diff --git a/geth-utils/gethutil/mpt/witness/gen_witness_transactions_test.go b/geth-utils/gethutil/mpt/witness/gen_witness_transactions_test.go index cd8c3b090d..962b9461b3 100644 --- a/geth-utils/gethutil/mpt/witness/gen_witness_transactions_test.go +++ b/geth-utils/gethutil/mpt/witness/gen_witness_transactions_test.go @@ -1,6 +1,7 @@ package witness import ( + "bytes" "fmt" "main/gethutil/mpt/trie" "main/gethutil/mpt/types" @@ -8,57 +9,162 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" ) -func TestTransactions(t *testing.T) { - t.Skip("failing test") - txs := make([]*types.Transaction, 70) +func makeTransactions(n int) []*types.Transaction { + txs := make([]*types.Transaction, n) key, _ := crypto.GenerateKey() signer := types.LatestSigner(params.TestChainConfig) for i := range txs { - amount := math.BigPow(2, int64(i)) - price := big.NewInt(300000) + amount := big.NewInt(int64(i)*10 ^ 9) + gas_price := big.NewInt(300_000) data := make([]byte, 100) - tx := types.NewTransaction(uint64(i), common.Address{}, amount, 123457, price, data) + // randomly assigned for debugging + data[3] = 3 + data[4] = 3 + data[5] = 3 + data[6] = 3 + data[7] = 3 + tx := types.NewTransaction(uint64(i), common.Address{}, amount, 10*10^6, gas_price, data) signedTx, err := types.SignTx(tx, signer, key) if err != nil { panic(err) } txs[i] = signedTx } + return txs +} + +/* +transactionsStackTrieInsertionTemplate inserts n transactions into a stacktrie. +For each of the n modifications of the trie it asks for a proof - GetProof is called before +and after the modification. The transactions in the trie are not hashed and thus GetProof +does not require to query a database to get the preimages. + +When the first transaction is added, a leaf is added to the trie +(it has index 1 which is used as a key when inserting into a trie, the key is changed by +calling KeybytesToHex(key) in TryUpdate to [0, 1, 16]). + +When the second transaction is added (it has index 2, when inserting into a trie, +it gets changed to [0, 2, 16]), the extension node E is created with nibble 0 (note that +both leaves/transactions have the first nibble 0) and the underlying branch B with children +at positions 1 and 2 (second nibble of the two leaves). + +At this point, the proof for the second transaction is (proofC when index = 2): +[226 16 160 212 52 159 164 192 63 244 122 229 5 208 58 20 16 54 62 169 98 62 238 163 88 174 155 252 118 132 91 148 62 122 23] +[248 81 128 160 32 244 75 78 180 11 251 73 229 254 70 16 254 170 54 254 200 97 231 24 180 34 220 244 153 76 1 194 23 63 64 224 160 46 141 2 37 188 204 110 232 46 31 230 82 226 213 98 71 18 241 37 90 213 167 221 58 33 36 249 248 180 207 235 47 128 128 128 128 128 128 128 128 128 128 128 128 128 128] +[248 200 2 131 4 147 224 131 1 226 65 148 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 184 100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 37 160 163 65 77 46 20 3 175 162 34 86 182 41 225 43 90 92 158 249 153 67 193 148 178 63 8 81 26 169 176 56 242 78 160 21 37 82 209 254 5 113 171 235 198 244 52 17 233 162 51 76 151 85 224 28 101 146 160 197 216 253 237 240 187 19 184] + +Note that the first proof element is an extension node with nibble 0 = 16 - 16 (see +the second byte). The third byte (32 = 160 - 128) denotes the length of the subsequent stream +which represents the hash of the underlying branch. +The second proof element is the underlying branch. The second byte (81) denotes the length +of the subsequent RLP stream. The third byte (128) denotes the nil element at position 0. +Then there are two children at positions 1 (32 244 75...) and 2 (46 141 2...). Note that +these two 32-long value are the hashes of the two leaves/transactions in the branch. +The bytes 128 at the end of the branch RLP represents nil objects at positions 3 - 15. +The last proof element is the second transaction, for example the third nibble (2) +represents the index of the transaction. + +When further 13 transactions are added, the branch B gets populated at positions 3 - 15 +(the position 0 remains nil). +When the 16-th transaction is added (it has index 16, it gets changed to [1, 0, 16]), +the extension node E is turned into branch B1 which has children at positions 0 and 1. +At position 0 it has a branch B (which used to be the underlying branch of E1) and +at position 1 it has a leaf that represents the 16-transaction. + +At this point, the proof for the second transaction is (proofC when index = 16): +[248 81 160 204 44 112 166 132 56 23 211 247 164 233 113 161 247 117 64 34 142 106 19 106 151 213 163 170 185 19 10 144 231 85 229 160 23 243 146 56 210 93 132 177 170 102 160 150 91 57 192 254 50 122 118 157 138 67 46 2 247 8 89 216 105 197 213 36 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128] +[248 203 16 131 4 147 224 131 1 226 65 148 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 131 1 0 0 184 100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 38 160 4 18 182 163 225 56 150 243 120 135 140 57 183 97 55 103 25 62 11 37 106 178 135 7 12 58 133 148 112 183 105 66 160 106 208 180 0 175 152 228 224 143 226 84 16 188 253 79 140 234 80 104 143 32 229 83 105 24 251 62 24 122 66 11 59] + +The first proof element is a branch with children at position 0 (branch B) and 1 (newly added leaf). +The second element is the 16-th transaction. For example, the third byte (16) represents +the transaction index. +*/ + +func transactionsStackTrieInsertionTemplate(t *testing.T, n int) { + txs := makeTransactions(n) db := rawdb.NewMemoryDatabase() stackTrie := trie.NewStackTrie(db) - stackTrie.UpdateAndGetProofs(db, types.Transactions(txs)) + proofs, _ := stackTrie.UpdateAndGetProofs(db, types.Transactions(txs)) - fmt.Println("===") -} + rlp_last_tx, _ := txs[n-1].MarshalBinary() + last_proofC := proofs[len(proofs)-1].GetProofC() -// No update for each step, just final proof. -func TestGetProof(t *testing.T) { - txs := make([]*types.Transaction, 70) - key, _ := crypto.GenerateKey() - signer := types.LatestSigner(params.TestChainConfig) + // Proof of the first tx is appended at the end of the proofs if len(tx) < 0x80 + // That's why we minus 2 here. + if len(txs) > 1 && len(txs) < 256 { + last_proofC = proofs[len(proofs)-2].GetProofC() + } + last_leaf_proof := last_proofC[len(last_proofC)-1] - for i := range txs { - amount := math.BigPow(2, int64(i)) - price := big.NewInt(300000) - data := make([]byte, 100) - tx := types.NewTransaction(uint64(i), common.Address{}, amount, 123457, price, data) - signedTx, err := types.SignTx(tx, signer, key) - if err != nil { - panic(err) - } - txs[i] = signedTx + if !bytes.Equal(last_leaf_proof, rlp_last_tx) { + fmt.Println("- last_tx ", rlp_last_tx) + fmt.Println("- last_proof ", last_leaf_proof) + t.Fail() } +} + +func TestStackTrieInsertion_1Tx(t *testing.T) { + // Only one leaf + transactionsStackTrieInsertionTemplate(t, 1) +} + +func TestStackTrieInsertion_2Txs(t *testing.T) { + // One ext. node and one leaf + transactionsStackTrieInsertionTemplate(t, 2) +} +func TestStackTrieInsertion_3Txs(t *testing.T) { + // One ext. node, one branch and one leaf + transactionsStackTrieInsertionTemplate(t, 3) +} + +func TestStackTrieInsertion_4Txs(t *testing.T) { + // One ext. node, one branch and two leaves + transactionsStackTrieInsertionTemplate(t, 4) +} + +func TestStackTrieInsertion_16Txs(t *testing.T) { + // One ext. node and one branch with full leaves (16 leaves) + transactionsStackTrieInsertionTemplate(t, 16) +} + +func TestStackTrieInsertion_17Txs(t *testing.T) { + // One ext. node, 3 branches and 17 leaves. + // The original ext. node turns into a branch (B1) which has children at position 0 and 1. + // At position 0 of B1, it has a branch with full leaves + // At position 1 of B1, it has a newly leaf + transactionsStackTrieInsertionTemplate(t, 17) +} + +func TestStackTrieInsertion_33Txs(t *testing.T) { + // Follow above test and have one more branch generated + transactionsStackTrieInsertionTemplate(t, 33) +} + +func TestStackTrieInsertion_ManyTxs(t *testing.T) { + // Just randomly picking a large number. + // The cap of block gas limit is 30M, the minimum gas cost of a tx is 21k + // 30M / 21k ~= 1429 + transactionsStackTrieInsertionTemplate(t, 2000) +} + +/* +batchedTransactionsStackTrieProofTemplate inserts n transactions into a stacktrie, +the trie is then hashed (DeriveSha call). +The proof is asked for one of the n transactions. The transactions in the trie are hashed and thus +GetProof requires to query a database to get the preimages. +*/ +func batchedTransactionsStackTrieProofTemplate(n int) { + txs := makeTransactions(n) db := rawdb.NewMemoryDatabase() stackTrie := trie.NewStackTrie(db) @@ -74,7 +180,35 @@ func TestGetProof(t *testing.T) { return } - fmt.Println(proofS) - + fmt.Println("proofS", proofS) fmt.Println("===") } + +func TestBatchedTxsProof_1Tx(t *testing.T) { + batchedTransactionsStackTrieProofTemplate(1) +} + +func TestBatchedTxsProof_2Txs(t *testing.T) { + batchedTransactionsStackTrieProofTemplate(2) +} + +func TestBatchedTxsProof_3Txs(t *testing.T) { + batchedTransactionsStackTrieProofTemplate(3) +} +func TestBatchedTxsProof_4Txs(t *testing.T) { + batchedTransactionsStackTrieProofTemplate(4) +} + +func TestBatchedTxsProof_16Txs(t *testing.T) { + batchedTransactionsStackTrieProofTemplate(16) +} + +func TestBatchedTxsProof_17Txs(t *testing.T) { + batchedTransactionsStackTrieProofTemplate(17) +} +func TestBatchedTxsProof_33Txs(t *testing.T) { + batchedTransactionsStackTrieProofTemplate(33) +} +func TestBatchedTxsProof_ManyTxs(t *testing.T) { + batchedTransactionsStackTrieProofTemplate(2000) +} diff --git a/geth-utils/gethutil/trace.go b/geth-utils/gethutil/trace.go index e6d8464d36..d48e46666c 100644 --- a/geth-utils/gethutil/trace.go +++ b/geth-utils/gethutil/trace.go @@ -99,25 +99,26 @@ type Account struct { } type Transaction struct { - From common.Address `json:"from"` - To *common.Address `json:"to"` - Nonce hexutil.Uint64 `json:"nonce"` - Value *hexutil.Big `json:"value"` - GasLimit hexutil.Uint64 `json:"gas_limit"` - GasPrice *hexutil.Big `json:"gas_price"` - GasFeeCap *hexutil.Big `json:"gas_fee_cap"` - GasTipCap *hexutil.Big `json:"gas_tip_cap"` - CallData hexutil.Bytes `json:"call_data"` - AccessList []struct { - Address common.Address `json:"address"` - StorageKeys []common.Hash `json:"storage_keys"` - } `json:"access_list"` + From common.Address `json:"from"` + To *common.Address `json:"to"` + Nonce hexutil.Uint64 `json:"nonce"` + Value *hexutil.Big `json:"value"` + GasLimit hexutil.Uint64 `json:"gas_limit"` + GasPrice *hexutil.Big `json:"gas_price"` + GasFeeCap *hexutil.Big `json:"gas_fee_cap"` + GasTipCap *hexutil.Big `json:"gas_tip_cap"` + CallData hexutil.Bytes `json:"call_data"` + AccessList types.AccessList `json:"access_list"` + Type string `json:"tx_type"` + V int64 `json:"v"` + R *hexutil.Big `json:"r"` + S *hexutil.Big `json:"s"` } type TraceConfig struct { ChainID *hexutil.Big `json:"chain_id"` // HistoryHashes contains most recent 256 block hashes in history, - // where the lastest one is at HistoryHashes[len(HistoryHashes)-1]. + // where the latest one is at HistoryHashes[len(HistoryHashes)-1]. HistoryHashes []*hexutil.Big `json:"history_hashes"` Block Block `json:"block_constants"` Accounts map[common.Address]Account `json:"accounts"` @@ -160,10 +161,14 @@ func Trace(config TraceConfig) ([]*ExecutionResult, error) { blockGasLimit := toBigInt(config.Block.GasLimit).Uint64() messages := make([]core.Message, len(config.Transactions)) for i, tx := range config.Transactions { - // If gas price is specified directly, the tx is treated as legacy type. if tx.GasPrice != nil { - tx.GasFeeCap = tx.GasPrice - tx.GasTipCap = tx.GasPrice + // Set GasFeeCap and GasTipCap to GasPrice if not exist. + if tx.GasFeeCap == nil { + tx.GasFeeCap = tx.GasPrice + } + if tx.GasTipCap == nil { + tx.GasTipCap = tx.GasPrice + } } txAccessList := make(types.AccessList, len(tx.AccessList)) diff --git a/geth-utils/go.mod b/geth-utils/go.mod index a80c801fe2..a417f0750e 100644 --- a/geth-utils/go.mod +++ b/geth-utils/go.mod @@ -1,10 +1,56 @@ module main -go 1.16 +go 1.21 require github.com/ethereum/go-ethereum v1.11.5 require golang.org/x/crypto v0.1.0 +require ( + github.com/DataDog/zstd v1.5.2 // indirect + github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect + github.com/VictoriaMetrics/fastcache v1.6.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 // indirect + github.com/cockroachdb/redact v1.1.3 // indirect + github.com/deckarep/golang-set/v2 v2.1.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/getsentry/sentry-go v0.18.0 // indirect + github.com/go-ole/go-ole v1.2.1 // indirect + github.com/go-stack/stack v1.8.1 // indirect + github.com/gofrs/flock v0.8.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/gorilla/websocket v1.4.2 // indirect + github.com/holiman/bloomfilter/v2 v2.0.3 // indirect + github.com/holiman/uint256 v1.2.0 // indirect + github.com/klauspost/compress v1.15.15 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.14.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.39.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect + github.com/tklauser/go-sysconf v0.3.5 // indirect + github.com/tklauser/numcpus v0.2.2 // indirect + golang.org/x/exp v0.0.0-20230206171751-46f607a40771 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/text v0.7.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect +) + // Uncomment for debugging // replace github.com/ethereum/go-ethereum => ../../go-ethereum diff --git a/geth-utils/go.sum b/geth-utils/go.sum index 62c668a662..11b360c307 100644 --- a/geth-utils/go.sum +++ b/geth-utils/go.sum @@ -1,327 +1,106 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= -cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= -github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= -github.com/CloudyKit/jet/v6 v6.1.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP/Lzo7Ro4= -github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06/go.mod h1:7erjKLwalezA0k99cWs5L11HWOAPNjdUZ6RxH1BXbbM= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= -github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= -github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= -github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= -github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= -github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= -github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= -github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= -github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 h1:ytcWPaNPhNoGMWEhDvS3zToKcDpRsLuRolQJBVGdozk= github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811/go.mod h1:Nb5lgvnQ2+oGlE/EyZy4+2/CxRh9KfvCXnag1vtpxVM= -github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= -github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= -github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= -github.com/consensys/gnark-crypto v0.9.1-0.20230105202408-1a7a29904a7c/go.mod h1:CkbdF9hbRidRJYMRzmfX8TMOr95I2pYXRHF18MzRrvA= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/crate-crypto/go-ipa v0.0.0-20220523130400-f11357ae11c7/go.mod h1:gFnFS95y8HstDP6P9pPwzrxOOC5TRDkwbM+ao15ChAI= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= -github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= -github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= -github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= -github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/djherbis/atime v1.1.0/go.mod h1:28OF6Y8s3NQWwacXc5eZTsEsiMzp7LF8MbXE+XJPdBE= -github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/docker v1.6.2/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= -github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= -github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7/go.mod h1:yRkwfj0CBpOGre+TwBsqPV0IH0Pk73e4PXJOeNDboGs= -github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= -github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= -github.com/ethereum/go-ethereum v1.10.26/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= github.com/ethereum/go-ethereum v1.11.5 h1:3M1uan+LAUvdn+7wCEFrcMM4LJTeuxDrPTg/f31a5QQ= github.com/ethereum/go-ethereum v1.11.5/go.mod h1:it7x0DWnTDMfVFdXcU6Ti4KEFQynLHVRarcSlPr0HBo= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= -github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= -github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= -github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/gballet/go-verkle v0.0.0-20220902153445-097bd83b7732/go.mod h1:o/XfIXWi4/GqbQirfRm5uTbXMG5NpqxkxblnbZ+QM9I= -github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= -github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= -github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= -github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= -github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= -github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= -github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= -github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= -github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= -github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= -github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= -github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= -github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0= -github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= -github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -330,201 +109,59 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= -github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM= github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= -github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= -github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= -github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= -github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= -github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= -github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= -github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= -github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/httpexpect/v2 v2.3.1/go.mod h1:ICTf89VBKSD3KB0fsyyHviKF8G8hyepP0dOXJPWz3T0= -github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/jade v1.1.4/go.mod h1:EDqR+ur9piDl6DUgs6qRrlfzmlx/D5UybogqrXvJTBE= github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= -github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA= -github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= -github.com/kataras/blocks v0.0.6/go.mod h1:UK+Iwk0Oxpc0GdoJja7sEildotAUKK1LYeYcVF0COWc= -github.com/kataras/blocks v0.0.7/go.mod h1:UJIU97CluDo0f+zEjbnbkeMRlvYORtmc1304EeyXf4I= -github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/golog v0.1.7/go.mod h1:jOSQ+C5fUqsNSwurB/oAHq1IFSb0KI3l6GMa7xB6dZA= -github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/iris/v12 v12.2.0-beta5/go.mod h1:q26aoWJ0Knx/00iPKg5iizDK7oQQSPjbD8np0XDh6dc= -github.com/kataras/jwt v0.1.8/go.mod h1:Q5j2IkcIHnfwy+oNY3TVWuEBJNw0ADgCcXK9CaZwV4o= -github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/neffos v0.0.20/go.mod h1:srdvC/Uo8mgrApWW0AYtiiLgMbyNPf69qPsd2FhE6MQ= -github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/pio v0.0.10/go.mod h1:gS3ui9xSD+lAUpbYnjOGiQyY7sUMJO+EHpiRzhtZ5no= -github.com/kataras/pio v0.0.11/go.mod h1:38hH6SWH6m4DKSYmRhlrCJ5WItwWgCVrTNU62XZyUvI= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= -github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4= -github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.14.4/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.10/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= -github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= -github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -532,808 +169,241 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= -github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= -github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= -github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mailgun/raymond/v2 v2.0.46/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= -github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= -github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= -github.com/mediocregopher/radix/v3 v3.8.0/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= -github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8mxyjJ0/kQBTElld50= -github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= -github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= -github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= -github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= -github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt/v2 v2.2.1-0.20220330180145-442af02fd36a/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k= -github.com/nats-io/jwt/v2 v2.3.0/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k= -github.com/nats-io/nats-server/v2 v2.8.4/go.mod h1:8zZa+Al3WsESfmgSs98Fi06dRWLH5Bnq90m5bKD/eT4= -github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nats.go v1.15.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= -github.com/nats-io/nats.go v1.16.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= -github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= -github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= -github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= -github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= -github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= -github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= -github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= -github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= -github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shirou/gopsutil/v3 v3.22.8/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI= -github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= -github.com/smartystreets/assertions v1.13.0/go.mod h1:wDmR7qL282YbGsPy6H/yAsesrxfxaaSlJazyFLYVFx8= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= -github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= -github.com/tdewolff/minify/v2 v2.12.1/go.mod h1:p5pwbvNs1ghbFED/ZW1towGsnnWwzvM8iz8l0eURi9g= -github.com/tdewolff/minify/v2 v2.12.4/go.mod h1:h+SRvSIX3kwgwTFOpSckvSxgax3uy8kZTSF1Ojrr3bk= -github.com/tdewolff/parse/v2 v2.6.3/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs= -github.com/tdewolff/parse/v2 v2.6.4/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs= -github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= -github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= -github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= -github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= +github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= -github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o= -github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= -github.com/urfave/cli/v2 v2.10.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo= -github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= -github.com/valyala/fasthttp v1.40.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= -go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/exp v0.0.0-20230206171751-46f607a40771 h1:xP7rWLUr1e1n2xkK5YB4LI0hPEy3LJC6Wk+D4pGlOJg= golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= -golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191126055441-b0650ceb63d9/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= -gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= -gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1343,61 +413,32 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/geth-utils/src/mpt.rs b/geth-utils/src/mpt.rs index 4fe0f3aa4c..6f212f2f54 100644 --- a/geth-utils/src/mpt.rs +++ b/geth-utils/src/mpt.rs @@ -86,7 +86,7 @@ pub fn get_witness(block_no: u64, mods: &[TrieModification], node_url: &str) -> let json = serde_json::to_string(&req).expect("Invalid request"); let c_config = CString::new(json).expect("invalid config"); - let result = unsafe { go::GetMptWitness(c_config.as_ptr() as *const i8) }; + let result = unsafe { go::GetMptWitness(c_config.as_ptr()) }; let c_str = unsafe { CStr::from_ptr(result) }; let json = c_str .to_str() @@ -96,7 +96,7 @@ pub fn get_witness(block_no: u64, mods: &[TrieModification], node_url: &str) -> unsafe { go::FreeString(c_str.as_ptr()) }; // Note: previously this function returned a Vec of Nodes, but now returning a JSON string - // to avoid imporing zkEVM circuit here (that will create a circular dependency). + // to avoid importing zkEVM circuit here (that will create a circular dependency). // TODO: consider defining Node types in another crate. json diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 068341dcdf..2990ac5cbb 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -13,7 +13,7 @@ serde_json = { version = "1.0.66", features = ["unbounded_depth"] } serde = { version = "1.0.130", features = ["derive"] } bus-mapping = { path = "../bus-mapping", features = ["test"] } eth-types = { path = "../eth-types" } -zkevm-circuits = { path = "../zkevm-circuits", features = ["test-circuits"] } +zkevm-circuits = { path = "../zkevm-circuits", features = ["test-circuits", "mock-challenge"] } tokio = { version = "1.13", features = ["macros", "rt-multi-thread"] } url = "2.2.2" pretty_assertions = "1.0.0" @@ -24,6 +24,7 @@ rand_chacha = "0.3" paste = "1.0" rand_xorshift = "0.3.0" rand_core = "0.6.4" +itertools = "0.10" mock = { path = "../mock" } [dev-dependencies] diff --git a/integration-tests/build.rs b/integration-tests/build.rs index b42601fe88..6b937e3bf9 100644 --- a/integration-tests/build.rs +++ b/integration-tests/build.rs @@ -45,7 +45,7 @@ enum BuildError { /// Vec is empty #[error("ArtifactError")] ArtifactError, - /// Functon compile_output failed to encode CompilerInput to Vec + /// Function compile_output failed to encode CompilerInput to Vec #[error("CompileOutputFailure({0:})")] CompileOutputFailure(String), /// Could not convert Vec to CompilerOutput diff --git a/integration-tests/src/bin/gen_blockchain_data.rs b/integration-tests/src/bin/gen_blockchain_data.rs index e9eac2682a..dd4f3ad4ef 100644 --- a/integration-tests/src/bin/gen_blockchain_data.rs +++ b/integration-tests/src/bin/gen_blockchain_data.rs @@ -63,7 +63,7 @@ async fn dump_tx_trace(prov: Provider, receipt: TransactionReceipt, name: .expect("Failed to get transaction debug trace"); let filename = format!("{}_trace.json", name); serde_json::to_writer(&File::create(filename).expect("cannot create file"), &trace) - .expect("Could not seralize trace as json data"); + .expect("Could not serialize trace as json data"); } fn erc20_transfer( diff --git a/integration-tests/src/integration_test_circuits.rs b/integration-tests/src/integration_test_circuits.rs index 639143f738..3a44ffa6f4 100644 --- a/integration-tests/src/integration_test_circuits.rs +++ b/integration-tests/src/integration_test_circuits.rs @@ -8,10 +8,13 @@ use halo2_proofs::{ self, circuit::Value, dev::{CellValue, MockProver}, - halo2curves::bn256::{Bn256, Fr, G1Affine}, + halo2curves::{ + bn256::{Bn256, Fr, G1Affine}, + pairing::Engine, + }, plonk::{ create_proof, keygen_pk, keygen_vk, permutation::Assembly, verify_proof, Circuit, - ProvingKey, + ConstraintSystem, ProvingKey, }, poly::{ commitment::ParamsProver, @@ -22,6 +25,7 @@ use halo2_proofs::{ }, }, }; +use itertools::Itertools; use lazy_static::lazy_static; use mock::TestContext; use rand_chacha::rand_core::SeedableRng; @@ -37,17 +41,19 @@ use zkevm_circuits::{ pi_circuit::TestPiCircuit, root_circuit::{ compile, Config, EvmTranscript, NativeLoader, PoseidonTranscript, RootCircuit, Shplonk, + SnarkWitness, UserChallenge, }, state_circuit::TestStateCircuit, super_circuit::SuperCircuit, tx_circuit::TestTxCircuit, util::SubCircuit, - witness::{block_convert, Block}, + witness::{block_convert, chunk_convert, Block, Chunk}, }; /// TEST_MOCK_RANDOMNESS const TEST_MOCK_RANDOMNESS: u64 = 0x100; - +/// +const TOTAL_CHUNKS: usize = 1; /// MAX_TXS const MAX_TXS: usize = 4; /// MAX_WITHDRAWALS @@ -66,8 +72,11 @@ const MAX_EVM_ROWS: usize = 10000; const MAX_EXP_STEPS: usize = 1000; const MAX_KECCAK_ROWS: usize = 38000; +/// MAX_VERTICAL_CIRCUIT_ROWS +const MAX_VERTICAL_CIRCUIT_ROWS: usize = 0; const CIRCUITS_PARAMS: FixedCParams = FixedCParams { + total_chunks: TOTAL_CHUNKS, max_rws: MAX_RWS, max_txs: MAX_TXS, max_withdrawals: MAX_WITHDRAWALS, @@ -77,6 +86,7 @@ const CIRCUITS_PARAMS: FixedCParams = FixedCParams { max_evm_rows: MAX_EVM_ROWS, max_exp_steps: MAX_EXP_STEPS, max_keccak_rows: MAX_KECCAK_ROWS, + max_vertical_circuit_rows: MAX_VERTICAL_CIRCUIT_ROWS, }; const EVM_CIRCUIT_DEGREE: u32 = 18; @@ -161,7 +171,7 @@ fn test_actual_circuit>( let mut transcript = PoseidonTranscript::new(Vec::new()); - // change instace to slice + // change instance to slice let instance: Vec<&[Fr]> = instance.iter().map(|v| v.as_slice()).collect(); log::info!("gen circuit proof"); @@ -211,7 +221,7 @@ fn test_actual_root_circuit>( let mut transcript = EvmTranscript::<_, NativeLoader, _, _>::new(vec![]); - // change instace to slice + // change instance to slice let instance: Vec<&[Fr]> = instance.iter().map(|v| v.as_slice()).collect(); log::info!("gen root circuit proof"); @@ -283,8 +293,8 @@ impl + Circuit> IntegrationTest { match self.key.clone() { Some(key) => key, None => { - let block = new_empty_block(); - let circuit = C::new_from_block(&block); + let (block, chunk) = new_empty_block_chunk(); + let circuit = C::new_from_block(&block, &chunk); let general_params = get_general_params(self.degree); let verifying_key = @@ -304,8 +314,8 @@ impl + Circuit> IntegrationTest { let params = get_general_params(self.degree); let pk = self.get_key(); - let block = new_empty_block(); - let circuit = C::new_from_block(&block); + let (block, chunk) = new_empty_block_chunk(); + let circuit = C::new_from_block(&block, &chunk); let instance = circuit.instance(); let protocol = compile( @@ -318,8 +328,12 @@ impl + Circuit> IntegrationTest { let circuit = RootCircuit::>::new( ¶ms, &protocol, - Value::unknown(), - Value::unknown(), + vec![SnarkWitness::new( + &protocol, + Value::unknown(), + Value::unknown(), + )], + None, ) .unwrap(); @@ -348,10 +362,26 @@ impl + Circuit> IntegrationTest { let fixed = mock_prover.fixed(); if let Some(prev_fixed) = self.fixed.clone() { - assert!( - fixed.eq(&prev_fixed), - "circuit fixed columns are not constant for different witnesses" - ); + fixed + .iter() + .enumerate() + .zip_eq(prev_fixed.iter()) + .for_each(|((index, col1), col2)| { + if !col1.eq(col2) { + println!("on column index {} not equal", index); + col1.iter().enumerate().zip_eq(col2.iter()).for_each( + |((index, cellv1), cellv2)| { + assert!( + cellv1.eq(cellv2), + "cellv1 {:?} != cellv2 {:?} on index {}", + cellv1, + cellv2, + index + ); + }, + ); + } + }); } else { self.fixed = Some(fixed.clone()); } @@ -373,6 +403,24 @@ impl + Circuit> IntegrationTest { match self.root_fixed.clone() { Some(prev_fixed) => { + fixed.iter().enumerate().zip_eq(prev_fixed.iter()).for_each( + |((index, col1), col2)| { + if !col1.eq(col2) { + println!("on column index {} not equal", index); + col1.iter().enumerate().zip_eq(col2.iter()).for_each( + |((index, cellv1), cellv2)| { + assert!( + cellv1.eq(cellv2), + "cellv1 {:?} != cellv2 {:?} on index {}", + cellv1, + cellv2, + index + ); + }, + ); + } + }, + ); assert!( fixed.eq(&prev_fixed), "root circuit fixed columns are not constant for different witnesses" @@ -414,8 +462,9 @@ impl + Circuit> IntegrationTest { block_tag, ); let mut block = block_convert(&builder).unwrap(); + let chunk = chunk_convert(&block, &builder).unwrap().remove(0); block.randomness = Fr::from(TEST_MOCK_RANDOMNESS); - let circuit = C::new_from_block(&block); + let circuit = C::new_from_block(&block, &chunk); let instance = circuit.instance(); #[allow(clippy::collapsible_else_if)] @@ -429,6 +478,11 @@ impl + Circuit> IntegrationTest { .with_num_instance(instance.iter().map(|instance| instance.len()).collect()), ); + // get chronological_rwtable and byaddr_rwtable columns index + let mut cs = ConstraintSystem::<::Fr>::default(); + let config = SuperCircuit::configure(&mut cs); + let rwtable_columns = config.get_rwtable_columns(); + let proof = { let mut proof_cache = PROOF_CACHE.lock().await; if let Some(proof) = proof_cache.get(&proof_name) { @@ -444,11 +498,19 @@ impl + Circuit> IntegrationTest { }; log::info!("root circuit new"); + let user_challenge = &UserChallenge { + column_indexes: rwtable_columns, + num_challenges: 2, // alpha, gamma + }; let root_circuit = RootCircuit::>::new( ¶ms, &protocol, - Value::known(&instance), - Value::known(&proof), + vec![SnarkWitness::new( + &protocol, + Value::known(&instance), + Value::known(&proof), + )], + Some(user_challenge), ) .unwrap(); @@ -483,16 +545,17 @@ impl + Circuit> IntegrationTest { } } -fn new_empty_block() -> Block { +fn new_empty_block_chunk() -> (Block, Chunk) { let block: GethData = TestContext::<0, 0>::new(None, |_| {}, |_, _| {}, |b, _| b) .unwrap() .into(); - let mut builder = BlockData::new_from_geth_data_with_params(block.clone(), CIRCUITS_PARAMS) - .new_circuit_input_builder(); - builder + let builder = BlockData::new_from_geth_data_with_params(block.clone(), CIRCUITS_PARAMS) + .new_circuit_input_builder() .handle_block(&block.eth_block, &block.geth_traces) .unwrap(); - block_convert(&builder).unwrap() + let block = block_convert(&builder).unwrap(); + let chunk = chunk_convert(&block, &builder).unwrap().remove(0); + (block, chunk) } fn get_general_params(degree: u32) -> ParamsKZG { diff --git a/integration-tests/tests/circuit_input_builder.rs b/integration-tests/tests/circuit_input_builder.rs index 339f243d02..e68f2eb67a 100644 --- a/integration-tests/tests/circuit_input_builder.rs +++ b/integration-tests/tests/circuit_input_builder.rs @@ -16,6 +16,7 @@ async fn test_circuit_input_builder_block(block_num: u64) { let cli = BuilderClient::new( cli, FixedCParams { + total_chunks: 1, max_rws: 16384, max_txs: 1, max_withdrawals: 1, @@ -25,6 +26,7 @@ async fn test_circuit_input_builder_block(block_num: u64) { max_evm_rows: 0, max_exp_steps: 1000, max_keccak_rows: 0, + max_vertical_circuit_rows: 0, }, ) .await @@ -73,7 +75,7 @@ macro_rules! declare_tests { } // This test builds the complete circuit inputs for the block where 1 ETH is -// transfered. +// transferred. declare_tests!(test_circuit_input_builder_block_transfer_0, "Transfer 0"); // This test builds the complete circuit inputs for the block where the Greeter // contract is deployed. diff --git a/mock/src/test_ctx.rs b/mock/src/test_ctx.rs index 23c3e38218..164b27e589 100644 --- a/mock/src/test_ctx.rs +++ b/mock/src/test_ctx.rs @@ -80,7 +80,7 @@ pub struct TestContext { /// Account list pub accounts: [Account; NACC], /// history hashes contains most recent 256 block hashes in history, where - /// the lastest one is at history_hashes[history_hashes.len() - 1]. + /// the latest one is at history_hashes[history_hashes.len() - 1]. pub history_hashes: Vec, /// Block from geth pub eth_block: eth_types::Block, @@ -172,7 +172,7 @@ impl TestContext { } } -/// Collection of helper functions which contribute to specific rutines on the +/// Collection of helper functions which contribute to specific routines on the /// builder pattern used to construct [`TestContext`]s. pub mod helpers { use super::*; diff --git a/mock/src/transaction.rs b/mock/src/transaction.rs index 1184d418d4..e960181b82 100644 --- a/mock/src/transaction.rs +++ b/mock/src/transaction.rs @@ -133,8 +133,8 @@ pub struct MockTransaction { pub s: Option, pub transaction_type: U64, pub access_list: AccessList, - pub max_priority_fee_per_gas: Word, - pub max_fee_per_gas: Word, + pub max_priority_fee_per_gas: Option, + pub max_fee_per_gas: Option, pub chain_id: Word, pub invalid: bool, } @@ -158,8 +158,8 @@ impl Default for MockTransaction { s: None, transaction_type: U64::zero(), access_list: AccessList::default(), - max_priority_fee_per_gas: Word::zero(), - max_fee_per_gas: Word::zero(), + max_priority_fee_per_gas: None, + max_fee_per_gas: None, chain_id: *MOCK_CHAIN_ID, invalid: false, } @@ -185,8 +185,8 @@ impl From for Transaction { s: mock.s.unwrap_or_default(), transaction_type: Some(mock.transaction_type), access_list: Some(mock.access_list), - max_priority_fee_per_gas: Some(mock.max_priority_fee_per_gas), - max_fee_per_gas: Some(mock.max_fee_per_gas), + max_priority_fee_per_gas: mock.max_priority_fee_per_gas, + max_fee_per_gas: mock.max_fee_per_gas, chain_id: Some(mock.chain_id), other: OtherFields::default(), } @@ -289,13 +289,13 @@ impl MockTransaction { /// Set max_priority_fee_per_gas field for the MockTransaction. pub fn max_priority_fee_per_gas(&mut self, max_priority_fee_per_gas: Word) -> &mut Self { - self.max_priority_fee_per_gas = max_priority_fee_per_gas; + self.max_priority_fee_per_gas = Some(max_priority_fee_per_gas); self } /// Set max_fee_per_gas field for the MockTransaction. pub fn max_fee_per_gas(&mut self, max_fee_per_gas: Word) -> &mut Self { - self.max_fee_per_gas = max_fee_per_gas; + self.max_fee_per_gas = Some(max_fee_per_gas); self } diff --git a/rust-toolchain b/rust-toolchain index b6ce6a50ba..c5f610378b 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2023-04-24 +nightly-2024-02-14 diff --git a/testool/README.md b/testool/README.md index 4a619374c5..0f389d8ad6 100644 --- a/testool/README.md +++ b/testool/README.md @@ -102,7 +102,7 @@ Sometimes there are some files or specific tests that we want to disable at all. When the command line parameter `--report` is defined, it automatically: - After the execution, a two files are created in the `report` folder. They are - - `-.hml` with the browseable results of the execution. + - `-.hml` with the browsable results of the execution. - `-.csv` with the raw results of the execution - The HTML file also contains the diff with the previous result. The previous result file is the more recent csv file with different commit from the current one diff --git a/testool/src/abi.rs b/testool/src/abi.rs index e3e9287bbb..34e1699253 100644 --- a/testool/src/abi.rs +++ b/testool/src/abi.rs @@ -15,7 +15,7 @@ pub fn encode_funccall(spec: &str) -> Result { let func_name = func_name_params[0]; let func_params = &func_name_params[1..func_name_params.len() - 1]; - // transform func_params and args into the appropiate types + // transform func_params and args into the appropriate types let map_type = |t| match t { "uint" => ParamType::Uint(256), diff --git a/testool/src/compiler.rs b/testool/src/compiler.rs index 53296cab3c..7f03d039f4 100644 --- a/testool/src/compiler.rs +++ b/testool/src/compiler.rs @@ -47,7 +47,6 @@ impl Cache { let entry = format!("{}={}\n", hex::encode(code_hash), hex::encode(&bytecode)); std::fs::OpenOptions::new() .read(true) - .write(true) .create(true) .append(true) .open(&self.path)? diff --git a/testool/src/main.rs b/testool/src/main.rs index e94bffff9d..1687af80fb 100644 --- a/testool/src/main.rs +++ b/testool/src/main.rs @@ -109,7 +109,7 @@ fn go() -> Result<()> { env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init(); log::info!("Using suite '{}'", args.suite); - log::info!("Parsing and compliling tests..."); + log::info!("Parsing and compiling tests..."); let compiler = Compiler::new(true, Some(PathBuf::from(CODEHASH_FILE)))?; let suite = config.suite(&args.suite)?.clone(); let state_tests = load_statetests_suite(&suite.path, config, compiler)?; diff --git a/testool/src/statetest/mod.rs b/testool/src/statetest.rs similarity index 100% rename from testool/src/statetest/mod.rs rename to testool/src/statetest.rs diff --git a/testool/src/statetest/executor.rs b/testool/src/statetest/executor.rs index 1a6fa800b2..0eff2d1452 100644 --- a/testool/src/statetest/executor.rs +++ b/testool/src/statetest/executor.rs @@ -1,14 +1,11 @@ use super::{AccountMatch, StateTest, StateTestResult}; -use crate::config::TestSuite; +use crate::{config::TestSuite, utils::ETH_CHAIN_ID}; use bus_mapping::{ circuit_input_builder::{CircuitInputBuilder, FixedCParams}, mock::BlockData, }; use eth_types::{geth_types, Address, Bytes, Error, GethExecTrace, U256, U64}; -use ethers_core::{ - k256::ecdsa::SigningKey, - types::{transaction::eip2718::TypedTransaction, TransactionRequest, Withdrawal}, -}; +use ethers_core::{k256::ecdsa::SigningKey, types::Withdrawal, utils::keccak256}; use ethers_signers::{LocalWallet, Signer}; use external_tracer::TraceConfig; use halo2_proofs::{dev::MockProver, halo2curves::bn256::Fr}; @@ -17,7 +14,7 @@ use thiserror::Error; use zkevm_circuits::{ super_circuit::SuperCircuit, test_util::{CircuitTestBuilder, CircuitTestError}, - witness::Block, + witness::{Block, Chunk}, }; #[derive(PartialEq, Eq, Error, Debug)] @@ -138,28 +135,22 @@ fn check_post( } fn into_traceconfig(st: StateTest) -> (String, TraceConfig, StateTestResult) { - let chain_id = 1; - let wallet = LocalWallet::from_str(&hex::encode(st.secret_key.0)).unwrap(); - let mut tx = TransactionRequest::new() - .chain_id(chain_id) - .from(st.from) - .nonce(st.nonce) - .value(st.value) - .data(st.data.clone()) - .gas(st.gas_limit) - .gas_price(st.gas_price); - - if let Some(to) = st.to { - tx = tx.to(to); - } - let tx: TypedTransaction = tx.into(); + let tx_type = st.tx_type(); + let tx = st.build_tx(); + + let wallet = LocalWallet::from_str(&hex::encode(&st.secret_key.0)).unwrap(); + let rlp_unsigned = tx.rlp().to_vec(); let sig = wallet.sign_transaction_sync(&tx).unwrap(); + let v = st.normalize_sig_v(sig.v); + let rlp_signed = tx.rlp_signed(&sig).to_vec(); + let tx_hash = keccak256(tx.rlp_signed(&sig)); + let accounts = st.pre; ( st.id, TraceConfig { - chain_id: U256::one(), + chain_id: U256::from(ETH_CHAIN_ID), history_hashes: vec![U256::from_big_endian(st.env.previous_hash.as_bytes())], block_constants: geth_types::BlockConstants { coinbase: st.env.current_coinbase, @@ -171,21 +162,25 @@ fn into_traceconfig(st: StateTest) -> (String, TraceConfig, StateTestResult) { }, transactions: vec![geth_types::Transaction { + tx_type, from: st.from, to: st.to, nonce: U64::from(st.nonce), value: st.value, gas_limit: U64::from(st.gas_limit), gas_price: st.gas_price, - gas_fee_cap: U256::zero(), - gas_tip_cap: U256::zero(), + gas_fee_cap: st.max_fee_per_gas, + gas_tip_cap: st.max_priority_fee_per_gas, call_data: st.data, - access_list: None, - v: sig.v, + access_list: st.access_list, + v, r: sig.r, s: sig.s, + rlp_bytes: rlp_signed, + rlp_unsigned_bytes: rlp_unsigned, + hash: tx_hash.into(), }], - accounts: st.pre.into_iter().collect(), + accounts, ..Default::default() }, st.result, @@ -324,10 +319,11 @@ pub fn run_test( eth_block: eth_block.clone(), }; - let mut builder; + let builder; if !circuits_config.super_circuit { let circuits_params = FixedCParams { + total_chunks: 1, max_txs: 1, max_withdrawals: 1, max_rws: 55000, @@ -337,18 +333,20 @@ pub fn run_test( max_evm_rows: 0, max_exp_steps: 5000, max_keccak_rows: 0, + max_vertical_circuit_rows: 0, }; let block_data = BlockData::new_from_geth_data_with_params(geth_data, circuits_params); - builder = block_data.new_circuit_input_builder(); - builder + builder = block_data + .new_circuit_input_builder() .handle_block(ð_block, &geth_traces) .map_err(|err| StateTestError::CircuitInput(err.to_string()))?; let block: Block = zkevm_circuits::evm_circuit::witness::block_convert(&builder).unwrap(); - - CircuitTestBuilder::<1, 1>::new_from_block(block) + let chunks: Vec> = + zkevm_circuits::evm_circuit::witness::chunk_convert(&block, &builder).unwrap(); + CircuitTestBuilder::<1, 1>::new_from_block(block, chunks) .run_with_result() .map_err(|err| match err { CircuitTestError::VerificationFailed { reasons, .. } => { @@ -366,6 +364,7 @@ pub fn run_test( geth_data.sign(&wallets); let circuits_params = FixedCParams { + total_chunks: 1, max_txs: 1, max_withdrawals: 1, max_calldata: 32, @@ -375,11 +374,15 @@ pub fn run_test( max_bytecode: 512, max_evm_rows: 0, max_keccak_rows: 0, + max_vertical_circuit_rows: 0, }; - let (k, circuit, instance, _builder) = + let (k, mut circuits, mut instances, _builder) = SuperCircuit::::build(geth_data, circuits_params, Fr::from(0x100)).unwrap(); builder = _builder; + let circuit = circuits.remove(0); + let instance = instances.remove(0); + let prover = MockProver::run(k, &circuit, instance).unwrap(); prover .verify() diff --git a/testool/src/statetest/json.rs b/testool/src/statetest/json.rs index b60c5157f1..fc357adb9c 100644 --- a/testool/src/statetest/json.rs +++ b/testool/src/statetest/json.rs @@ -9,8 +9,6 @@ use ethers_core::{k256::ecdsa::SigningKey, utils::secret_key_to_address}; use serde::Deserialize; use std::collections::{BTreeMap, HashMap}; -use serde_json::value::Value; - fn default_block_base_fee() -> String { DEFAULT_BASE_FEE.to_string() } @@ -71,8 +69,11 @@ struct JsonStateTest { #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] struct Transaction { + access_list: Option, data: Vec, gas_limit: Vec, + max_priority_fee_per_gas: Option, + max_fee_per_gas: Option, gas_price: String, nonce: String, secret_key: String, @@ -109,8 +110,7 @@ impl<'a> JsonStateTestBuilder<'a> { /// generates `StateTest` vectors from a ethereum josn test specification pub fn load_json(&mut self, path: &str, source: &str) -> Result> { let mut state_tests = Vec::new(); - let tests: HashMap = - serde_json::from_str(&strip_json_comments(source))?; + let tests: HashMap = serde_json::from_str(source)?; for (test_name, test) in tests { let env = Self::parse_env(&test.env)?; @@ -120,13 +120,32 @@ impl<'a> JsonStateTestBuilder<'a> { let secret_key = parse::parse_bytes(&test.transaction.secret_key)?; let from = secret_key_to_address(&SigningKey::from_slice(&secret_key)?); let nonce = parse::parse_u64(&test.transaction.nonce)?; - let gas_price = parse::parse_u256(&test.transaction.gas_price)?; + + let max_priority_fee_per_gas = test + .transaction + .max_priority_fee_per_gas + .map_or(Ok(None), |s| parse::parse_u256(&s).map(Some))?; + let max_fee_per_gas = test + .transaction + .max_fee_per_gas + .map_or(Ok(None), |s| parse::parse_u256(&s).map(Some))?; + + // Set gas price to `min(max_priority_fee_per_gas + base_fee, max_fee_per_gas)` for + // EIP-1559 transaction. + // + let gas_price = parse::parse_u256(&test.transaction.gas_price).unwrap_or_else(|_| { + max_fee_per_gas + .unwrap() + .min(max_priority_fee_per_gas.unwrap() + env.current_base_fee) + }); + + let access_list = &test.transaction.access_list; let data_s: Vec<_> = test .transaction .data .iter() - .map(|item| parse::parse_calldata(self.compiler, item)) + .map(|item| parse::parse_calldata(self.compiler, item, access_list)) .collect::>()?; let gas_limit_s: Vec<_> = test @@ -167,7 +186,7 @@ impl<'a> JsonStateTestBuilder<'a> { } } - for (idx_data, data) in data_s.iter().enumerate() { + for (idx_data, calldata) in data_s.iter().enumerate() { for (idx_gas, gas_limit) in gas_limit_s.iter().enumerate() { for (idx_value, value) in value_s.iter().enumerate() { for (data_refs, gas_refs, value_refs, result) in &expects { @@ -193,10 +212,13 @@ impl<'a> JsonStateTestBuilder<'a> { to, secret_key: secret_key.clone(), nonce, + max_priority_fee_per_gas, + max_fee_per_gas, gas_price, gas_limit: *gas_limit, value: *value, - data: data.0.clone(), + data: calldata.data.clone(), + access_list: calldata.access_list.clone(), exception: false, }); } @@ -313,29 +335,10 @@ impl<'a> JsonStateTestBuilder<'a> { } } -fn strip_json_comments(json: &str) -> String { - fn strip(value: Value) -> Value { - use Value::*; - match value { - Array(vec) => Array(vec.into_iter().map(strip).collect()), - Object(map) => Object( - map.into_iter() - .filter(|(k, _)| !k.starts_with("//")) - .map(|(k, v)| (k, strip(v))) - .collect(), - ), - _ => value, - } - } - - let value: Value = serde_json::from_str(json).unwrap(); - strip(value).to_string() -} - #[cfg(test)] mod test { use super::*; - use eth_types::{Bytes, H256}; + use eth_types::{address, AccessList, AccessListItem, Bytes, H256}; use std::{collections::HashMap, str::FromStr}; const JSON: &str = r#" @@ -381,6 +384,15 @@ mod test { } }, "transaction" : { + "accessList" : [ + { + "address" : "0x009e7baea6a6c7c4c2dfeb977efac326af552d87", + "storageKeys" : [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001" + ] + } + ], "data" : [ "0x6001", "0x6002" @@ -430,9 +442,24 @@ mod test { )?), gas_limit: 400000, gas_price: U256::from(10u64), + max_fee_per_gas: None, + max_priority_fee_per_gas: None, nonce: 0, value: U256::from(100000u64), data: Bytes::from(hex::decode("6001")?), + access_list: Some(AccessList(vec![AccessListItem { + address: address!("0x009e7baea6a6c7c4c2dfeb977efac326af552d87"), + storage_keys: vec![ + H256::from_str( + "0x0000000000000000000000000000000000000000000000000000000000000000", + ) + .unwrap(), + H256::from_str( + "0x0000000000000000000000000000000000000000000000000000000000000001", + ) + .unwrap(), + ], + }])), pre: BTreeMap::from([( acc095e, Account { @@ -460,13 +487,4 @@ mod test { Ok(()) } - - #[test] - fn test_strip() { - let original = r#"{"//a":"a1","b":[{"c":"c1","//d":"d1"}]}"#; - let expected = r#"{"b":[{"c":"c1"}]}"#; - - let stripped = strip_json_comments(original); - assert_eq!(expected, stripped); - } } diff --git a/testool/src/statetest/parse.rs b/testool/src/statetest/parse.rs index 0576cc8d35..7f41973755 100644 --- a/testool/src/statetest/parse.rs +++ b/testool/src/statetest/parse.rs @@ -1,15 +1,52 @@ -use std::collections::HashMap; - use crate::{abi, Compiler}; - use anyhow::{bail, Context, Result}; -use eth_types::{Address, Bytes, H256, U256}; +use eth_types::{address, AccessList, AccessListItem, Address, Bytes, H256, U256}; use log::debug; use once_cell::sync::Lazy; use regex::Regex; +use serde::Deserialize; +use std::{collections::HashMap, str::FromStr}; type Label = String; +/// Raw access list to parse +pub type RawAccessList = Vec; + +/// Raw access list item to parse +#[derive(Clone, Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RawAccessListItem { + address: String, + storage_keys: Vec, +} + +impl RawAccessListItem { + pub fn new(address: String, storage_keys: Vec) -> Self { + Self { + address, + storage_keys, + } + } +} + +/// parsed calldata +#[derive(Debug)] +pub struct Calldata { + pub data: Bytes, + pub label: Option

, pub gas_limit: u64, + pub max_priority_fee_per_gas: Option, + pub max_fee_per_gas: Option, pub gas_price: U256, pub nonce: u64, pub value: U256, pub data: Bytes, + pub access_list: Option, pub pre: BTreeMap, pub result: StateTestResult, pub exception: bool, @@ -74,6 +89,7 @@ impl std::fmt::Display for StateTest { format!("{k} :") }; let max_len = max_len - k.len(); + let v = v.chars().collect::>(); for i in 0..=v.len() / max_len { if i == 0 && !k.is_empty() { text.push_str(&k); @@ -81,7 +97,11 @@ impl std::fmt::Display for StateTest { let padding: String = " ".repeat(k.len()); text.push_str(&padding); } - text.push_str(&v[i * max_len..std::cmp::min((i + 1) * max_len, v.len())]); + text.push_str( + &v[i * max_len..std::cmp::min((i + 1) * max_len, v.len())] + .iter() + .collect::(), + ); text.push('\n'); } text @@ -108,10 +128,19 @@ impl std::fmt::Display for StateTest { table.add_row(row!["from", format!("{:?}", self.from)]); table.add_row(row!["to", format!("{:?}", self.to)]); table.add_row(row!["gas_limit", format!("{}", self.gas_limit)]); + table.add_row(row![ + "max_priority_fee_per_gas", + format!("{:?}", self.max_priority_fee_per_gas) + ]); + table.add_row(row![ + "max_fee_per_gas", + format!("{:?}", self.max_fee_per_gas) + ]); table.add_row(row!["gas_price", format!("{}", self.gas_price)]); table.add_row(row!["nonce", format!("{}", self.nonce)]); table.add_row(row!["value", format!("{}", self.value)]); table.add_row(row!["data", format(&hex::encode(&self.data), "")]); + table.add_row(row!["access_list", format!("{:?}", self.access_list)]); table.add_row(row!["exception", self.exception]); let mut addrs: Vec<_> = self.pre.keys().collect(); @@ -273,10 +302,13 @@ impl StateTest { from, to, gas_limit, + max_priority_fee_per_gas: None, + max_fee_per_gas: None, gas_price: U256::one(), nonce: 0, value, data: data.into(), + access_list: None, pre, result: HashMap::new(), exception: false, @@ -284,4 +316,88 @@ impl StateTest { Ok(state_test) } + + /// Parse transaction type. + pub fn tx_type(&self) -> TxType { + if self.max_priority_fee_per_gas.is_some() { + // For EIP-1559, both maxPriorityFeePerGas and maxFeePerGas must + // exist, and accessList should exist but may be empty. + assert!(self.max_fee_per_gas.is_some()); + assert!(self.access_list.is_some()); + + TxType::Eip1559 + } else if self.access_list.is_some() { + TxType::Eip2930 + } else { + // Set transaction type to EIP-155 as default. + TxType::Eip155 + } + } + + /// Normalize the signature back to 0/1. + pub fn normalize_sig_v(&self, v: u64) -> u64 { + match self.tx_type() { + TxType::Eip1559 | TxType::Eip2930 => { + // + if v > 1 { + v - ETH_CHAIN_ID * 2 - 35 + } else { + v + } + } + _ => v, + } + } + + /// Build a transaction from this test case. + pub fn build_tx(&self) -> TypedTransaction { + match self.tx_type() { + TxType::Eip1559 => self.build_eip1559_tx(), + TxType::Eip2930 => self.build_eip2930_tx(), + _ => self.build_normal_tx_request().into(), + } + } + + fn build_eip1559_tx(&self) -> TypedTransaction { + let mut request = Eip1559TransactionRequest::new() + .chain_id(ETH_CHAIN_ID) + .from(self.from) + .nonce(self.nonce) + .value(self.value) + .data(self.data.clone()) + .gas(self.gas_limit) + .access_list(self.access_list.clone().unwrap()) + .max_priority_fee_per_gas(self.max_priority_fee_per_gas.unwrap()) + .max_fee_per_gas(self.max_fee_per_gas.unwrap()); + + if let Some(to) = self.to { + request = request.to(to); + } + + request.into() + } + + fn build_eip2930_tx(&self) -> TypedTransaction { + let request = self.build_normal_tx_request(); + request + .with_access_list(self.access_list.clone().unwrap()) + .into() + } + + fn build_normal_tx_request(&self) -> TransactionRequest { + let mut request = TransactionRequest::new() + .chain_id(ETH_CHAIN_ID) + .from(self.from) + .nonce(self.nonce) + .value(self.value) + .data(self.data.clone()) + .gas(self.gas_limit) + .gas_price(self.gas_price); + + if let Some(to) = self.to { + request = request.to(to); + } + + request + } } diff --git a/testool/src/statetest/yaml.rs b/testool/src/statetest/yaml.rs index 3fe0b2eba3..ae4bb6623c 100644 --- a/testool/src/statetest/yaml.rs +++ b/testool/src/statetest/yaml.rs @@ -3,18 +3,16 @@ use super::{ spec::{AccountMatch, Env, StateTest, DEFAULT_BASE_FEE}, }; use crate::{utils::MainnetFork, Compiler}; -use anyhow::{bail, Context, Result}; +use anyhow::{anyhow, bail, Context, Result}; use eth_types::{geth_types::Account, Address, Bytes, H256, U256}; use ethers_core::{k256::ecdsa::SigningKey, utils::secret_key_to_address}; use std::{ - collections::{BTreeMap, HashMap}, + collections::{BTreeMap, HashMap, HashSet}, convert::TryInto, str::FromStr, }; use yaml_rust::Yaml; -type Label = String; - #[derive(Debug, Clone)] enum Ref { Any, @@ -76,7 +74,7 @@ impl<'a> YamlStateTestBuilder<'a> { // parse pre (account states before executing the transaction) let pre: BTreeMap = self - .parse_accounts(&yaml_test["pre"])? + .parse_accounts(&yaml_test["pre"], None)? .into_iter() .map(|(addr, account)| (addr, account.try_into().expect("unable to parse account"))) .collect(); @@ -104,12 +102,19 @@ impl<'a> YamlStateTestBuilder<'a> { .map(Self::parse_u256) .collect::>()?; - let max_fee_per_gas = Self::parse_u256(&yaml_transaction["maxFeePerGas"]) - .unwrap_or_else(|_| U256::zero()); - let gas_price = - Self::parse_u256(&yaml_transaction["gasPrice"]).unwrap_or(max_fee_per_gas); + let max_priority_fee_per_gas = + Self::parse_u256(&yaml_transaction["maxPriorityFeePerGas"]).ok(); + let max_fee_per_gas = Self::parse_u256(&yaml_transaction["maxFeePerGas"]).ok(); + + // Set gas price to `min(max_priority_fee_per_gas + base_fee, max_fee_per_gas)` for + // EIP-1559 transaction. + // + let gas_price = Self::parse_u256(&yaml_transaction["gasPrice"]).unwrap_or_else(|_| { + max_fee_per_gas + .unwrap() + .min(max_priority_fee_per_gas.unwrap() + env.current_base_fee) + }); - // TODO handle maxPriorityFeePerGas & maxFeePerGas let nonce = Self::parse_u64(&yaml_transaction["nonce"])?; let to = Self::parse_to_address(&yaml_transaction["to"])?; let secret_key = Self::parse_bytes(&yaml_transaction["secretKey"])?; @@ -143,7 +148,10 @@ impl<'a> YamlStateTestBuilder<'a> { let data_refs = Self::parse_refs(&expect["indexes"]["data"])?; let gas_refs = Self::parse_refs(&expect["indexes"]["gas"])?; let value_refs = Self::parse_refs(&expect["indexes"]["value"])?; - let result = self.parse_accounts(&expect["result"])?; + + // Pass the account addresses before transaction as expected for result. + let expected_addresses = pre.keys().collect(); + let result = self.parse_accounts(&expect["result"], Some(&expected_addresses))?; if MainnetFork::in_network_range(&networks)? { expects.push((exception, data_refs, gas_refs, value_refs, result)); @@ -152,14 +160,14 @@ impl<'a> YamlStateTestBuilder<'a> { // generate all the tests defined in the transaction by generating product of // data x gas x value - for (idx_data, data) in data_s.iter().enumerate() { + for (idx_data, calldata) in data_s.iter().enumerate() { for (idx_gas, gas_limit) in gas_limit_s.iter().enumerate() { for (idx_value, value) in value_s.iter().enumerate() { // find the first result that fulfills the pattern for (exception, data_refs, gas_refs, value_refs, result) in &expects { // check if this result can be applied to the current test let mut data_label = String::new(); - if let Some(label) = &data.1 { + if let Some(label) = &calldata.label { if !data_refs.contains_label(label) { continue; } @@ -189,10 +197,13 @@ impl<'a> YamlStateTestBuilder<'a> { secret_key: secret_key.clone(), to, gas_limit: *gas_limit, + max_priority_fee_per_gas, + max_fee_per_gas, gas_price, nonce, value: *value, - data: data.0.clone(), + data: calldata.data.clone(), + access_list: calldata.access_list.clone(), exception: *exception, }); break; @@ -210,7 +221,7 @@ impl<'a> YamlStateTestBuilder<'a> { Ok(Env { current_base_fee: Self::parse_u256(&yaml["currentBaseFee"]) .unwrap_or_else(|_| U256::from(DEFAULT_BASE_FEE)), - current_coinbase: Self::parse_address(&yaml["currentCoinbase"])?, + current_coinbase: Self::parse_address(&yaml["currentCoinbase"], None)?, current_difficulty: Self::parse_u256(&yaml["currentDifficulty"])?, current_gas_limit: Self::parse_u64(&yaml["currentGasLimit"])?, current_number: Self::parse_u64(&yaml["currentNumber"])?, @@ -220,7 +231,11 @@ impl<'a> YamlStateTestBuilder<'a> { } /// parse a vector of address=>(storage,balance,code,nonce) entry - fn parse_accounts(&mut self, yaml: &Yaml) -> Result> { + fn parse_accounts( + &mut self, + yaml: &Yaml, + expected_addresses: Option<&HashSet<&Address>>, + ) -> Result> { let mut accounts = HashMap::new(); for (address, account) in yaml.as_hash().context("parse_hash")?.iter() { let acc_storage = &account["storage"]; @@ -235,7 +250,7 @@ impl<'a> YamlStateTestBuilder<'a> { } } - let address = Self::parse_address(address)?; + let address = Self::parse_address(address, expected_addresses)?; let account = AccountMatch { address, balance: if acc_balance.is_badvalue() { @@ -289,22 +304,43 @@ impl<'a> YamlStateTestBuilder<'a> { tags } /// returns the element as an address - fn parse_address(yaml: &Yaml) -> Result
{ - match yaml { - Yaml::Real(real) => Ok(Address::from_str(real)?), - Yaml::Integer(int) => { - let hex = format!("{int:0>40}"); - Ok(Address::from_slice(&hex::decode(hex)?)) + fn parse_address( + yaml: &Yaml, + expected_addresses: Option<&HashSet<&Address>>, + ) -> Result
{ + if let Some(as_str) = yaml.as_str() { + parse::parse_address(as_str) + } else if let Some(as_i64) = yaml.as_i64() { + // Try to convert the integer to hex if has expected addresses for + // accounts after transaction (result). + // e.g. 10 -> 0xa + if let Some(expected_addresses) = expected_addresses { + let address = Address::from_slice(&hex::decode(format!("{as_i64:040x}"))?); + if expected_addresses.contains(&address) { + return Ok(address); + } } - Yaml::String(str) => parse::parse_address(str), - _ => bail!("cannot parse address {yaml:?}"), + + // Format as a hex string directly for accounts before transaction (pre). + // e.g. 10 -> 0x10 + Ok(Address::from_slice(&hex::decode(format!("{as_i64:0>40}"))?)) + } else if let Yaml::Real(as_real) = yaml { + Ok(Address::from_str(as_real)?) + } else { + bail!("cannot parse address {yaml:?}"); } } /// returns the element as a to address fn parse_to_address(yaml: &Yaml) -> Result> { - let as_str = yaml.as_str().context("to_address_as_str")?; - parse::parse_to_address(as_str) + if let Some(as_str) = yaml.as_str() { + if as_str.trim().is_empty() { + return Ok(None); + } + parse::parse_to_address(as_str) + } else { + bail!("cannot parse to address {:?}", yaml); + } } /// returns the element as an array of bytes @@ -315,25 +351,32 @@ impl<'a> YamlStateTestBuilder<'a> { /// returns the element as calldata bytes, supports 0x, :raw, :abi, :yul and /// { LLL } - fn parse_calldata(&mut self, yaml: &Yaml) -> Result<(Bytes, Option