From 75f98909990ccd73110238cdf0deec260756acb8 Mon Sep 17 00:00:00 2001 From: weiihann Date: Fri, 25 Oct 2024 13:34:02 +0800 Subject: [PATCH] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 8ca930797e6d76acb92c7ca99e8283733c1cff67 Author: wojciechos Date: Thu Oct 24 14:19:52 2024 +0200 Fix spec version for 0_7 endpoint (#2238) commit 00ac988d3f5febdd91ed2f5a11884da1a5deefc9 Author: Kirill Date: Tue Oct 22 18:11:24 2024 +0400 Remove v0.6 endpoints, added v0.8 endpoints (#2229) commit 731099040a8fdd4b966f201b7637a814834291fb Author: Mario Apra Date: Mon Oct 21 15:31:04 2024 +0100 chore: Update instructions on how to build Juno Signed-off-by: Mario Apra commit 0ab532f25325f75e4eba3d5389c4f29ce4eb4988 Author: Kirill Date: Mon Oct 21 15:45:15 2024 +0400 Pass required libbz2 to linker to fix compilation error on macOS (#2228) commit bdc598982e86bf950bbbe19ce88f4a9b701ff09c Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Oct 21 11:15:33 2024 +0000 Bump github.com/prometheus/client_golang from 1.20.4 to 1.20.5 Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.20.4 to 1.20.5. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.20.4...v1.20.5) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] commit bf38adb53cae5eec67fd32e4a0dd9ec5607be0df Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Oct 21 11:15:38 2024 +0000 Bump go.uber.org/mock from 0.4.0 to 0.5.0 Bumps [go.uber.org/mock](https://github.com/uber/mock) from 0.4.0 to 0.5.0. - [Release notes](https://github.com/uber/mock/releases) - [Changelog](https://github.com/uber-go/mock/blob/main/CHANGELOG.md) - [Commits](https://github.com/uber/mock/compare/v0.4.0...v0.5.0) --- updated-dependencies: - dependency-name: go.uber.org/mock dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] commit b9d987eb11401b2ddb8b6a128c564938e315b2db Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Oct 21 11:18:58 2024 +0000 Bump aquasecurity/trivy-action from 0.27.0 to 0.28.0 Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.27.0 to 0.28.0. - [Release notes](https://github.com/aquasecurity/trivy-action/releases) - [Commits](https://github.com/aquasecurity/trivy-action/compare/5681af892cd0f4997658e2bacc62bd0a894cf564...915b19bbe73b92a6cf82a1bc12b087c9a19a5fe2) --- updated-dependencies: - dependency-name: aquasecurity/trivy-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] commit c67b458aa039c50b1855cca177f00edf114a1bb0 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Oct 21 11:19:05 2024 +0000 Update github/codeql-action requirement to 5618c9fc1e675841ca52c1c6b1304f5255a905a0 Updates the requirements on [github/codeql-action](https://github.com/github/codeql-action) to permit the latest version. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/commits/5618c9fc1e675841ca52c1c6b1304f5255a905a0) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production ... Signed-off-by: dependabot[bot] commit 8bdff962b22b3dcedff96350271df6ec140e3be0 Author: yevh Date: Mon Oct 21 11:12:37 2024 +0200 Create trivy.yml (#2226) Signed-off-by: yevh Co-authored-by: Mario Apra commit 0d02f9e75e449f047bef59fb0bbfcad0d03e68f5 Author: wojciechos Date: Fri Oct 18 12:57:02 2024 +0200 Update starknet.go, starknet-js and starknet-rs tests (#2217) commit 3833c0095d171404fd9474a50684663be0525749 Author: Mario Apra Date: Fri Oct 18 10:44:26 2024 +0100 Remove UPX from macOS build process Updated the GitHub Actions workflow to exclude UPX installation and usage on macOS. This change addresses compatibility issues with UPX on macOS, ensuring smoother build processes for macOS environments. More info: https://github.com/upx/upx/issues/612 commit eb19859609fd496feee39fafa0c9504141ee6b04 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Oct 7 11:30:13 2024 +0000 Bump actions/setup-go from 4 to 5 Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4 to 5. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] commit 7faba7c05c0de7cc9d972432b11416eccbac7d9c Author: Kirill Date: Thu Oct 17 18:05:36 2024 +0400 Add missing execution resources to fetched traces (#2222) commit f4d9d698792fd8ec711b9bf2cfc6405a098a7874 Author: Kirill Date: Thu Oct 17 15:56:02 2024 +0400 Add missing gomock.Controller.Finish() calls in plugin tests (#2225) commit f5dc02caac7c59d36015845cf9d5b3355d312da4 Author: Kirill Date: Thu Oct 17 11:15:15 2024 +0400 Small restructure of plugin logic (#2221) commit b43c46f48189926713c58a9760168ef2496c3bff Author: Rian Hughes Date: Wed Oct 16 15:42:07 2024 +0300 Support plugins (#2051) Co-authored-by: rian Co-authored-by: LordGhostX commit ca006de578cfbc5a99dc13c2f751ed0cd03adcb7 Author: Kirill Date: Wed Oct 16 16:14:16 2024 +0400 Replace UnmarshalJSON() with UnmarshalText() for transaction statuses (#2220) * Replace UnmarshalJSON() with UnmarshalText() for transaction statuses UnmarshalText avoids issues with forgetting quotes in JSON, making it simpler for parsing plain text values. commit 935b903f8dcd1fa435aa365d0735bc7a99502300 Author: Kirill Date: Wed Oct 16 13:40:55 2024 +0400 Add db revert cmd (#2216) commit a1be2ebdec563c0e08189f4abc30dbbd07420b05 Author: Mario Apra Date: Fri Oct 11 07:56:32 2024 +0100 chore: Fix how to send comments to github Added necessary permissions to the GitHub Actions workflow to allow writing comments on issues and pull requests. This enables automated feedback and notifications, improving workflow efficiency and communication. commit 6937def6ee72dfe40443f0798cb78fbd636ef2d0 Author: Mario Apra Date: Wed Oct 9 13:00:52 2024 +0100 feat: Check for rust version in Makefile - Enhanced MSRV check in GitHub workflow to include Makefile updates. - Added a new target in Makefile to ensure Rust version compliance. - Updated dependencies and formatting targets to include Rust version check. - Fixed minor formatting issues in Makefile comments. commit f83a70e5190d5f76ed8239195ed4bf672208bc4e Author: Rian Hughes Date: Tue Oct 15 17:22:32 2024 +0300 Fix traces (fees, state diff, events) (#2118) commit 384fe56ca7f20760122de8558181f11d24ee6abb Author: Ng Wei Han <47109095+weiihann@users.noreply.github.com> Date: Tue Oct 15 18:48:39 2024 +0800 Fix core/state_test tests failure (#2198) commit 9ed2accb6ecc731c67727d48817e9957aede8dec Author: wojciechos Date: Mon Oct 14 14:21:08 2024 +0200 Update starknet.go version to fix failing tests (#2215) commit 9c8370362a0d9eebf65b67651a2d037f7e99995f Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Oct 14 11:33:00 2024 +0000 Bump github.com/libp2p/go-libp2p-kad-dht from 0.26.1 to 0.27.0 Bumps [github.com/libp2p/go-libp2p-kad-dht](https://github.com/libp2p/go-libp2p-kad-dht) from 0.26.1 to 0.27.0. - [Release notes](https://github.com/libp2p/go-libp2p-kad-dht/releases) - [Commits](https://github.com/libp2p/go-libp2p-kad-dht/compare/v0.26.1...v0.27.0) --- updated-dependencies: - dependency-name: github.com/libp2p/go-libp2p-kad-dht dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] commit c28429eebda04ed57f8b36e4d8e6a822ef3663c6 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Oct 14 11:32:53 2024 +0000 Bump google.golang.org/protobuf from 1.34.2 to 1.35.1 Bumps google.golang.org/protobuf from 1.34.2 to 1.35.1. --- updated-dependencies: - dependency-name: google.golang.org/protobuf dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] commit 584414117bb139c59d50b87ad203faa6d9b009d4 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri Oct 11 22:25:39 2024 +0000 Bump the npm_and_yarn group across 1 directory with 2 updates Bumps the npm_and_yarn group with 2 updates in the /docs directory: [cookie](https://github.com/jshttp/cookie) and [express](https://github.com/expressjs/express). Updates `cookie` from 0.6.0 to 0.7.1 - [Release notes](https://github.com/jshttp/cookie/releases) - [Commits](https://github.com/jshttp/cookie/compare/v0.6.0...v0.7.1) Updates `express` from 4.21.0 to 4.21.1 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/4.21.1/History.md) - [Commits](https://github.com/expressjs/express/compare/4.21.0...4.21.1) --- updated-dependencies: - dependency-name: cookie dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: express dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] commit 1786cb3874444c37429c281c4235e0fa08a0ef5f Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Oct 7 20:36:59 2024 +0400 Bump google.golang.org/grpc from 1.67.0 to 1.67.1 (#2202) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.67.0 to 1.67.1. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.67.0...v1.67.1) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: Kirill Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kirill commit 45ce05df1eb932ab19c04f5662506bb01fdf4e9f Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Oct 7 20:23:26 2024 +0400 Bump golang.org/x/crypto from 0.27.0 to 0.28.0 (#2201) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.27.0 to 0.28.0. - [Commits](https://github.com/golang/crypto/compare/v0.27.0...v0.28.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit 73be13e913b1fa3a972a19647731c3eb5c0aafda Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Oct 7 16:55:01 2024 +0400 Bump github.com/ethereum/go-ethereum from 1.14.10 to 1.14.11 (#2203) Bump github.com/ethereum/go-ethereum from 1.14.10 to 1.14.11 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.14.10 to 1.14.11. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.14.10...v1.14.11) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit f20c3decbfd8292b703013ee7714be92cb3e5e11 Author: Kirill Date: Mon Oct 7 14:37:19 2024 +0400 Change tx commitment calculation for tx with empty signature (#2196) commit c07eb9d4a057e17963023a3e54af17f21233fb88 Author: Kirill Date: Mon Oct 7 14:20:12 2024 +0400 Update README.md: change header of a network commit 702f25b2296cc419d823d09b671431c14d5b2244 Author: Ng Wei Han <47109095+weiihann@users.noreply.github.com> Date: Fri Oct 4 17:37:05 2024 +0800 Add metrics for gossipsub (#2163) commit 8fcbb938319ff17193849f24b3058ae136e7b62f Author: Kirill Date: Fri Oct 4 11:33:04 2024 +0400 Remove p2p/starnket.StaticStream (#2195) commit 1b89289fefd69500fabde9e7b37d250b7a424887 Author: wojo Date: Wed Sep 18 10:24:48 2024 +0200 Improve starknet-go-tests workflow flexibility and security - Make TEST_RPC_URL and TEST_ACCOUNT_PRIVATE_KEY secrets required - Add 'ref' input parameter to allow testing different branches/tags commit 3e1044dcaecd53125c789bba6940f8a80e0e6021 Author: wojo Date: Fri Sep 13 19:09:42 2024 +0200 Add Starknet Go tests to CI/CD pipeline - Integrate starknet-go-tests workflow into development, staging, and production stages - Mirror the structure used for Rust and JavaScript tests - Use appropriate RPC URLs and account private keys for each environment - Ensure Go tests run after validation/promotion in each stage commit 7e9652c056e0ef507fe506c146cbf6f5a11cd870 Author: Ng Wei Han <47109095+weiihann@users.noreply.github.com> Date: Thu Oct 3 17:48:24 2024 +0800 Move starknet/rust deps to separate package (#2148) Co-authored-by: Mario Apra commit 262c51f7f2643ec08f2a476b0005a30e2c21c2f5 Author: Ng Wei Han <47109095+weiihann@users.noreply.github.com> Date: Thu Oct 3 17:47:46 2024 +0800 Refactor transaction into batch and snapshot (#2182) commit 0c0700c1f47ebd892ea3afbaa85440621d95de18 Author: Daniil Ankushin Date: Tue Oct 1 23:39:32 2024 +0300 Refactor commitment parallel processing (#2169) commit 6b683d8a5c73197d544ba4b0e1069743d0b5ed48 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Sep 30 17:56:49 2024 +0000 Bump github.com/ethereum/go-ethereum from 1.14.9 to 1.14.10 (#2190) Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.14.9 to 1.14.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.14.9...v1.14.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... commit 9d609b62086543a62febe84a929b3491e2a7759d Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Sep 30 17:55:59 2024 +0000 Bump go.uber.org/automaxprocs from 1.5.3 to 1.6.0 (#2191) Bumps [go.uber.org/automaxprocs](https://github.com/uber-go/automaxprocs) from 1.5.3 to 1.6.0. - [Release notes](https://github.com/uber-go/automaxprocs/releases) - [Changelog](https://github.com/uber-go/automaxprocs/blob/master/CHANGELOG.md) - [Commits](https://github.com/uber-go/automaxprocs/compare/v1.5.3...v1.6.0) --- updated-dependencies: - dependency-name: go.uber.org/automaxprocs dependency-type: direct:production update-type: version-update:semver-minor ... commit 546f62ded729489eda1400dbae3576af71afa2c2 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Sep 30 17:54:40 2024 +0000 Bump google.golang.org/grpc from 1.66.2 to 1.67.0 (#2192) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.66.2 to 1.67.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.66.2...v1.67.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit 9a3f2638b77ff8f897f41ea77369b6b86a4e1bcc Author: yevh Date: Mon Sep 30 09:28:59 2024 +0200 Update codeql-analysis.yml Signed-off-by: yevh commit 201d12ee867eb99e737ef623b9bace22ad4f26d3 Author: Mario Apra Date: Wed Sep 25 15:41:53 2024 +0100 chore: Switch to ORAS for artifact promotion Updated CI/CD pipeline to use ORAS instead of Docker for artifact promotion. Changed repository references to align with ORAS. Also, change from docker registry to OCI registry commit 48fb6c54711e7475b33cd04f5c04d63941274847 Author: Daniil Ankushin Date: Wed Sep 25 16:18:14 2024 +0300 Add fuzz tests for utils (#1982) commit b240aba4392b94b058ff4d1cf1e2c42538225e2a Author: Daniil Ankushin Date: Wed Sep 25 11:51:01 2024 +0300 Refactor `syncService.start` method in p2p (#2174) commit 38638ca710f9ba63eeb7296fc7572c98651efbc0 Author: Ng Wei Han <47109095+weiihann@users.noreply.github.com> Date: Tue Sep 24 20:29:02 2024 +0800 Refactor ProofNode to use interface (#2176) commit 67430decdec8c8218a0bbe00ecba89b0863ef10b Author: Daniil Ankushin Date: Tue Sep 24 12:23:19 2024 +0300 feat: Update transactionCommitmentPoseidon function to handle different transaction types (#2153) * feat: Update transactionCommitmentPoseidon function to handle different transaction types The code changes in `transactionCommitmentPoseidon` function update the logic to handle different transaction types. With the changes, the function now checks the type of the transaction and updates the digest accordingly. For `DeployTransaction` and `L1HandlerTransaction`, the digest is updated with a zero value, while for other transaction types, the digest is updated with the transaction signature. * Added tests * Replace dynamic hashes with hardcoded value in test --------- Co-authored-by: Kirill commit 72535cc41d7b8fc78429732751d331c83de6d35b Author: Kirill Date: Tue Sep 24 11:58:05 2024 +0400 Add receipt commitment calculation in post07Hash function (#2133) commit aa241f1c07e5b0a31d779844cfa019d9d91a8395 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Sep 23 17:37:06 2024 +0400 Bump github.com/ethereum/go-ethereum from 1.14.8 to 1.14.9 (#2170) Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.14.8 to 1.14.9. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.14.8...v1.14.9) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit 21d69294b6817a9c416e2be97523bfae404dfdae Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Sep 23 13:23:29 2024 +0000 Bump github.com/bits-and-blooms/bitset from 1.14.2 to 1.14.3 (#2171) Bumps [github.com/bits-and-blooms/bitset](https://github.com/bits-and-blooms/bitset) from 1.14.2 to 1.14.3. - [Release notes](https://github.com/bits-and-blooms/bitset/releases) - [Commits](https://github.com/bits-and-blooms/bitset/compare/v1.14.2...v1.14.3) --- updated-dependencies: - dependency-name: github.com/bits-and-blooms/bitset dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit 4e3d53a6d8c4122b60ac49d710bf0d81b1becf1e Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Sep 23 17:13:02 2024 +0400 Bump github.com/prometheus/client_golang from 1.20.3 to 1.20.4 (#2172) * Bump github.com/prometheus/client_golang from 1.20.3 to 1.20.4 Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.20.3 to 1.20.4. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.20.3...v1.20.4) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump github.com/prometheus/client_golang from 1.20.3 to 1.20.4 Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.20.3 to 1.20.4. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.20.3...v1.20.4) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kirill commit 107876a16086ee6fe2251e37035848b827748dfe Author: Daniil Ankushin Date: Mon Sep 23 14:23:58 2024 +0300 Improve receiptCommitment function with parallel processing (#2165) commit 37ed0958cf1713affc1a4f344edaf23491839053 Author: Kirill Date: Thu Sep 19 17:50:46 2024 +0400 Fix p2p sync for 0.13.2 blocks (#2146) commit 4fb5d0f59b5132945ef9904303925f0940be26aa Author: Ng Wei Han <47109095+weiihann@users.noreply.github.com> Date: Thu Sep 19 15:55:14 2024 +0800 Remove repeated close host call (#2147) commit f3c885fa02bef81f2ae140ee81d85145e3d2b7a7 Author: Daniil Ankushin Date: Wed Sep 18 18:03:02 2024 +0300 Enable nilness check in govet linter (#2161) commit 793edae5bcebc01a5d92432c4f4b7228b1d5a417 Author: Daniil Ankushin Date: Wed Sep 18 17:48:20 2024 +0300 Fix error handling in trie/node.go (#2159) chore: Fix error handling in trie/node.go commit 494f9cc12a054ae35ba51a47b16cd8b368e48001 Author: Mario Apra Date: Mon Sep 16 11:15:42 2024 +0100 chore: Add minimum rust version into readme - Fix #2139 commit 3f34c50cff70adcb4c338380f70e3af7b3b3ddb6 Author: Mario Apra Date: Fri Sep 13 21:24:25 2024 +0100 feat: Add GitHub Actions workflow to find the smallest supported Rust version commit d637844217b1aa97c864a026a6dfd838afee9b9b Author: Daniil Ankushin Date: Wed Sep 18 17:47:48 2024 +0300 L1->L2 message hashes are 256 bit hashes (#2160) * refactor: Update Hash message to use Hash256 type * Regenerate spec * refactor: Update MsgHash to use Hash256 type in AdaptReceipt function commit 5c6ffd9c5203a9d7b4dc225635900eca593075a8 Author: Daniil Ankushin Date: Wed Sep 18 12:44:08 2024 +0300 Refactor randomPeer function to use local variable (#2158) commit 1ff5e2c049bdc9cdeaced7cc7edf135560960d31 Author: Daniil Ankushin Date: Tue Sep 17 11:31:16 2024 +0300 chore: Update golangci-lint to version 1.61.0 (#2154) * chore: Update golangci-lint to version 1.61.0 * chore: Exclude G115 from gosec linter Exclude G115 from the gosec linter to address the issue with https://github.com/securego/gosec/issues/1212. * chore: Remove unused variable assignments Remove unused variable assignments in node/node.go and utils/pipeline/pipeline_test.go files. * chore: Remove unused nolint directives Remove unused nolint directives in the starknet client.go and handlers.go files. commit 6735ed5cfcf8db08276774768899a48bc5b45d11 Author: Daniil Ankushin Date: Mon Sep 16 15:19:29 2024 +0300 Add a filter for nodes to exclude a host node (#2149) * Add a filter for nodes to exclude a host node * Update p2p/p2p.go Co-authored-by: Ng Wei Han <47109095+weiihann@users.noreply.github.com> Signed-off-by: Daniil Ankushin --------- Signed-off-by: Daniil Ankushin Co-authored-by: Ng Wei Han <47109095+weiihann@users.noreply.github.com> commit 175cff21a0c4f38e9abc6f8087a83b9fbd8327e6 Author: Paweł Nowosielski Date: Fri Sep 13 13:36:33 2024 +0200 fix: iterface is not nil unless never assigned commit 6ce6441e104b0975a15a1dd5b4c435a609954eaf Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Sep 16 11:57:32 2024 +0000 Bump golang.org/x/crypto from 0.26.0 to 0.27.0 (#2152) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.26.0 to 0.27.0. - [Commits](https://github.com/golang/crypto/compare/v0.26.0...v0.27.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit 903ced6d810fd21cd7ddf27b1eba323c4fa20cd2 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Sep 16 11:21:28 2024 +0000 Bump google.golang.org/grpc from 1.66.0 to 1.66.2 Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.66.0 to 1.66.2. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.66.0...v1.66.2) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] commit 471831b1f80e5ab37b702cde49f998c193057eab Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Sep 16 11:21:34 2024 +0000 Bump github.com/consensys/gnark-crypto from 0.13.0 to 0.14.0 Bumps [github.com/consensys/gnark-crypto](https://github.com/consensys/gnark-crypto) from 0.13.0 to 0.14.0. - [Release notes](https://github.com/consensys/gnark-crypto/releases) - [Changelog](https://github.com/Consensys/gnark-crypto/blob/master/CHANGELOG.md) - [Commits](https://github.com/consensys/gnark-crypto/compare/v0.13.0...v0.14.0) --- updated-dependencies: - dependency-name: github.com/consensys/gnark-crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] commit 153e651f156fd579a9e4e6676fe3ca9b881b05c2 Author: Mario Apra Date: Fri Sep 13 12:42:40 2024 +0100 chore: Update jFrog Docker credentials in CI/CD pipeline commit e6725072b9d80c4bbba81a9146a48a20129de848 Author: Mario Apra Date: Fri Sep 13 11:52:48 2024 +0100 chore: update how to deploy dev and staging envs With the https://github.com/NethermindEth/argo/pull/1094 change, it will now always track the latest tag which can be overwriten everytime this workflow runs. It means that even performing roll-backs will work commit e3b6939b6fbb67dd317460301b7fe9a456dcb752 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu Sep 12 19:42:46 2024 +0200 Bump body-parser and express in /docs (#2135) Bumps [body-parser](https://github.com/expressjs/body-parser) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together. Updates `body-parser` from 1.20.2 to 1.20.3 - [Release notes](https://github.com/expressjs/body-parser/releases) - [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md) - [Commits](https://github.com/expressjs/body-parser/compare/1.20.2...1.20.3) Updates `express` from 4.19.2 to 4.21.0 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/4.21.0/History.md) - [Commits](https://github.com/expressjs/express/compare/4.19.2...4.21.0) --- updated-dependencies: - dependency-name: body-parser dependency-type: indirect - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit 94158fedd889b8c6db247d68299febe3c499724d Author: AnkushinDaniil Date: Tue Sep 10 14:37:09 2024 +0300 Bump Go version to 1.23.1 commit b2f565e19e8430dca7e1cd2e879d412925ff015d Author: Kirill Date: Wed Sep 11 11:07:43 2024 +0200 Fix p2p header adapters (#2127) commit 71c7ca2a75d29adac03d55387e4b9f9368303fcc Author: Daniil Ankushin Date: Tue Sep 10 12:37:58 2024 +0300 Remove unused code in node.newL1Client() (#2128) commit b89e0786091a683049a62c7eac83588557934fe7 Author: Kanishka Date: Mon Sep 9 18:57:43 2024 +0530 Add l1 metrics (#1678) Co-authored-by: Kirill commit 8a96b78a679b39b8fce8e3c88d4c75831c2c82a7 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Sep 9 12:57:25 2024 +0100 Bump github.com/go-playground/validator/v10 from 10.22.0 to 10.22.1 (#2124) * Bump github.com/go-playground/validator/v10 from 10.22.0 to 10.22.1 Bumps [github.com/go-playground/validator/v10](https://github.com/go-playground/validator) from 10.22.0 to 10.22.1. - [Release notes](https://github.com/go-playground/validator/releases) - [Commits](https://github.com/go-playground/validator/compare/v10.22.0...v10.22.1) --- updated-dependencies: - dependency-name: github.com/go-playground/validator/v10 dependency-type: direct:production update-type: version-update:semver-patch ... --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit 4456d93b21012cb0c6b55eb760a4f5d31e5ee8da Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Sep 9 12:56:56 2024 +0100 Bump github.com/prometheus/client_golang from 1.20.2 to 1.20.3 (#2125) * Bump github.com/prometheus/client_golang from 1.20.2 to 1.20.3 Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.20.2 to 1.20.3. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/v1.20.3/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.20.2...v1.20.3) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit 990a5804d79e1b4f81cbade00e426f6472cdaa39 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Sep 9 11:11:29 2024 +0000 Bump github.com/libp2p/go-libp2p-kad-dht from 0.25.2 to 0.26.1 Bumps [github.com/libp2p/go-libp2p-kad-dht](https://github.com/libp2p/go-libp2p-kad-dht) from 0.25.2 to 0.26.1. - [Release notes](https://github.com/libp2p/go-libp2p-kad-dht/releases) - [Commits](https://github.com/libp2p/go-libp2p-kad-dht/compare/v0.25.2...v0.26.1) --- updated-dependencies: - dependency-name: github.com/libp2p/go-libp2p-kad-dht dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] commit 238c43cb2d42e6b3c11be7d30d9c1b36bde207c6 Author: Onur Yuce <63292060+onuruci@users.noreply.github.com> Date: Fri Sep 6 12:41:52 2024 +0300 merge and split proofs (#1984) * implement logic to support ordering, merging and splitting of proof nodes sent over P2P --------- Co-authored-by: Rian Hughes commit dc91f9b3be9e9412ca352e1e74148bdde30459ca Author: Mario Apra Date: Thu Sep 5 10:26:47 2024 +0100 Improve build binaries pipeline Changes made: - build macOS arm and x86 - rename architecture from amd64 to x86_64, which is much easier to distinct from arm - remove unnecessary step for self-hosted which is not being used anymore - create ARTIFACT_NAME env var, so it's much easier to read the code - remove unnecessary id - add trigger on PR that change the build binaries files - get architecture during runtime commit 4f3231ba53b15f180faf7b6104a900d58782b937 Author: Ömer Faruk Irmak Date: Thu Sep 5 17:17:33 2024 +0300 Optimize reading felts from state (#1713) Co-authored-by: onuruci commit c0008d7161a88e37f722322b2cbe69b64b0024ee Author: Mario Apra Date: Tue Sep 3 13:16:49 2024 +0100 Update number of cores for ubuntu-arm64 in juno-test workflow commit 1862240f8ff8da6f94fb7c2e1a0f062bbe5780ba Author: Kirill Date: Tue Sep 3 14:48:32 2024 +0200 Update blockifier to 0.8.0-rc.3 (#2116) commit cb350dffa9f7accddc64162b2341e73043f13a87 Author: Ng Wei Han <47109095+weiihann@users.noreply.github.com> Date: Mon Sep 2 23:07:46 2024 +0800 Remove additional "kad" substring from p2p discovery protocol name (#2113) commit 52d16ab18ca9466c02f7f4d4e0d04d2682d72fd5 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Sep 2 11:12:50 2024 +0000 Bump google.golang.org/grpc from 1.65.0 to 1.66.0 Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.65.0 to 1.66.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.65.0...v1.66.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] commit 552327aa74dcf4871eecde74901c7a63ea985780 Author: Kirill Date: Mon Sep 2 15:23:49 2024 +0200 Rewrite semver usage with new methods .LessThanEqual() and .GreaterThanEqual() (#2112) commit 8f8d37a4b8f5b2d7e60790b4f8d01e10a4741b69 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Sep 2 11:12:57 2024 +0000 Bump github.com/Masterminds/semver/v3 from 3.2.1 to 3.3.0 Bumps [github.com/Masterminds/semver/v3](https://github.com/Masterminds/semver) from 3.2.1 to 3.3.0. - [Release notes](https://github.com/Masterminds/semver/releases) - [Changelog](https://github.com/Masterminds/semver/blob/master/CHANGELOG.md) - [Commits](https://github.com/Masterminds/semver/compare/v3.2.1...v3.3.0) --- updated-dependencies: - dependency-name: github.com/Masterminds/semver/v3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] commit ef162c31edec97680027793d07c97cfe1b9165d7 Author: Kirill Date: Mon Sep 2 14:19:06 2024 +0200 Rewrite func iterator to range loop in p2p/starknet.streamHandler (#2106) commit 77b0d60d3ccbb368c8ac290e834469fcf08735aa Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Sep 2 12:04:14 2024 +0000 Bump github.com/rs/cors from 1.11.0 to 1.11.1 (#2108) Bumps [github.com/rs/cors](https://github.com/rs/cors) from 1.11.0 to 1.11.1. - [Commits](https://github.com/rs/cors/compare/v1.11.0...v1.11.1) --- updated-dependencies: - dependency-name: github.com/rs/cors dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit 5e6e86c14442e82bd44cc17cc608e84115472e5f Author: Priyank Makwana <117025290+RuneRogue@users.noreply.github.com> Date: Fri Aug 30 18:57:33 2024 +0530 Emit events on remote db (#2088) commit daf1cde54900ce59df45eba742285d4524197067 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri Aug 30 12:57:27 2024 +0200 Bump webpack from 5.91.0 to 5.94.0 in /docs (#2100) Bumps [webpack](https://github.com/webpack/webpack) from 5.91.0 to 5.94.0. - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](https://github.com/webpack/webpack/compare/v5.91.0...v5.94.0) --- updated-dependencies: - dependency-name: webpack dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit a4eac4cd0d484299669a7654a331d7af3751433b Author: Kirill Date: Fri Aug 30 12:28:33 2024 +0200 Improve trace logging (#2101) Improve trace logging. 1. "DEBUG" prefix has been removed 2. Added color support 3. Fixed caller reference commit 90d04becbb85382caaea42130a34d755019bd915 Author: Onur Yuce <63292060+onuruci@users.noreply.github.com> Date: Thu Aug 29 01:23:26 2024 +0300 Added /ready/sync endpoint (#2060) commit 54e20a6b6bf9854b723cc6ef462308aa52c5732f Author: Kirill Date: Wed Aug 28 11:53:00 2024 +0200 Add output field to vm.ComputationResources (#2096) commit 0f2d88bbc4150b6e09f33ca0492f0fb343089852 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Aug 27 09:28:58 2024 +0000 Bump micromatch from 4.0.7 to 4.0.8 in /docs (#2094) Bumps [micromatch](https://github.com/micromatch/micromatch) from 4.0.7 to 4.0.8. - [Release notes](https://github.com/micromatch/micromatch/releases) - [Changelog](https://github.com/micromatch/micromatch/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/micromatch/compare/4.0.7...4.0.8) --- updated-dependencies: - dependency-name: micromatch dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit dd99bc16a3a53ebc58b7f86a092d1da2370d4314 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Aug 27 11:14:24 2024 +0200 Bump github.com/bits-and-blooms/bitset from 1.13.0 to 1.14.2 (#2091) Bumps [github.com/bits-and-blooms/bitset](https://github.com/bits-and-blooms/bitset) from 1.13.0 to 1.14.2. - [Release notes](https://github.com/bits-and-blooms/bitset/releases) - [Commits](https://github.com/bits-and-blooms/bitset/compare/v1.13.0...v1.14.2) --- updated-dependencies: - dependency-name: github.com/bits-and-blooms/bitset dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit fe5add8deba59f91ba6dffd92d7314ea21486b92 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Aug 27 10:59:24 2024 +0200 Bump github.com/spf13/cobra from 1.8.0 to 1.8.1 (#2090) Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.8.0 to 1.8.1. - [Release notes](https://github.com/spf13/cobra/releases) - [Commits](https://github.com/spf13/cobra/compare/v1.8.0...v1.8.1) --- updated-dependencies: - dependency-name: github.com/spf13/cobra dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit 7e2e13f3e34d4f2c05945f1a846177877d8c77ac Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Aug 27 10:32:22 2024 +0200 Bump github.com/prometheus/client_golang from 1.20.0 to 1.20.2 (#2089) Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.20.0 to 1.20.2. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.20.0...v1.20.2) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit acda2a222b74434fc9fe7ecd977dc9b3b7f4943f Author: Osakpolor Obaseki <12957252+obasekiosa@users.noreply.github.com> Date: Fri Aug 23 10:28:14 2024 +0100 Add execution stepcount in header [X-Cairo-Steps] (#1989) Co-authored-by: Kirill commit 692bd490dd508d7b5bfcdff0d31e2656b42fdc1f Author: Mario Apra Date: Wed Aug 21 18:13:50 2024 +0100 chore: Remove concurrency settings in child workflow When the parent and the child workflow set the concurrency, it creates a deadlock. More info: https://github.com/github/vscode-github-actions/issues/135 commit eb2eb04fa95faec1c7f999c3ee19277dd6150905 Author: Daniil Ankushin Date: Wed Aug 21 20:19:11 2024 +0300 Update `blockifier` to 0.8.0-rc.2 (#2081) * Update blockifier dependency to version 0.8.0-rc.2 * Update starknet_api and cairo-vm dependencies This commit updates the `starknet_api` dependency to version 0.13.0-rc.1 and the `cairo-vm` dependency to version 1.0.1 in the `Cargo.toml` file. * Update once_cell dependency to version 1.19.0 * Update dependencies in Cargo.toml * Update serde dependency to version 1.0.208 * Update serde_json dependency to version 1.0.125 * Update cairo-vm dependency to version 1.0.1 * Update dependencies in Cargo.toml commit 5c333255c71f9c19d56127a4537889fcb6a49f68 Author: Osakpolor Obaseki <12957252+obasekiosa@users.noreply.github.com> Date: Wed Aug 21 10:49:18 2024 +0100 Make starknet_getTransactionReceipt and other function calls response conform to the 0.7.1 spec (#2078) Co-authored-by: Kirill commit af674c3decc9cd6bd50b583d00a1012a8f0a8ddc Author: Kirill Date: Wed Aug 21 11:39:44 2024 +0300 Replace custom code with maps package functions (#2073) commit c391201aba707d33fa7f7ae4315856a0ca3d26a0 Author: Mario Apra Date: Tue Aug 20 14:45:54 2024 +0100 Replace nhooyr.io/websocket with github.com/coder/websocket (#2079) * Replace nhooyr.io/websocket with github.com/coder/websocket * format jsonrpc/websocket_test.go with gci fix lint errors --------- Co-authored-by: onuruci commit 52c97ba1daf21ccc69d6cbea212d8f3c1fdafc12 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Aug 20 11:28:02 2024 +0000 Bump github.com/ethereum/go-ethereum from 1.14.7 to 1.14.8 (#2075) Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.14.7 to 1.14.8. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.14.7...v1.14.8) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit 4e99b580b1aabfe0d485ed39171793ae8c67d824 Author: Kirill Date: Tue Aug 20 14:15:03 2024 +0300 Add adapter for starknet.TransactionStatus in rpc (#2072) commit 6f1d6d9b078088d794f7edb4cb1f032be3533b5d Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Aug 20 09:48:42 2024 +0000 Bump github.com/libp2p/go-libp2p-pubsub from 0.11.0 to 0.12.0 (#2076) Bumps [github.com/libp2p/go-libp2p-pubsub](https://github.com/libp2p/go-libp2p-pubsub) from 0.11.0 to 0.12.0. - [Release notes](https://github.com/libp2p/go-libp2p-pubsub/releases) - [Commits](https://github.com/libp2p/go-libp2p-pubsub/compare/v0.11.0...v0.12.0) --- updated-dependencies: - dependency-name: github.com/libp2p/go-libp2p-pubsub dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit 946560bb3709b95067080b672971e665f88909d9 Author: wojciechos Date: Mon Aug 19 21:54:45 2024 +0200 Add sepolia integration snapshot to docs (#2071) commit 5855946e378db12e53fe7aa988d4235c4e0c2de3 Author: Mario Apra Date: Mon Aug 19 20:36:40 2024 +0100 chore: Ignore specific dependencies in dependabot.yml commit de9f20b4951e4d248db9e25764d327aed3b40c16 Author: Mario Apra Date: Mon Aug 19 11:49:53 2024 +0100 ci: Update concurrency settings in GitHub workflows If there are two jobs running for the same branch, cancel the oldest one. This is useful when merging many PRs at the same time (for example the ones from dependabot), avoiding running the tests/deployment for every single commit commit 32ef2d6a117ed835e1a60fe8f1200fc51c2c85ba Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Aug 19 18:08:17 2024 +0300 Bump github.com/prometheus/client_golang from 1.19.1 to 1.20.0 (#2064) Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.19.1 to 1.20.0. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.19.1...v1.20.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit 0ac7e8744fed40cfcf049dbb2863c48b1b8646a5 Author: Daniil Ankushin Date: Mon Aug 19 17:36:00 2024 +0300 Rewrite iterator functions with new for loop statement (#1954) commit 50bc46d15cdb8649ac1d2e9a4bf438f7ace0e6ce Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Aug 19 16:54:07 2024 +0300 Bump github.com/cockroachdb/pebble from 1.1.1 to 1.1.2 (#2063) Bumps [github.com/cockroachdb/pebble](https://github.com/cockroachdb/pebble) from 1.1.1 to 1.1.2. - [Release notes](https://github.com/cockroachdb/pebble/releases) - [Commits](https://github.com/cockroachdb/pebble/compare/v1.1.1...v1.1.2) --- updated-dependencies: - dependency-name: github.com/cockroachdb/pebble dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit efe0fc1eba6616a10d3d99b7d0c8348ced7455b3 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Aug 19 16:18:50 2024 +0300 Bump github.com/bits-and-blooms/bloom/v3 from 3.6.0 to 3.7.0 (#2065) Bumps [github.com/bits-and-blooms/bloom/v3](https://github.com/bits-and-blooms/bloom) from 3.6.0 to 3.7.0. - [Release notes](https://github.com/bits-and-blooms/bloom/releases) - [Commits](https://github.com/bits-and-blooms/bloom/compare/v3.6.0...v3.7.0) --- updated-dependencies: - dependency-name: github.com/bits-and-blooms/bloom/v3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Onur Yuce <63292060+onuruci@users.noreply.github.com> commit d65d4b48da2fae522c24cc4dd955346dd9313011 Author: Mario Apra Date: Mon Aug 19 12:37:18 2024 +0100 fix: Remove unnecessary go in matrix CI is getting the go version from go.mod, and there is no reference for matrix.go. Therefore we can conclude that this is not being used. The annoying part with this is when upgrading the go version, the job will be a different name, and someone needs to manually go to the protected rule for the main branch and update what's the name of the tests --- .dockerignore | 3 + .github/dependabot.yml | 4 + .github/workflows/build-binaries.yml | 41 +- .github/workflows/ci-cd-pipeline.yml | 61 +- .github/workflows/codeql-analysis.yml | 8 +- .github/workflows/docs-deploy.yml | 6 +- .github/workflows/docs-test.yml | 4 + .github/workflows/find-smallest-rust.yml | 55 ++ .github/workflows/juno-lint.yml | 8 +- .github/workflows/juno-test.yml | 13 +- .github/workflows/rpc-tests.yml | 2 +- .github/workflows/starknet-go-tests.yml | 36 ++ .github/workflows/starknet-js-tests.yml | 8 +- .github/workflows/starknet-rs-tests.yml | 4 +- .../sync_first_100_blocks_smoke_test.yml | 8 +- .github/workflows/trivy.yml | 43 ++ .golangci.yaml | 11 +- Dockerfile | 2 +- Makefile | 31 +- README.md | 19 +- adapters/core2p2p/block.go | 7 +- adapters/core2p2p/receipt.go | 4 +- adapters/p2p2core/block.go | 1 - adapters/p2p2core/class.go | 3 +- adapters/p2p2core/felt.go | 18 +- adapters/p2p2core/felt_test.go | 39 ++ adapters/p2p2core/receipt.go | 30 +- adapters/p2p2core/state.go | 4 +- adapters/vm2core/vm2core.go | 2 +- adapters/vm2core/vm2core_test.go | 7 +- blockchain/blockchain.go | 18 +- .../feeder/testdata/integration/block/0.json | 24 +- .../testdata/integration/block/300000.json | 112 +++- cmd/juno/dbcmd.go | 94 ++- cmd/juno/dbcmd_test.go | 66 +- cmd/juno/juno.go | 4 + core/block.go | 27 +- core/block_pkg_test.go | 63 ++ core/block_test.go | 14 - core/class_test.go | 2 - core/receipt.go | 49 +- core/receipt_pkg_test.go | 98 +++ core/state.go | 71 +- core/state_test.go | 31 +- core/state_update.go | 7 +- core/transaction.go | 231 +++---- core/transaction_test.go | 2 - core/trie/node.go | 4 +- core/trie/proof.go | 307 ++++++--- core/trie/proof_test.go | 478 +++++++++++--- core/trie/snap_support.go | 15 +- db/db.go | 3 - db/pebble/batch.go | 115 ++++ db/pebble/common.go | 34 + db/pebble/db.go | 17 +- db/pebble/db_test.go | 2 +- db/pebble/snapshot.go | 75 +++ db/pebble/transaction.go | 145 ----- db/remote/db.go | 22 +- docs/docs/configuring.md | 1 + docs/docs/plugins.md | 82 +++ docs/docs/snapshots.md | 9 + docs/package-lock.json | 157 +++-- docs/sidebars.js | 1 + .../version-0.11.8/snapshots.md | 9 + go.mod | 132 ++-- go.sum | 311 ++++----- jsonrpc/http.go | 6 +- jsonrpc/server.go | 90 ++- jsonrpc/server_test.go | 25 +- jsonrpc/websocket.go | 4 +- jsonrpc/websocket_test.go | 2 +- l1/eth_subscriber.go | 17 +- l1/event_listener.go | 10 + migration/migration.go | 5 +- mocks/mock_plugin.go | 98 +++ mocks/mock_vm.go | 23 +- node/http.go | 48 +- node/http_test.go | 75 +++ node/metrics.go | 9 + node/node.go | 34 +- node/throttled_vm.go | 18 +- p2p/gossip_tracer.go | 218 +++++++ p2p/metrics.go | 18 - p2p/p2p.go | 34 +- p2p/snap_server.go | 30 +- p2p/snap_syncer.go | 16 +- p2p/starknet/client.go | 7 +- p2p/starknet/handlers.go | 16 +- p2p/starknet/ids.go | 4 - p2p/starknet/p2p/proto/common.proto | 7 + p2p/starknet/p2p/proto/receipt.proto | 2 +- p2p/starknet/snap_provider.go | 3 +- p2p/starknet/spec/common.pb.go | 276 +++++--- p2p/starknet/spec/receipt.pb.go | 60 +- p2p/starknet/stream.go | 17 - p2p/starknet/stream_test.go | 19 - p2p/sync.go | 198 +++--- plugin/plugin.go | 43 ++ plugin/plugin_test.go | 79 +++ plugin/service.go | 19 + plugin/service_test.go | 47 ++ rpc/block.go | 24 +- rpc/block_test.go | 11 +- rpc/class.go | 3 +- rpc/estimate_fee.go | 74 +-- rpc/estimate_fee_test.go | 100 +-- rpc/events_test.go | 2 +- rpc/handlers.go | 42 +- rpc/handlers_test.go | 12 +- rpc/helpers.go | 9 +- rpc/simulation.go | 70 +- rpc/simulation_test.go | 43 +- rpc/trace.go | 159 +++-- rpc/trace_test.go | 212 ++---- rpc/transaction.go | 92 ++- rpc/transaction_test.go | 311 +++------ scripts/fuzz_all.sh | 18 + starknet/{ => compiler}/compiler.go | 10 +- starknet/{ => compiler}/compiler_test.go | 11 +- starknet/{ => compiler}/rust/.gitignore | 0 starknet/{ => compiler}/rust/Cargo.toml | 6 +- starknet/{ => compiler}/rust/Makefile | 0 starknet/{ => compiler}/rust/src/lib.rs | 0 starknet/transaction.go | 54 +- starknet/transaction_test.go | 38 +- sync/sync.go | 65 +- utils/compression_test.go | 10 + utils/iter/pull.go | 34 - utils/iter/pull_test.go | 49 -- utils/iter/seq.go | 6 - utils/log.go | 51 +- utils/maps.go | 18 - utils/pipeline/pipeline_test.go | 1 - vm/rust/Cargo.toml | 12 +- vm/rust/src/juno_state_reader.rs | 64 +- vm/rust/src/lib.rs | 27 +- vm/rust/versioned_constants_13_0.json | 1 + vm/rust/versioned_constants_13_1.json | 1 + vm/rust/versioned_constants_13_1_1.json | 1 + vm/rust/versioned_constants_13_2.json | 608 ++++++++++++++++++ vm/state_reader.go | 23 +- vm/trace.go | 15 +- vm/vm.go | 70 +- vm/vm_test.go | 18 +- 145 files changed, 4731 insertions(+), 2535 deletions(-) create mode 100644 .dockerignore create mode 100644 .github/workflows/find-smallest-rust.yml create mode 100644 .github/workflows/starknet-go-tests.yml create mode 100644 .github/workflows/trivy.yml create mode 100644 adapters/p2p2core/felt_test.go create mode 100644 core/block_pkg_test.go create mode 100644 core/receipt_pkg_test.go create mode 100644 db/pebble/batch.go create mode 100644 db/pebble/common.go create mode 100644 db/pebble/snapshot.go delete mode 100644 db/pebble/transaction.go create mode 100644 docs/docs/plugins.md create mode 100644 mocks/mock_plugin.go create mode 100644 node/http_test.go create mode 100644 p2p/gossip_tracer.go delete mode 100644 p2p/metrics.go delete mode 100644 p2p/starknet/stream.go delete mode 100644 p2p/starknet/stream_test.go create mode 100644 plugin/plugin.go create mode 100644 plugin/plugin_test.go create mode 100644 plugin/service.go create mode 100644 plugin/service_test.go create mode 100755 scripts/fuzz_all.sh rename starknet/{ => compiler}/compiler.go (81%) rename starknet/{ => compiler}/compiler_test.go (86%) rename starknet/{ => compiler}/rust/.gitignore (100%) rename starknet/{ => compiler}/rust/Cargo.toml (64%) rename starknet/{ => compiler}/rust/Makefile (100%) rename starknet/{ => compiler}/rust/src/lib.rs (100%) delete mode 100644 utils/iter/pull.go delete mode 100644 utils/iter/pull_test.go delete mode 100644 utils/iter/seq.go create mode 100644 vm/rust/versioned_constants_13_2.json diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..2f579965df --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +# do not copy local database files +p2p-dbs/ +juno/ \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 794debc288..0209195a1f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -20,3 +20,7 @@ updates: open-pull-requests-limit: 3 schedule: interval: "weekly" + ignore: + - dependency-name: "cairo-vm" + - dependency-name: "starknet_api" + - dependency-name: "blockifier" diff --git a/.github/workflows/build-binaries.yml b/.github/workflows/build-binaries.yml index ae2bc83eac..c85c08263c 100644 --- a/.github/workflows/build-binaries.yml +++ b/.github/workflows/build-binaries.yml @@ -5,6 +5,11 @@ on: tags: - 'v*' workflow_dispatch: + pull_request: + branches: + - main + paths: + - .github/workflows/build-binaries.yml jobs: build: @@ -13,11 +18,9 @@ jobs: matrix: include: - os: ubuntu-latest - architecture: amd64 - - os: macOS-latest - architecture: amd64 + - os: macos-13 - os: ubuntu-arm64-4-core - architecture: arm64 + - os: macos-latest runs-on: ${{ matrix.os }} steps: @@ -27,47 +30,45 @@ jobs: fetch-depth: 0 - name: Get latest tag - id: tag run: echo "TAG=$(git describe --tags)" >> $GITHUB_ENV + - name: Get artifact name + run: echo "ARTIFACT_NAME=juno-${{ env.TAG }}-${{ runner.os }}-$(uname -m)" >> $GITHUB_ENV + - name: Install dependencies (Linux) if: runner.os == 'Linux' run: sudo apt-get update -qq && sudo apt-get install -y upx-ucl build-essential cargo git golang libjemalloc-dev libjemalloc2 -y - name: Install dependencies (macOS) if: runner.os == 'macOS' - run: brew install upx cargo-c jemalloc + run: brew install cargo-c jemalloc - name: Set up Go - uses: actions/setup-go@v5.0.2 + uses: actions/setup-go@v5 with: go-version-file: go.mod - name: Build Juno run: | make juno - upx build/juno - mv build/juno juno-${{ env.TAG }}-${{ runner.os }}-${{ matrix.architecture }} + if [[ "${{ runner.os }}" != "macOS" ]]; then + upx build/juno + fi + mv build/juno ${{ env.ARTIFACT_NAME }} - name: Generate Checksum id: checksum run: | if [[ "${{ runner.os }}" == "macOS" ]]; then - shasum -a 256 juno-${{ env.TAG }}-${{ runner.os }}-${{ matrix.architecture }} > juno-${{ env.TAG }}-${{ runner.os }}-${{ matrix.architecture }}.sha256 + shasum -a 256 ${{ env.ARTIFACT_NAME }} > ${{ env.ARTIFACT_NAME }}.sha256 else - sha256sum juno-${{ env.TAG }}-${{ runner.os }}-${{ matrix.architecture }} > juno-${{ env.TAG }}-${{ runner.os }}-${{ matrix.architecture }}.sha256 + sha256sum ${{ env.ARTIFACT_NAME }} > ${{ env.ARTIFACT_NAME }}.sha256 fi - name: Upload Artifact uses: actions/upload-artifact@v4 with: - name: juno-${{ env.TAG }}-${{ runner.os }}-${{ matrix.architecture }} + name: ${{ env.ARTIFACT_NAME }} path: | - juno-${{ env.TAG }}-${{ runner.os }}-${{ matrix.architecture }} - juno-${{ env.TAG }}-${{ runner.os }}-${{ matrix.architecture }}.sha256 - - - name: Cleanup - if: matrix.os == 'self-hosted' - run: | - rm juno-${{ env.TAG }}-${{ runner.os }}-${{ matrix.architecture }} - rm juno-${{ env.TAG }}-${{ runner.os }}-${{ matrix.architecture }}.sha256 + ${{ env.ARTIFACT_NAME }} + ${{ env.ARTIFACT_NAME }}.sha256 diff --git a/.github/workflows/ci-cd-pipeline.yml b/.github/workflows/ci-cd-pipeline.yml index 0c4c3da0b7..50c628f21d 100644 --- a/.github/workflows/ci-cd-pipeline.yml +++ b/.github/workflows/ci-cd-pipeline.yml @@ -3,9 +3,9 @@ name: CI/CD pipeline env: DOCKER_REGISTRY: nethermind.jfrog.io - REPO_DEV: nubia-docker-local-dev - REPO_STAGING: nubia-docker-local-staging - REPO_PROD: nubia-docker-local-prod + REPO_DEV: nubia-oci-local-dev + REPO_STAGING: nubia-oci-local-staging + REPO_PROD: nubia-oci-local-prod on: @@ -14,6 +14,10 @@ on: tags: ["v*"] workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: id-token: write contents: write @@ -38,7 +42,7 @@ jobs: # This one is to be able to use the image tag in the next steps in this job echo "DOCKER_IMAGE_TAG=$DOCKER_IMAGE_TAG" >> $GITHUB_ENV - # This one is to be able to use the image tag in the next jobs + # This one is to be able to use the image tag in the next jobs echo "DOCKER_IMAGE_TAG=$DOCKER_IMAGE_TAG" >> $GITHUB_OUTPUT - name: Setup Docker Buildx @@ -46,7 +50,7 @@ jobs: - name: Login to registry run: | - docker login ${{ env.DOCKER_REGISTRY }} -u ${{ vars.ARTIFACTORY_NUBIA_USER }} -p ${{ secrets.ARTIFACTORY_NUBIA_CONTRIBUTOR}} + docker login ${{ env.DOCKER_REGISTRY }} -u ${{ secrets.ARTIFACTORY_NUBIA_USERNAME }} -p ${{ secrets.ARTIFACTORY_NUBIA_TOKEN_DEVELOPER }} - name: Build and Push uses: docker/build-push-action@v6 @@ -54,7 +58,9 @@ jobs: context: . platforms: "linux/amd64" push: true - tags: ${{ env.DOCKER_REGISTRY }}/${{ env.REPO_DEV }}/juno:${{ env.DOCKER_IMAGE_TAG }} + tags: | + ${{ env.DOCKER_REGISTRY }}/${{ env.REPO_DEV }}/juno:${{ env.DOCKER_IMAGE_TAG }} + ${{ env.DOCKER_REGISTRY }}/${{ env.REPO_DEV }}/juno:latest validate_dev: @@ -77,7 +83,7 @@ jobs: needs: [validate_dev] uses: ./.github/workflows/starknet-rs-tests.yml secrets: - STARKNET_RPC: ${{ secrets.DEV_SEPOLIA_URL }}/v0_6 + STARKNET_RPC: ${{ secrets.DEV_SEPOLIA_URL }}/v0_7 dev-starknet-js-tests: needs: [validate_dev] @@ -87,6 +93,12 @@ jobs: TEST_ACCOUNT_ADDRESS: ${{ secrets.TEST_ACCOUNT_ADDRESS }} TEST_ACCOUNT_PRIVATE_KEY: ${{ secrets.TEST_ACCOUNT_PRIVATE_KEY }} + dev-starknet-go-tests: + needs: [validate_dev] + uses: ./.github/workflows/starknet-go-tests.yml + secrets: + TEST_RPC_URL: ${{ secrets.DEV_SEPOLIA_URL }}/v0_7 + promote_to_staging: needs: [build_docker_image, validate_dev] runs-on: ubuntu-latest @@ -96,19 +108,19 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Setup oras cli + uses: oras-project/setup-oras@v1 + - name: Login to registry run: | - docker login ${{ env.DOCKER_REGISTRY }} -u ${{ vars.ARTIFACTORY_NUBIA_USER }} -p ${{ secrets.ARTIFACTORY_NUBIA_CONTRIBUTOR}} + oras login ${{ env.DOCKER_REGISTRY }} -u ${{ secrets.ARTIFACTORY_NUBIA_USERNAME }} -p ${{ secrets.ARTIFACTORY_NUBIA_TOKEN_DEVELOPER }} - name: Promote to Staging run: | OLD_TAG=${{ env.DOCKER_REGISTRY }}/${{ env.REPO_DEV }}/juno:${{ needs.build_docker_image.outputs.DOCKER_IMAGE_TAG }} NEW_TAG=${{ env.DOCKER_REGISTRY }}/${{ env.REPO_STAGING }}/juno:${{ needs.build_docker_image.outputs.DOCKER_IMAGE_TAG }} - docker pull $OLD_TAG - docker tag $OLD_TAG $NEW_TAG - docker push $NEW_TAG - + oras cp -r $OLD_TAG $NEW_TAG,latest - name: Verify Deployment Version (Staging) run: | bash .github/workflow-scripts/verify_deployment.sh ${{ secrets.STAGING_SEPOLIA_URL }} ${{ needs.build_docker_image.outputs.DOCKER_IMAGE_TAG }} @@ -117,7 +129,7 @@ jobs: needs: [promote_to_staging] uses: ./.github/workflows/starknet-rs-tests.yml secrets: - STARKNET_RPC: ${{ secrets.STAGING_SEPOLIA_URL }}/v0_6 + STARKNET_RPC: ${{ secrets.STAGING_SEPOLIA_URL }}/v0_7 staging-starknet-js-tests: needs: [promote_to_staging] @@ -127,24 +139,31 @@ jobs: TEST_ACCOUNT_ADDRESS: ${{ secrets.TEST_ACCOUNT_ADDRESS }} TEST_ACCOUNT_PRIVATE_KEY: ${{ secrets.TEST_ACCOUNT_PRIVATE_KEY }} + staging-starknet-go-tests: + needs: [promote_to_staging] + uses: ./.github/workflows/starknet-go-tests.yml + secrets: + TEST_RPC_URL: ${{ secrets.STAGING_SEPOLIA_URL }}/v0_7 + promote_to_production: needs: [build_docker_image, promote_to_staging] runs-on: ubuntu-latest environment: name: Production steps: + - name: Setup oras cli + uses: oras-project/setup-oras@v1 + - name: Login to registry run: | - docker login ${{ env.DOCKER_REGISTRY }} -u ${{ vars.ARTIFACTORY_NUBIA_USER }} -p ${{ secrets.ARTIFACTORY_NUBIA_CONTRIBUTOR}} + oras login ${{ env.DOCKER_REGISTRY }} -u ${{ secrets.ARTIFACTORY_NUBIA_USERNAME }} -p ${{ secrets.ARTIFACTORY_NUBIA_TOKEN_DEVELOPER }} - name: Promote to Production run: | OLD_TAG=${{ env.DOCKER_REGISTRY }}/${{ env.REPO_STAGING }}/juno:${{ needs.build_docker_image.outputs.DOCKER_IMAGE_TAG }} NEW_TAG=${{ env.DOCKER_REGISTRY }}/${{ env.REPO_PROD }}/juno:${{ needs.build_docker_image.outputs.DOCKER_IMAGE_TAG }} - docker pull $OLD_TAG - docker tag $OLD_TAG $NEW_TAG - docker push $NEW_TAG + oras cp -r $OLD_TAG $NEW_TAG,latest test_in_production: needs: [promote_to_production] @@ -160,7 +179,7 @@ jobs: needs: [test_in_production] uses: ./.github/workflows/starknet-rs-tests.yml secrets: - STARKNET_RPC: ${{ secrets.PROD_SEPOLIA_URL }}/v0_6 + STARKNET_RPC: ${{ secrets.PROD_SEPOLIA_URL }}/v0_7 prod-starknet-js-tests: needs: [test_in_production] @@ -169,3 +188,9 @@ jobs: TEST_RPC_URL: ${{ secrets.PROD_SEPOLIA_URL }}/v0_7 TEST_ACCOUNT_ADDRESS: ${{ secrets.TEST_ACCOUNT_ADDRESS }} TEST_ACCOUNT_PRIVATE_KEY: ${{ secrets.TEST_ACCOUNT_PRIVATE_KEY }} + + prod-starknet-go-tests: + needs: [test_in_production] + uses: ./.github/workflows/starknet-go-tests.yml + secrets: + TEST_RPC_URL: ${{ secrets.PROD_SEPOLIA_URL }}/v0_7 \ No newline at end of file diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 9efe8a23b9..b6d59e453c 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -38,11 +38,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@5618c9fc1e675841ca52c1c6b1304f5255a905a0 #v2.19.0 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -53,7 +53,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v3 + uses: github/codeql-action/autobuild@5618c9fc1e675841ca52c1c6b1304f5255a905a0 #v2.19.0 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -67,4 +67,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@5618c9fc1e675841ca52c1c6b1304f5255a905a0 #v2.19.0 diff --git a/.github/workflows/docs-deploy.yml b/.github/workflows/docs-deploy.yml index 1452b9c7f1..cf4a5ecda5 100644 --- a/.github/workflows/docs-deploy.yml +++ b/.github/workflows/docs-deploy.yml @@ -3,12 +3,16 @@ name: Deploy Documentation to GitHub Pages on: push: branches: - main + - main workflow_dispatch: permissions: contents: write +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: deploy: name: Deploy to GitHub Pages diff --git a/.github/workflows/docs-test.yml b/.github/workflows/docs-test.yml index 6b8870c96a..00e3f55ac7 100644 --- a/.github/workflows/docs-test.yml +++ b/.github/workflows/docs-test.yml @@ -5,6 +5,10 @@ on: branches: - main +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: test-deploy: name: Test deployment diff --git a/.github/workflows/find-smallest-rust.yml b/.github/workflows/find-smallest-rust.yml new file mode 100644 index 0000000000..4942f8c7a3 --- /dev/null +++ b/.github/workflows/find-smallest-rust.yml @@ -0,0 +1,55 @@ +name: Minimum Supported Rust + +on: + pull_request: + branches: + - main + paths: + - .github/workflows/find-smallest-rust.yml + - core/rust/* + - vm/rust/* + - starknet/compiler/rust/* + workflow_dispatch: + + +permissions: + issues: write # Required for sending comments + pull-requests: write # Required for sending comments + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + find-smallest-rust: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Find smallest supported Rust version + id: rust-version + uses: derrix060/detect-rust-minimum-version@v1 + with: + paths: core/rust/,vm/rust/,starknet/compiler/rust/ + - name: Send notification on PR + uses: actions/github-script@v7 + with: + script: | + const msrv = '${{ steps.rust-version.outputs.highest-msrv }}' + const previous_msrv = '1.80.1' + + if (msrv != previous_msrv) { + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'Minimum supported Rust version is `' + msrv + '`, previous `' + previous_msrv + '`. Please update the README file, the Makefile, and this workflow.' + }) + } + + - name: "Check README and Makefile" + run: | + set -euxo pipefail + echo "Checking if version is set in README" + cat README.md | grep "\[Rust\]" | grep "${{ steps.rust-version.outputs.highest-msrv }}" + echo "Checking makefile" + cat Makefile | grep "MINIMUM_RUST_VERSION = ${{ steps.rust-version.outputs.highest-msrv }}" diff --git a/.github/workflows/juno-lint.yml b/.github/workflows/juno-lint.yml index 80d0b6a31a..c33a9944ed 100644 --- a/.github/workflows/juno-lint.yml +++ b/.github/workflows/juno-lint.yml @@ -6,16 +6,22 @@ on: branches: - main pull_request: + permissions: contents: read pull-requests: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: golangci: name: lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v5.0.2 + - uses: actions/setup-go@v5 with: go-version-file: go.mod cache: false diff --git a/.github/workflows/juno-test.yml b/.github/workflows/juno-test.yml index 66591688aa..beb885d78e 100644 --- a/.github/workflows/juno-test.yml +++ b/.github/workflows/juno-test.yml @@ -7,21 +7,24 @@ on: pull_request: workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: test: name: Run Tests strategy: fail-fast: false matrix: - go: ["1.23.0"] - os: [ubuntu-latest, macos-latest, ubuntu-arm64-2-core] + os: [ubuntu-latest, macos-latest, ubuntu-arm64-4-core] runs-on: ${{ matrix.os }} env: VM_DEBUG: true steps: - uses: actions/checkout@v4 - name: Set up go - uses: actions/setup-go@v5.0.2 + uses: actions/setup-go@v5 with: go-version-file: go.mod - uses: dtolnay/rust-toolchain@stable @@ -30,14 +33,14 @@ jobs: workspaces: | vm/rust core/rust - starknet/rust + starknet/compiler/rust - name: Install deps run: make install-deps - name: Install Jemalloc (Linux) if: runner.os == 'Linux' - run: sudo apt-get update -qq && sudo apt-get install -y libjemalloc-dev libjemalloc2 -y + run: sudo apt-get update -qq && sudo apt-get install -y libjemalloc-dev libjemalloc2 libbz2-dev - name: Install dependencies (macOS) if: runner.os == 'macOS' diff --git a/.github/workflows/rpc-tests.yml b/.github/workflows/rpc-tests.yml index 0a2eb26904..e0f336c7c1 100644 --- a/.github/workflows/rpc-tests.yml +++ b/.github/workflows/rpc-tests.yml @@ -23,7 +23,7 @@ jobs: token: ${{ secrets.REPOSITORY_DISPATCH_TOKEN }} - name: Setup Go Environment - uses: actions/setup-go@v5.0.2 + uses: actions/setup-go@v5 with: go-version-file: rpc-tests/go.mod diff --git a/.github/workflows/starknet-go-tests.yml b/.github/workflows/starknet-go-tests.yml new file mode 100644 index 0000000000..7d81979047 --- /dev/null +++ b/.github/workflows/starknet-go-tests.yml @@ -0,0 +1,36 @@ +name: starknet-go tests + +on: + workflow_call: + inputs: + ref: + description: 'The branch, tag or SHA to checkout' + required: false + default: '1ede19210c10f1f1f9c3cb49a42f737cd90eda5e' + type: string + secrets: + TEST_RPC_URL: + required: true + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout the repo + uses: actions/checkout@v4 + with: + repository: NethermindEth/starknet.go + ref: ${{ inputs.ref }} + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.23' + + - name: Install dependencies + run: go mod download + + - name: Test RPC on testnet + run: cd rpc && go test -timeout 1200s -v -env testnet . + env: + INTEGRATION_BASE: ${{ secrets.TEST_RPC_URL }} diff --git a/.github/workflows/starknet-js-tests.yml b/.github/workflows/starknet-js-tests.yml index 279c5acc18..fbcae3d164 100644 --- a/.github/workflows/starknet-js-tests.yml +++ b/.github/workflows/starknet-js-tests.yml @@ -9,7 +9,7 @@ on: required: false TEST_ACCOUNT_PRIVATE_KEY: required: false - + jobs: test: runs-on: ubuntu-latest @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v4 with: repository: starknet-io/starknet.js - ref: v6.6.6 + ref: v6.14.1 - name: Setup Node.js uses: actions/setup-node@v4 @@ -29,8 +29,8 @@ jobs: run: npm ci - name: Run tests - run: npm test -- rpcProvider.test.ts transactionReceipt.test.ts rpcChannel.test.ts defaultProvider.test.ts contract.test.ts cairo1v2.test.ts cairo1v2_typed.test.ts cairo1.test.ts account.test.ts account.starknetId.test.ts --testNamePattern="^(?!.*declare Sierra 1.5.0).*$" + run: npm test -- rpcProvider.test.ts transactionReceipt.test.ts rpcChannel.test.ts defaultProvider.test.ts contract.test.ts cairo1v2.test.ts cairo1v2_typed.test.ts cairo1.test.ts account.test.ts account.starknetId.test.ts --testNamePattern="^(?!.*(declare Sierra 1.5.0|getSyncingStats)).*$" env: TEST_RPC_URL: ${{ secrets.TEST_RPC_URL }} TEST_ACCOUNT_ADDRESS: ${{ secrets.TEST_ACCOUNT_ADDRESS }} - TEST_ACCOUNT_PRIVATE_KEY: ${{ secrets.TEST_ACCOUNT_PRIVATE_KEY }} \ No newline at end of file + TEST_ACCOUNT_PRIVATE_KEY: ${{ secrets.TEST_ACCOUNT_PRIVATE_KEY }} diff --git a/.github/workflows/starknet-rs-tests.yml b/.github/workflows/starknet-rs-tests.yml index 91467d9a73..e70e9ccc55 100644 --- a/.github/workflows/starknet-rs-tests.yml +++ b/.github/workflows/starknet-rs-tests.yml @@ -14,7 +14,7 @@ jobs: uses: actions/checkout@v4 with: repository: xJonathanLEI/starknet-rs - ref: starknet-providers/v0.10.0 + ref: starknet/v0.12.0 - name: Setup Rust uses: actions-rs/toolchain@v1 @@ -29,4 +29,4 @@ jobs: cd ../starknet-accounts && cargo test jsonrpc -- --skip can_declare_cairo0_contract_with_jsonrpc env: STARKNET_RPC: ${{ secrets.STARKNET_RPC }} - RUST_BACKTRACE: full \ No newline at end of file + RUST_BACKTRACE: full diff --git a/.github/workflows/sync_first_100_blocks_smoke_test.yml b/.github/workflows/sync_first_100_blocks_smoke_test.yml index 0ac0e9a933..55948abd1e 100644 --- a/.github/workflows/sync_first_100_blocks_smoke_test.yml +++ b/.github/workflows/sync_first_100_blocks_smoke_test.yml @@ -7,7 +7,11 @@ on: pull_request: branches: - main - + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: run_smoke_tests: runs-on: ubuntu-latest @@ -26,7 +30,7 @@ jobs: uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v5.0.2 + uses: actions/setup-go@v5 with: go-version-file: go.mod cache: true diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml new file mode 100644 index 0000000000..8d020a7808 --- /dev/null +++ b/.github/workflows/trivy.yml @@ -0,0 +1,43 @@ +name: Container Security + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + schedule: + - cron: '29 19 * * 4' + +permissions: + contents: read + +jobs: + build: + permissions: + contents: read + security-events: write + actions: read + name: Build + runs-on: "ubuntu-latest" + steps: + - name: Checkout code + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1 + + - name: Build an image from Dockerfile + run: | + docker build -t docker.io/my-organization/my-app:${{ github.sha }} . + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@915b19bbe73b92a6cf82a1bc12b087c9a19a5fe2 #v0.28.0 + with: + image-ref: 'docker.io/my-organization/my-app:${{ github.sha }}' + format: 'sarif' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + severity: 'CRITICAL,HIGH' + env: + TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db + + - name: Upload Trivy scan results to GitHub Security tab + uses: github/codeql-action/upload-sarif@5618c9fc1e675841ca52c1c6b1304f5255a905a0 #v2.19.1 + with: + sarif_file: 'trivy-results.sarif' diff --git a/.golangci.yaml b/.golangci.yaml index 8838350c20..debb50b506 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -47,6 +47,7 @@ linters-settings: - strings.SplitN govet: + enable: [nilness] shadow: true settings: printf: @@ -67,6 +68,10 @@ linters-settings: exhaustruct: include: [] + gosec: + excludes: + - G115 #TODO: remove after fixing https://github.com/securego/gosec/issues/1212 + linters: disable-all: true enable: @@ -75,7 +80,7 @@ linters: - dogsled - dupl - errcheck - - exportloopref + - copyloopvar - funlen - gochecknoinits - goconst @@ -108,14 +113,12 @@ linters: # don't enable: # - asciicheck - # - scopelint # - gochecknoglobals # - gocognit # - godot # - godox - # - goerr113 + # - err113 # - interfacer - # - maligned # - nestif # - prealloc # - testpackage diff --git a/Dockerfile b/Dockerfile index 30b0c4b551..cb6e537a46 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ ARG VM_DEBUG RUN apt-get -qq update && \ - apt-get -qq install curl build-essential git golang upx-ucl libjemalloc-dev libjemalloc2 -y + apt-get -qq install curl build-essential git golang upx-ucl libjemalloc-dev libjemalloc2 libbz2-dev RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -q -y WORKDIR /app diff --git a/Makefile b/Makefile index 2497df5b26..00e8575c40 100644 --- a/Makefile +++ b/Makefile @@ -13,8 +13,8 @@ endif ifeq ($(shell uname -s),Darwin) export CGO_LDFLAGS=-framework Foundation -framework SystemConfiguration - # Set macOS deployment target in order to avoid linker warnings linke - # "ld: warning: object file XX was built for newer macOS version (14.4) than being linked (14.0)" + # Set macOS deployment target in order to avoid linker warnings linke + # "ld: warning: object file XX was built for newer macOS version (14.4) than being linked (14.0)" export MACOSX_DEPLOYMENT_TARGET=$(shell sw_vers --productVersion) # for test-race we need to pass -ldflags to fix linker warnings on macOS @@ -31,7 +31,7 @@ endif MAKEFLAGS += -j$(NPROCS) -rustdeps: vm core-rust compiler +rustdeps: check-rust vm core-rust compiler juno: rustdeps ## compile @mkdir -p build @@ -41,6 +41,13 @@ juno-cached: @mkdir -p build @go build $(GO_TAGS) -ldflags="-X main.Version=$(shell git describe --tags)" -o build/juno ./cmd/juno/ + +MINIMUM_RUST_VERSION = 1.80.1 +CURR_RUST_VERSION = $(shell rustc --version | grep -o '[0-9.]\+' | head -n1) +check-rust: ## Ensure rust version is greater than minimum + @echo "Checking if current rust version >= $(MINIMUM_RUST_VERSION)" + @bash -c '[[ $(CURR_RUST_VERSION) < $(MINIMUM_RUST_VERSION) ]] && (echo "Rust version must be >= $(MINIMUM_RUST_VERSION). Found version $(CURR_RUST_VERSION)" && exit 1) || echo "Current rust version is $(CURR_RUST_VERSION)"' + vm: $(MAKE) -C vm/rust $(VM_TARGET) @@ -48,7 +55,7 @@ core-rust: $(MAKE) -C core/rust $(VM_TARGET) compiler: - $(MAKE) -C starknet/rust $(VM_TARGET) + $(MAKE) -C starknet/compiler/rust $(VM_TARGET) generate: ## generate mkdir -p mocks @@ -74,7 +81,7 @@ test-cover: clean-testcache rustdeps ## tests with coverage go test $(GO_TAGS) -coverpkg=./... -coverprofile=coverage/coverage.out -covermode=atomic ./... go tool cover -html=coverage/coverage.out -o coverage/coverage.html -install-deps: | install-gofumpt install-mockgen install-golangci-lint## install some project dependencies +install-deps: | install-gofumpt install-mockgen install-golangci-lint check-rust ## install some project dependencies install-gofumpt: go install mvdan.cc/gofumpt@latest @@ -83,7 +90,7 @@ install-mockgen: go install go.uber.org/mock/mockgen@latest install-golangci-lint: - @which golangci-lint || go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.60.1 + @which golangci-lint || go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.61.0 lint: install-golangci-lint golangci-lint run @@ -94,13 +101,13 @@ tidy: ## add missing and remove unused modules format: ## run go & rust formatters $(MAKE) -C vm/rust format $(MAKE) -C core/rust format - $(MAKE) -C starknet/rust format + $(MAKE) -C starknet/compiler/rust format gofumpt -l -w . clean: ## clean project builds $(MAKE) -C vm/rust clean $(MAKE) -C core/rust clean - $(MAKE) -C starknet/rust clean + $(MAKE) -C starknet/compiler/rust clean @rm -rf ./build help: ## show this help @@ -115,13 +122,8 @@ feedernode: juno-cached --p2p-feeder-node \ --p2p-addr=/ip4/0.0.0.0/tcp/7777 \ --p2p-private-key="5f6cdc3aebcc74af494df054876100368ef6126e3a33fa65b90c765b381ffc37a0a63bbeeefab0740f24a6a38dabb513b9233254ad0020c721c23e69bc820089" \ - --metrics-port=9090 \ - --pprof \ - --pprof-port=9095 node1: juno-cached -# todo remove rm before merge - rm -rf ./p2p-dbs/node1/ && \ ./build/juno \ --network=sepolia \ --log-level=debug \ @@ -167,3 +169,6 @@ pathfinder: juno-cached --p2p-peers=/ip4/127.0.0.1/tcp/8888/p2p/12D3KooWF1JrZWQoBiBSjsFSuLbDiDvqcmJQRLaFQLmpVkHA9duk \ --p2p-private-key="54a695e2a5d5717d5ba8730efcafe6f17251a1955733cffc55a4085fbf7f5d2c1b4009314092069ef7ca9b364ce3eb3072531c64dfb2799c6bad76720a5bdff0" \ --metrics-port=9094 + +test-fuzz: ## run fuzzing script + ./scripts/fuzz_all.sh diff --git a/README.md b/README.md index 7a5413f34d..4f922ff8a4 100644 --- a/README.md +++ b/README.md @@ -47,22 +47,23 @@ - Golang 1.23 or higher is required to build and run the project. You can find the installer on the official Golang [download](https://go.dev/doc/install) page. -- [Rust](https://www.rust-lang.org/tools/install). +- [Rust](https://www.rust-lang.org/tools/install) 1.80.1 or higher. - A C compiler: `gcc` or `clang`. -- Install `jemalloc` and `pkg-config` on your system: +- Install some dependencies on your system: - macOS ```bash brew install jemalloc brew install pkg-config + make install-deps ``` - Ubuntu ```bash - sudo apt-get install -y libjemalloc-dev - sudo apt-get install -y pkg-config + sudo apt-get install -y libjemalloc-dev libjemalloc2 pkg-config libbz2-dev + make install-deps ``` - To ensure a successful build, you either need to synchronize the tags from the upstream repository or create a new tag. @@ -119,6 +120,12 @@ Use the provided snapshots to quickly sync your Juno node with the current state | ------- | ------------- | | **>=v0.9.2** | [**juno_sepolia.tar**](https://juno-snapshots.nethermind.dev/files/sepolia/latest) | +#### Sepolia-Integration + +| Version | Download Link | +| ------- | ------------- | +| **>=v0.9.2** | [**juno_sepolia_integration.tar**](https://juno-snapshots.nethermind.dev/files/sepolia-integration/latest) | + ### Getting the size for each snapshot ```console $date @@ -129,6 +136,9 @@ $curl -s -I -L https://juno-snapshots.nethermind.dev/files/mainnet/latest | gawk $curl -s -I -L https://juno-snapshots.nethermind.dev/files/sepolia/latest | gawk -v IGNORECASE=1 '/^Content-Length/ { printf "%.2f GB\n", $2/1024/1024/1024 }' 5.67 GB + +$curl -s -I -L https://juno-snapshots.nethermind.dev/files/sepolia-integration/latest | gawk -v IGNORECASE=1 '/^Content-Length/ { printf "%.2f GB\n", $2/1024/1024/1024 }' +2.4 GB ``` ### Run Juno Using Snapshot @@ -219,6 +229,7 @@ After following these steps, Juno should be up and running on your machine, util - Starknet state construction and storage using a path-based Merkle Patricia trie. - Feeder gateway synchronisation of Blocks, Transactions, Receipts, State Updates and Classes. - Block and Transaction hash verification. +- Plugins ## 🛣 Roadmap diff --git a/adapters/core2p2p/block.go b/adapters/core2p2p/block.go index 3495df361d..fa3c5b446d 100644 --- a/adapters/core2p2p/block.go +++ b/adapters/core2p2p/block.go @@ -45,16 +45,15 @@ func AdaptHeader(header *core.Header, commitments *core.BlockCommitments, NLeaves: header.EventCount, Root: AdaptHash(commitments.EventCommitment), }, - // todo fill receipts with receipt commitment - Receipts: AdaptHash(&felt.Zero), + Receipts: AdaptHash(commitments.ReceiptCommitment), ProtocolVersion: header.ProtocolVersion, - GasPriceFri: AdaptUint128(header.GasPrice), + GasPriceFri: AdaptUint128(header.GasPriceSTRK), Signatures: utils.Map(header.Signatures, AdaptSignature), StateDiffCommitment: &spec.StateDiffCommitment{ StateDiffLength: stateDiffLength, Root: AdaptHash(stateDiffCommitment), }, - GasPriceWei: AdaptUint128(header.GasPriceSTRK), + GasPriceWei: AdaptUint128(header.GasPrice), DataGasPriceFri: AdaptUint128(header.L1DataGasPrice.PriceInFri), DataGasPriceWei: AdaptUint128(header.L1DataGasPrice.PriceInWei), L1DataAvailabilityMode: adaptL1DA(header.L1DAMode), diff --git a/adapters/core2p2p/receipt.go b/adapters/core2p2p/receipt.go index c45b5354cb..9067524e73 100644 --- a/adapters/core2p2p/receipt.go +++ b/adapters/core2p2p/receipt.go @@ -27,7 +27,7 @@ func AdaptReceipt(r *core.TransactionReceipt, txn core.Transaction) *spec.Receip Type: &spec.Receipt_L1Handler_{ L1Handler: &spec.Receipt_L1Handler{ Common: receiptCommon(r), - MsgHash: &spec.Hash{Elements: t.MessageHash()}, + MsgHash: &spec.Hash256{Elements: t.MessageHash()}, }, }, } @@ -66,6 +66,8 @@ func receiptCommon(r *core.TransactionReceipt) *spec.Receipt_Common { var revertReason *string if r.RevertReason != "" { revertReason = &r.RevertReason + } else if r.Reverted { + revertReason = utils.Ptr("") } return &spec.Receipt_Common{ diff --git a/adapters/p2p2core/block.go b/adapters/p2p2core/block.go index 4b54d12f9a..e593a3d6c8 100644 --- a/adapters/p2p2core/block.go +++ b/adapters/p2p2core/block.go @@ -40,7 +40,6 @@ func AdaptBlockHeader(h *spec.SignedBlockHeader, eventsBloom *bloom.BloomFilter) PriceInWei: AdaptUint128(h.DataGasPriceWei), PriceInFri: AdaptUint128(h.DataGasPriceFri), }, - // todo(kirill) check prices GasPrice: AdaptUint128(h.GasPriceWei), GasPriceSTRK: AdaptUint128(h.GasPriceFri), } diff --git a/adapters/p2p2core/class.go b/adapters/p2p2core/class.go index 40c5a7bc51..3962787253 100644 --- a/adapters/p2p2core/class.go +++ b/adapters/p2p2core/class.go @@ -10,6 +10,7 @@ import ( "github.com/NethermindEth/juno/core/felt" "github.com/NethermindEth/juno/p2p/starknet/spec" "github.com/NethermindEth/juno/starknet" + "github.com/NethermindEth/juno/starknet/compiler" "github.com/NethermindEth/juno/utils" ) @@ -110,7 +111,7 @@ func createCompiledClass(cairo1 *spec.Cairo1Class) (*core.CompiledClass, error) Version: cairo1.ContractClassVersion, } - compiledClass, err := starknet.Compile(def) + compiledClass, err := compiler.Compile(def) if err != nil { return nil, err } diff --git a/adapters/p2p2core/felt.go b/adapters/p2p2core/felt.go index 103e57b399..0d200fcf18 100644 --- a/adapters/p2p2core/felt.go +++ b/adapters/p2p2core/felt.go @@ -1,10 +1,12 @@ package p2p2core import ( + "encoding/binary" + "reflect" + "github.com/NethermindEth/juno/core/felt" "github.com/NethermindEth/juno/p2p/starknet/spec" "github.com/ethereum/go-ethereum/common" - "reflect" ) func AdaptHash(h *spec.Hash) *felt.Felt { @@ -24,6 +26,8 @@ func AdaptFelt(f *spec.Felt252) *felt.Felt { } func adapt(v interface{ GetElements() []byte }) *felt.Felt { + // when passing a nil pointer `v` is boxed to an interface and is not nil + // see: https://blog.devtrovert.com/p/go-secret-interface-nil-is-not-nil if v == nil || reflect.ValueOf(v).IsNil() { return nil } @@ -31,6 +35,14 @@ func adapt(v interface{ GetElements() []byte }) *felt.Felt { } func AdaptUint128(u *spec.Uint128) *felt.Felt { - // todo handle u128 - return &felt.Zero + if u == nil { + return nil + } + + bytes := make([]byte, 16) //nolint:mnd + + binary.BigEndian.PutUint64(bytes[:8], u.High) + binary.BigEndian.PutUint64(bytes[8:], u.Low) + + return new(felt.Felt).SetBytes(bytes) } diff --git a/adapters/p2p2core/felt_test.go b/adapters/p2p2core/felt_test.go new file mode 100644 index 0000000000..46853b06e8 --- /dev/null +++ b/adapters/p2p2core/felt_test.go @@ -0,0 +1,39 @@ +package p2p2core + +import ( + "testing" + + "github.com/NethermindEth/juno/core/felt" + "github.com/NethermindEth/juno/p2p/starknet/spec" + "github.com/NethermindEth/juno/utils" + "github.com/stretchr/testify/assert" +) + +func TestAdaptNilReturnsNil(t *testing.T) { + assert.Nil(t, AdaptHash(nil)) + assert.Nil(t, AdaptAddress(nil)) + assert.Nil(t, AdaptFelt(nil)) +} + +func TestAdaptUint128(t *testing.T) { + t.Run("nil", func(t *testing.T) { + u128 := AdaptUint128(nil) + assert.Nil(t, u128) + }) + t.Run("non-nil", func(t *testing.T) { + cases := []struct { + Low, High uint64 + Expect *felt.Felt + }{ + {32, 64, utils.HexToFelt(t, "0x400000000000000020")}, + } + + for _, c := range cases { + result := AdaptUint128(&spec.Uint128{ + Low: c.Low, + High: c.High, + }) + assert.Equal(t, c.Expect, result, "expected %v actual %v", c.Expect, result) + } + }) +} diff --git a/adapters/p2p2core/receipt.go b/adapters/p2p2core/receipt.go index 66c28a1499..b00ac531aa 100644 --- a/adapters/p2p2core/receipt.go +++ b/adapters/p2p2core/receipt.go @@ -52,15 +52,21 @@ func adaptExecutionResources(er *spec.Receipt_ExecutionResources) *core.Executio Keccak: uint64(er.GetBuiltins().GetKeccak()), Poseidon: uint64(er.GetBuiltins().GetPoseidon()), SegmentArena: 0, // todo(kirill) recheck - // todo(kirill) set fields after spec update - AddMod: 0, - MulMod: 0, - RangeCheck96: 0, + AddMod: uint64(er.GetBuiltins().GetAddMod()), + MulMod: uint64(er.GetBuiltins().GetMulMod()), + RangeCheck96: uint64(er.GetBuiltins().GetRangeCheck96()), + }, + DataAvailability: &core.DataAvailability{ + L1Gas: feltToUint64(er.L1Gas), + L1DataGas: feltToUint64(er.L1DataGas), + }, + MemoryHoles: uint64(er.MemoryHoles), + Steps: uint64(er.Steps), // todo SPEC 32 -> 64 bytes + TotalGasConsumed: &core.GasConsumed{ + L1Gas: feltToUint64(er.TotalL1Gas), + // total_l1_data_gas = l1_data_gas, because there's only one place that can generate l1_data_gas costs + L1DataGas: feltToUint64(er.L1DataGas), }, - DataAvailability: nil, // todo(kirill) recheck - MemoryHoles: uint64(er.MemoryHoles), - Steps: uint64(er.Steps), // todo SPEC 32 -> 64 bytes - TotalGasConsumed: nil, // todo(kirill) fill after spec update } } @@ -71,3 +77,11 @@ func adaptMessageToL1(m *spec.MessageToL1) *core.L2ToL1Message { Payload: utils.Map(m.Payload, AdaptFelt), } } + +func feltToUint64(f *spec.Felt252) uint64 { + var result uint64 + if adapted := AdaptFelt(f); adapted != nil { + result = adapted.Uint64() + } + return result +} diff --git a/adapters/p2p2core/state.go b/adapters/p2p2core/state.go index a51958798c..59bad84772 100644 --- a/adapters/p2p2core/state.go +++ b/adapters/p2p2core/state.go @@ -41,7 +41,9 @@ func AdaptStateDiff(reader core.StateReader, contractDiffs []*spec.ContractDiff, if diff.Nonce != nil { nonces[*address] = AdaptFelt(diff.Nonce) } - storageDiffs[*address] = utils.ToMap(diff.Values, adaptStoredValue) + if diff.Values != nil { + storageDiffs[*address] = utils.ToMap(diff.Values, adaptStoredValue) + } // todo recheck this logic if diff.ClassHash != nil { diff --git a/adapters/vm2core/vm2core.go b/adapters/vm2core/vm2core.go index 3c83713740..3646bd98b1 100644 --- a/adapters/vm2core/vm2core.go +++ b/adapters/vm2core/vm2core.go @@ -21,7 +21,7 @@ func AdaptExecutionResources(resources *vm.ExecutionResources) *core.ExecutionRe Keccak: resources.Keccak, Poseidon: resources.Poseidon, SegmentArena: resources.SegmentArena, - Output: 0, // todo(kirill) recheck, add Output field to core? + Output: resources.Output, AddMod: resources.AddMod, MulMod: resources.MulMod, RangeCheck96: resources.RangeCheck96, diff --git a/adapters/vm2core/vm2core_test.go b/adapters/vm2core/vm2core_test.go index 5a00625220..168cfa07e7 100644 --- a/adapters/vm2core/vm2core_test.go +++ b/adapters/vm2core/vm2core_test.go @@ -75,19 +75,17 @@ func TestAdaptExecutionResources(t *testing.T) { Pedersen: 1, RangeCheck: 2, Bitwise: 3, - Output: 0, Ecsda: 4, EcOp: 5, Keccak: 6, Poseidon: 7, SegmentArena: 8, + Output: 11, }, MemoryHoles: 9, Steps: 10, }, vm2core.AdaptExecutionResources(&vm.ExecutionResources{ ComputationResources: vm.ComputationResources{ - Steps: 10, - MemoryHoles: 9, Pedersen: 1, RangeCheck: 2, Bitwise: 3, @@ -96,6 +94,9 @@ func TestAdaptExecutionResources(t *testing.T) { Keccak: 6, Poseidon: 7, SegmentArena: 8, + MemoryHoles: 9, + Steps: 10, + Output: 11, }, })) } diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go index 36c98946c4..2101f0c3e5 100644 --- a/blockchain/blockchain.go +++ b/blockchain/blockchain.go @@ -891,6 +891,23 @@ func (b *Blockchain) RevertHead() error { return b.database.Update(b.revertHead) } +func (b *Blockchain) GetReverseStateDiff() (*core.StateDiff, error) { + var reverseStateDiff *core.StateDiff + return reverseStateDiff, b.database.View(func(txn db.Transaction) error { + blockNumber, err := chainHeight(txn) + if err != nil { + return err + } + stateUpdate, err := stateUpdateByNumber(txn, blockNumber) + if err != nil { + return err + } + state := core.NewState(txn) + reverseStateDiff, err = state.GetReverseStateDiff(blockNumber, stateUpdate.StateDiff) + return err + }) +} + func (b *Blockchain) revertHead(txn db.Transaction) error { blockNumber, err := chainHeight(txn) if err != nil { @@ -937,7 +954,6 @@ func (b *Blockchain) revertHead(txn db.Transaction) error { } // Revert chain height and pending. - if genesisBlock { if err = txn.Delete(db.Pending.Key()); err != nil { return err diff --git a/clients/feeder/testdata/integration/block/0.json b/clients/feeder/testdata/integration/block/0.json index 33f3c9e317..c653b80951 100644 --- a/clients/feeder/testdata/integration/block/0.json +++ b/clients/feeder/testdata/integration/block/0.json @@ -79,7 +79,11 @@ "ecdsa_builtin": 0, "ec_op_builtin": 0 }, - "n_memory_holes": 0 + "n_memory_holes": 0, + "data_availability": { + "l1_gas": 1, + "l1_data_gas": 2 + } }, "actual_fee": "0x0" }, @@ -99,7 +103,11 @@ "ecdsa_builtin": 0, "ec_op_builtin": 0 }, - "n_memory_holes": 0 + "n_memory_holes": 0, + "data_availability": { + "l1_gas": 2, + "l1_data_gas": 3 + } }, "actual_fee": "0x0" }, @@ -119,7 +127,11 @@ "ecdsa_builtin": 0, "ec_op_builtin": 0 }, - "n_memory_holes": 22 + "n_memory_holes": 22, + "data_availability": { + "l1_gas": 3, + "l1_data_gas": 4 + } }, "actual_fee": "0x0" }, @@ -139,7 +151,11 @@ "ecdsa_builtin": 0, "ec_op_builtin": 0 }, - "n_memory_holes": 22 + "n_memory_holes": 22, + "data_availability": { + "l1_gas": 4, + "l1_data_gas": 5 + } }, "actual_fee": "0x0" } diff --git a/clients/feeder/testdata/integration/block/300000.json b/clients/feeder/testdata/integration/block/300000.json index 0735e9d953..2731155d38 100644 --- a/clients/feeder/testdata/integration/block/300000.json +++ b/clients/feeder/testdata/integration/block/300000.json @@ -1 +1,111 @@ -{"block_hash": "0xe3828bd9154ab385e2cbb95b3b650365fb3c6a4321660d98ce8b0a9194f9a3", "parent_block_hash": "0x3e313bf24e413beadee1bf88590debeffdd7d24c979a7fbf790a3a5c4d9e88f", "block_number": 300000, "state_root": "0x293feec0a25b7134299ded77f1a701ce7da3191d419ef88dc6b9b1c4f9b2f68", "status": "ACCEPTED_ON_L1", "gas_price": "0x277a02decd", "transactions": [{"transaction_hash": "0x2a648ab1aa6847eb38507fc842e050f256562bf87b26083c332f3f21318c2c3", "version": "0x1", "max_fee": "0x2386f26fc10000", "signature": ["0x3e71a0a29877eae7a045b8d5153ca26770e104b1ac7712dc6fdd0f005ab1d37", "0x5e7446beab40bb53324d05be3d8f130a86890895221d00bd8cd2e3839d0593a"], "nonce": "0x39bd", "sender_address": "0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7", "calldata": ["0x1", "0x332299dc083f3778122e5b7762bc9d399da18fefe93769aee67bb49f51c8d2", "0x2d7cf5d5a324a320f9f37804b1615a533fde487400b41af80f13f7ac5581325", "0x0", "0x4", "0x4", "0xaf35ee8ed700ff132c5d1d298a73becda25ccdf9", "0x2", "0x6cd852fe1b2bbd8587bb0aaeb09813436c57c8ce21e75651e317273a1f22228", "0x58feb991988e53fffcba71f6df23c803fb062f1b3bab126d2c9ce574255b36e"], "type": "INVOKE_FUNCTION"}, {"transaction_hash": "0xbc984e8e1fe594dd518a3a51db4f338437a5d2fbdda772d4426b532a67ffff", "version": "0x1", "max_fee": "0x2386f26fc10000", "signature": ["0x36faaf651e7e4a783dacd362bc4853f2906f8ff23f1b8b52ed4b3b3cd51c09f", "0x59b8b785b9b494aa6d6d30a3535e4a649c305643fe6e4c5d3aacefbbae00004"], "nonce": "0x39be", "sender_address": "0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7", "calldata": ["0x1", "0x5f9211b05c9609d54a8bf5f9cfa4e2cd5a3cab3b5d79682c585575495a15dd1", "0x317eb442b72a9fae758d4fb26830ed0d9f31c8e7da4dbff4e8c59ea6a158e7f", "0x0", "0x4", "0x4", "0x447379c077035ef4f442411d0407ce9aa66c558f0060137f6455f4f230eabeb", "0x2", "0x6811b7755a7dd0ec1fb6f51a883e3f255368e2dfd497b5f6480c00cf9cd5a2e", "0x23b9e26720dd7aaf98c7cea56499f48f75dc1d4123f7e2d6c23bfc4d5f4a336"], "type": "INVOKE_FUNCTION"}], "timestamp": 1688044916, "sequencer_address": "0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8", "transaction_receipts": [{"execution_status": "SUCCEEDED", "transaction_index": 0, "transaction_hash": "0x2a648ab1aa6847eb38507fc842e050f256562bf87b26083c332f3f21318c2c3", "l2_to_l1_messages": [{"from_address": "0x332299dc083f3778122e5b7762bc9d399da18fefe93769aee67bb49f51c8d2", "to_address": "0xAf35eE8eD700ff132C5d1d298A73BECdA25ccDF9", "payload": ["0x6cd852fe1b2bbd8587bb0aaeb09813436c57c8ce21e75651e317273a1f22228", "0x58feb991988e53fffcba71f6df23c803fb062f1b3bab126d2c9ce574255b36e"]}], "events": [], "execution_resources": {"n_steps": 374, "builtin_instance_counter": {"range_check_builtin": 7}, "n_memory_holes": 4}, "actual_fee": "0x127089df3a1984"}, {"execution_status": "SUCCEEDED", "transaction_index": 1, "transaction_hash": "0xbc984e8e1fe594dd518a3a51db4f338437a5d2fbdda772d4426b532a67ffff", "l2_to_l1_messages": [], "events": [], "execution_resources": {"n_steps": 307, "builtin_instance_counter": {"range_check_builtin": 9, "pedersen_builtin": 2}, "n_memory_holes": 25}, "actual_fee": "0x3b2d25cd7bccc"}], "starknet_version": "0.12.0"} \ No newline at end of file +{ + "block_hash": "0xe3828bd9154ab385e2cbb95b3b650365fb3c6a4321660d98ce8b0a9194f9a3", + "parent_block_hash": "0x3e313bf24e413beadee1bf88590debeffdd7d24c979a7fbf790a3a5c4d9e88f", + "block_number": 300000, + "state_root": "0x293feec0a25b7134299ded77f1a701ce7da3191d419ef88dc6b9b1c4f9b2f68", + "status": "ACCEPTED_ON_L1", + "gas_price": "0x277a02decd", + "transactions": [ + { + "transaction_hash": "0x2a648ab1aa6847eb38507fc842e050f256562bf87b26083c332f3f21318c2c3", + "version": "0x1", + "max_fee": "0x2386f26fc10000", + "signature": [ + "0x3e71a0a29877eae7a045b8d5153ca26770e104b1ac7712dc6fdd0f005ab1d37", + "0x5e7446beab40bb53324d05be3d8f130a86890895221d00bd8cd2e3839d0593a" + ], + "nonce": "0x39bd", + "sender_address": "0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7", + "calldata": [ + "0x1", + "0x332299dc083f3778122e5b7762bc9d399da18fefe93769aee67bb49f51c8d2", + "0x2d7cf5d5a324a320f9f37804b1615a533fde487400b41af80f13f7ac5581325", + "0x0", + "0x4", + "0x4", + "0xaf35ee8ed700ff132c5d1d298a73becda25ccdf9", + "0x2", + "0x6cd852fe1b2bbd8587bb0aaeb09813436c57c8ce21e75651e317273a1f22228", + "0x58feb991988e53fffcba71f6df23c803fb062f1b3bab126d2c9ce574255b36e" + ], + "type": "INVOKE_FUNCTION" + }, + { + "transaction_hash": "0xbc984e8e1fe594dd518a3a51db4f338437a5d2fbdda772d4426b532a67ffff", + "version": "0x1", + "max_fee": "0x2386f26fc10000", + "signature": [ + "0x36faaf651e7e4a783dacd362bc4853f2906f8ff23f1b8b52ed4b3b3cd51c09f", + "0x59b8b785b9b494aa6d6d30a3535e4a649c305643fe6e4c5d3aacefbbae00004" + ], + "nonce": "0x39be", + "sender_address": "0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7", + "calldata": [ + "0x1", + "0x5f9211b05c9609d54a8bf5f9cfa4e2cd5a3cab3b5d79682c585575495a15dd1", + "0x317eb442b72a9fae758d4fb26830ed0d9f31c8e7da4dbff4e8c59ea6a158e7f", + "0x0", + "0x4", + "0x4", + "0x447379c077035ef4f442411d0407ce9aa66c558f0060137f6455f4f230eabeb", + "0x2", + "0x6811b7755a7dd0ec1fb6f51a883e3f255368e2dfd497b5f6480c00cf9cd5a2e", + "0x23b9e26720dd7aaf98c7cea56499f48f75dc1d4123f7e2d6c23bfc4d5f4a336" + ], + "type": "INVOKE_FUNCTION" + } + ], + "timestamp": 1688044916, + "sequencer_address": "0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8", + "transaction_receipts": [ + { + "execution_status": "SUCCEEDED", + "transaction_index": 0, + "transaction_hash": "0x2a648ab1aa6847eb38507fc842e050f256562bf87b26083c332f3f21318c2c3", + "l2_to_l1_messages": [ + { + "from_address": "0x332299dc083f3778122e5b7762bc9d399da18fefe93769aee67bb49f51c8d2", + "to_address": "0xAf35eE8eD700ff132C5d1d298A73BECdA25ccDF9", + "payload": [ + "0x6cd852fe1b2bbd8587bb0aaeb09813436c57c8ce21e75651e317273a1f22228", + "0x58feb991988e53fffcba71f6df23c803fb062f1b3bab126d2c9ce574255b36e" + ] + } + ], + "events": [], + "execution_resources": { + "n_steps": 374, + "builtin_instance_counter": { + "range_check_builtin": 7 + }, + "n_memory_holes": 4, + "data_availability": { + "l1_gas": 1, + "l1_data_gas": 2 + } + }, + "actual_fee": "0x127089df3a1984" + }, + { + "execution_status": "SUCCEEDED", + "transaction_index": 1, + "transaction_hash": "0xbc984e8e1fe594dd518a3a51db4f338437a5d2fbdda772d4426b532a67ffff", + "l2_to_l1_messages": [], + "events": [], + "execution_resources": { + "n_steps": 307, + "builtin_instance_counter": { + "range_check_builtin": 9, + "pedersen_builtin": 2 + }, + "n_memory_holes": 25, + "data_availability": { + "l1_gas": 2, + "l1_data_gas": 3 + } + }, + "actual_fee": "0x3b2d25cd7bccc" + } + ], + "starknet_version": "0.12.0" +} \ No newline at end of file diff --git a/cmd/juno/dbcmd.go b/cmd/juno/dbcmd.go index be3d51b64e..4fe5cd3a81 100644 --- a/cmd/juno/dbcmd.go +++ b/cmd/juno/dbcmd.go @@ -15,6 +15,10 @@ import ( "github.com/spf13/cobra" ) +const ( + dbRevertToBlockF = "to-block" +) + type DBInfo struct { Network string `json:"network"` ChainHeight uint64 `json:"chain_height"` @@ -33,7 +37,7 @@ func DBCmd(defaultDBPath string) *cobra.Command { } dbCmd.PersistentFlags().String(dbPathF, defaultDBPath, dbPathUsage) - dbCmd.AddCommand(DBInfoCmd(), DBSizeCmd()) + dbCmd.AddCommand(DBInfoCmd(), DBSizeCmd(), DBRevertCmd()) return dbCmd } @@ -55,21 +59,29 @@ func DBSizeCmd() *cobra.Command { } } +func DBRevertCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "revert", + Short: "Revert current head to given position", + Long: `This subcommand revert all data related to all blocks till given so it becomes new head.`, + RunE: dbRevert, + } + cmd.Flags().Uint64(dbRevertToBlockF, 0, "New head (this block won't be reverted)") + + return cmd +} + func dbInfo(cmd *cobra.Command, args []string) error { dbPath, err := cmd.Flags().GetString(dbPathF) if err != nil { return err } - if _, err = os.Stat(dbPath); os.IsNotExist(err) { - fmt.Fprintln(cmd.OutOrStdout(), "Database path does not exist") - return nil - } - - database, err := pebble.New(dbPath) + database, err := openDB(dbPath) if err != nil { - return fmt.Errorf("open DB: %w", err) + return err } + defer database.Close() chain := blockchain.New(database, nil) info := DBInfo{} @@ -110,6 +122,50 @@ func dbInfo(cmd *cobra.Command, args []string) error { return nil } +func dbRevert(cmd *cobra.Command, args []string) error { + dbPath, err := cmd.Flags().GetString(dbPathF) + if err != nil { + return err + } + + revertToBlock, err := cmd.Flags().GetUint64(dbRevertToBlockF) + if err != nil { + return err + } + + if revertToBlock == 0 { + return fmt.Errorf("--%v cannot be 0", dbRevertToBlockF) + } + + database, err := openDB(dbPath) + if err != nil { + return err + } + defer database.Close() + + for { + chain := blockchain.New(database, nil) + head, err := chain.Head() + if err != nil { + return fmt.Errorf("failed to get the latest block information: %v", err) + } + + if head.Number == revertToBlock { + fmt.Fprintf(cmd.OutOrStdout(), "Successfully reverted all blocks to %d\n", revertToBlock) + break + } + + err = chain.RevertHead() + if err != nil { + return fmt.Errorf("failed to revert head at block %d: %v", head.Number, err) + } + + fmt.Fprintf(cmd.OutOrStdout(), "Reverted head at block %d\n", head.Number) + } + + return nil +} + func dbSize(cmd *cobra.Command, args []string) error { dbPath, err := cmd.Flags().GetString(dbPathF) if err != nil { @@ -120,15 +176,11 @@ func dbSize(cmd *cobra.Command, args []string) error { return fmt.Errorf("--%v cannot be empty", dbPathF) } - if _, err = os.Stat(dbPath); os.IsNotExist(err) { - fmt.Fprintln(cmd.OutOrStdout(), "Database path does not exist") - return nil - } - - pebbleDB, err := pebble.New(dbPath) + pebbleDB, err := openDB(dbPath) if err != nil { return err } + defer pebbleDB.Close() var ( totalSize utils.DataSize @@ -201,3 +253,17 @@ func getNetwork(head *core.Block, stateDiff *core.StateDiff) string { return "unknown" } + +func openDB(path string) (db.DB, error) { + _, err := os.Stat(path) + if os.IsNotExist(err) { + return nil, fmt.Errorf("database path does not exist") + } + + database, err := pebble.New(path) + if err != nil { + return nil, fmt.Errorf("failed to open db: %w", err) + } + + return database, nil +} diff --git a/cmd/juno/dbcmd_test.go b/cmd/juno/dbcmd_test.go index 3491923962..454774e85f 100644 --- a/cmd/juno/dbcmd_test.go +++ b/cmd/juno/dbcmd_test.go @@ -2,6 +2,7 @@ package main_test import ( "context" + "strconv" "testing" "github.com/NethermindEth/juno/blockchain" @@ -12,6 +13,7 @@ import ( adaptfeeder "github.com/NethermindEth/juno/starknetdata/feeder" "github.com/NethermindEth/juno/utils" "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -27,27 +29,69 @@ func TestDBCmd(t *testing.T) { cmd := juno.DBSizeCmd() executeCmdInDB(t, cmd) }) + + t.Run("revert db by 1 block", func(t *testing.T) { + network := utils.Mainnet + + const ( + syncToBlock = uint64(2) + revertToBlock = syncToBlock - 1 + ) + + cmd := juno.DBRevertCmd() + cmd.Flags().String("db-path", "", "") + + dbPath := prepareDB(t, &network, syncToBlock) + + require.NoError(t, cmd.Flags().Set("db-path", dbPath)) + require.NoError(t, cmd.Flags().Set("to-block", strconv.Itoa(int(revertToBlock)))) + require.NoError(t, cmd.Execute()) + + // unfortunately we cannot use blockchain from prepareDB because + // inside revert cmd another pebble instance is used which will panic if there are other instances + // that use the same db path + db, err := pebble.New(dbPath) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, db.Close()) + }) + + chain := blockchain.New(db, &network) + block, err := chain.Head() + require.NoError(t, err) + assert.Equal(t, revertToBlock, block.Number) + }) } func executeCmdInDB(t *testing.T, cmd *cobra.Command) { cmd.Flags().String("db-path", "", "") - client := feeder.NewTestClient(t, &utils.Mainnet) - gw := adaptfeeder.New(client) - block0, err := gw.BlockByNumber(context.Background(), 0) - require.NoError(t, err) + dbPath := prepareDB(t, &utils.Mainnet, 0) - stateUpdate0, err := gw.StateUpdate(context.Background(), 0) - require.NoError(t, err) + require.NoError(t, cmd.Flags().Set("db-path", dbPath)) + require.NoError(t, cmd.Execute()) +} + +func prepareDB(t *testing.T, network *utils.Network, syncToBlock uint64) string { + client := feeder.NewTestClient(t, network) + gw := adaptfeeder.New(client) dbPath := t.TempDir() testDB, err := pebble.New(dbPath) require.NoError(t, err) - chain := blockchain.New(testDB, &utils.Mainnet) - require.NoError(t, chain.Store(block0, &emptyCommitments, stateUpdate0, nil)) - testDB.Close() + chain := blockchain.New(testDB, network) - require.NoError(t, cmd.Flags().Set("db-path", dbPath)) - require.NoError(t, cmd.Execute()) + for blockNumber := uint64(0); blockNumber <= syncToBlock; blockNumber++ { + block, err := gw.BlockByNumber(context.Background(), blockNumber) + require.NoError(t, err) + + stateUpdate, err := gw.StateUpdate(context.Background(), blockNumber) + require.NoError(t, err) + + require.NoError(t, chain.Store(block, &emptyCommitments, stateUpdate, nil)) + } + require.NoError(t, testDB.Close()) + + return dbPath } diff --git a/cmd/juno/juno.go b/cmd/juno/juno.go index 75fb7d3fea..fd957bf863 100644 --- a/cmd/juno/juno.go +++ b/cmd/juno/juno.go @@ -82,6 +82,7 @@ const ( callMaxStepsF = "rpc-call-max-steps" corsEnableF = "rpc-cors-enable" versionedConstantsFileF = "versioned-constants-file" + pluginPathF = "plugin-path" p2pSyncModeF = "p2p-sync-mode" defaultConfig = "" @@ -120,6 +121,7 @@ const ( defaultGwTimeout = 5 * time.Second defaultCorsEnable = false defaultVersionedConstantsFile = "" + defaultPluginPath = "" defaultP2pSyncMode = "full" configFlagUsage = "The YAML configuration file." @@ -173,6 +175,7 @@ const ( "The upper limit is 4 million steps, and any higher value will still be capped at 4 million." corsEnableUsage = "Enable CORS on RPC endpoints" versionedConstantsFileUsage = "Use custom versioned constants from provided file" + pluginPathUsage = "Path to the plugin .so file" ) var Version string @@ -359,6 +362,7 @@ func NewCmd(config *node.Config, run func(*cobra.Command, []string) error) *cobr junoCmd.Flags().Bool(corsEnableF, defaultCorsEnable, corsEnableUsage) junoCmd.Flags().String(versionedConstantsFileF, defaultVersionedConstantsFile, versionedConstantsFileUsage) junoCmd.MarkFlagsMutuallyExclusive(p2pFeederNodeF, p2pPeersF) + junoCmd.Flags().String(pluginPathF, defaultPluginPath, pluginPathUsage) junoCmd.AddCommand(GenP2PKeyPair(), DBCmd(defaultDBPath)) diff --git a/core/block.go b/core/block.go index b9ff81e2af..d9fa02e2fd 100644 --- a/core/block.go +++ b/core/block.go @@ -127,19 +127,6 @@ func VerifyBlockHash(b *Block, network *utils.Network, stateDiff *StateDiff) (*B return nil, errors.New("can not verify hash in block header") } -// BlockHash assumes block.SequencerAddress is not nil as this is called with post v0.12.0 -// and by then issues with unverifiable block hash were resolved. -// In future, this may no longer be required. -// Todo: Pass stateDiff so that p2p layer can calculate post 0.13.2 Block Hash -func BlockHash(b *Block) (*felt.Felt, error) { - if b.SequencerAddress == nil { - return nil, errors.New("block.SequencerAddress is nil") - } - - h, _, err := post07Hash(b, nil) - return h, err -} - // blockHash computes the block hash, with option to override sequence address func blockHash(b *Block, stateDiff *StateDiff, network *utils.Network, overrideSeqAddr *felt.Felt) (*felt.Felt, *BlockCommitments, error, @@ -254,8 +241,8 @@ func post07Hash(b *Block, overrideSeqAddr *felt.Felt) (*felt.Felt, *BlockCommitm } wg := conc.NewWaitGroup() - var txCommitment, eCommitment *felt.Felt - var tErr, eErr error + var txCommitment, eCommitment, rCommitment *felt.Felt + var tErr, eErr, rErr error wg.Go(func() { txCommitment, tErr = transactionCommitmentPedersen(b.Transactions, b.Header.ProtocolVersion) @@ -263,6 +250,11 @@ func post07Hash(b *Block, overrideSeqAddr *felt.Felt) (*felt.Felt, *BlockCommitm wg.Go(func() { eCommitment, eErr = eventCommitmentPedersen(b.Receipts) }) + wg.Go(func() { + // even though rCommitment is not required for pre 0.13.2 hash + // we need to calculate it for BlockCommitments that will be stored in db + rCommitment, rErr = receiptCommitment(b.Receipts) + }) wg.Wait() if tErr != nil { @@ -271,6 +263,9 @@ func post07Hash(b *Block, overrideSeqAddr *felt.Felt) (*felt.Felt, *BlockCommitm if eErr != nil { return nil, nil, eErr } + if rErr != nil { + return nil, nil, rErr + } // Unlike the pre07Hash computation, we exclude the chain // id and replace the zero felt with the actual values for: @@ -290,7 +285,7 @@ func post07Hash(b *Block, overrideSeqAddr *felt.Felt) (*felt.Felt, *BlockCommitm &felt.Zero, // reserved: protocol version &felt.Zero, // reserved: extra data b.ParentHash, // parent block hash - ), &BlockCommitments{TransactionCommitment: txCommitment, EventCommitment: eCommitment}, nil + ), &BlockCommitments{TransactionCommitment: txCommitment, EventCommitment: eCommitment, ReceiptCommitment: rCommitment}, nil } func MarshalBlockNumber(blockNumber uint64) []byte { diff --git a/core/block_pkg_test.go b/core/block_pkg_test.go new file mode 100644 index 0000000000..adc58dfc95 --- /dev/null +++ b/core/block_pkg_test.go @@ -0,0 +1,63 @@ +package core + +import ( + "testing" + + "github.com/NethermindEth/juno/core/felt" + "github.com/NethermindEth/juno/utils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestTransactionCommitmentPoseidon(t *testing.T) { + t.Run("nil", func(t *testing.T) { + c, err := transactionCommitmentPoseidon(nil) + require.NoError(t, err) + assert.Equal(t, &felt.Zero, c) + }) + t.Run("txs with signature", func(t *testing.T) { + var txs []Transaction + + type signature = []*felt.Felt + // actual tx hash is irrelevant so it's ok to have different transactions with the same hash + txHash := utils.HexToFelt(t, "0xCAFEBABE") + // nil signature, empty signature and signature with some non-empty value + for _, sign := range []signature{nil, make(signature, 0), {new(felt.Felt).SetUint64(uint64(3))}} { + invoke := &InvokeTransaction{ + TransactionHash: txHash, + TransactionSignature: sign, + } + deployAccount := &DeployAccountTransaction{ + DeployTransaction: DeployTransaction{ + TransactionHash: txHash, + }, + TransactionSignature: sign, + } + declare := &DeclareTransaction{ + TransactionHash: txHash, + TransactionSignature: sign, + } + txs = append(txs, invoke, deployAccount, declare) + } + + c, err := transactionCommitmentPoseidon(txs) + require.NoError(t, err) + expected := utils.HexToFelt(t, "0x68303856fce63d62acb85da0766b370c03754aa316b0b5bce05982f9561b73d") + assert.Equal(t, expected, c, "expected: %s, got: %s", expected, c) + }) + t.Run("txs without signature", func(t *testing.T) { + txs := []Transaction{ + &L1HandlerTransaction{ + TransactionHash: utils.HexToFelt(t, "0x1"), + }, + &DeployTransaction{ + TransactionHash: utils.HexToFelt(t, "0x2"), + }, + } + + c, err := transactionCommitmentPoseidon(txs) + require.NoError(t, err) + expected := utils.HexToFelt(t, "0x6e067f82eefc8efa75b4ad389253757f4992eee0f81f0b43815fa56135ca801") + assert.Equal(t, expected, c, "expected: %s, got: %s", expected, c) + }) +} diff --git a/core/block_test.go b/core/block_test.go index 55a09fd171..068bd50666 100644 --- a/core/block_test.go +++ b/core/block_test.go @@ -267,17 +267,3 @@ func Test0132BlockHash(t *testing.T) { }) } } - -func TestBlockHashP2P(t *testing.T) { - mainnetGW := adaptfeeder.New(feeder.NewTestClient(t, &utils.Mainnet)) - - t.Run("error if block.SequencerAddress is nil", func(t *testing.T) { - mainnetBlock1, err := mainnetGW.BlockByNumber(context.Background(), 1) - require.NoError(t, err) - - mainnetBlock1.SequencerAddress = nil - - _, err = core.BlockHash(mainnetBlock1) - assert.EqualError(t, err, "block.SequencerAddress is nil") - }) -} diff --git a/core/class_test.go b/core/class_test.go index a0aad1464b..599651202c 100644 --- a/core/class_test.go +++ b/core/class_test.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "reflect" "testing" "github.com/NethermindEth/juno/clients/feeder" @@ -168,7 +167,6 @@ func TestClassEncoding(t *testing.T) { func checkClassSymmetry(t *testing.T, input core.Class) { t.Helper() - require.NoError(t, encoder.RegisterType(reflect.TypeOf(input))) data, err := encoder.Marshal(input) require.NoError(t, err) diff --git a/core/receipt.go b/core/receipt.go index 0984118c28..0e0f071f96 100644 --- a/core/receipt.go +++ b/core/receipt.go @@ -1,6 +1,9 @@ package core import ( + "runtime" + "sync" + "github.com/NethermindEth/juno/core/crypto" "github.com/NethermindEth/juno/core/felt" "github.com/NethermindEth/juno/core/trie" @@ -61,13 +64,49 @@ func messagesSentHash(messages []*L2ToL1Message) *felt.Felt { } func receiptCommitment(receipts []*TransactionReceipt) (*felt.Felt, error) { + return calculateCommitment( + receipts, + trie.RunOnTempTriePoseidon, + func(receipt *TransactionReceipt) *felt.Felt { + return receipt.hash() + }, + ) +} + +type ( + onTempTrieFunc func(uint8, func(*trie.Trie) error) error + processFunc[T any] func(T) *felt.Felt +) + +// General function for parallel processing of items and calculation of a commitment +func calculateCommitment[T any](items []T, runOnTempTrie onTempTrieFunc, process processFunc[T]) (*felt.Felt, error) { var commitment *felt.Felt + return commitment, runOnTempTrie(commitmentTrieHeight, func(trie *trie.Trie) error { + numWorkers := min(runtime.GOMAXPROCS(0), len(items)) + results := make([]*felt.Felt, len(items)) + var wg sync.WaitGroup + wg.Add(numWorkers) + + jobs := make(chan int, len(items)) + for idx := range items { + jobs <- idx + } + close(jobs) + + for range numWorkers { + go func() { + defer wg.Done() + for i := range jobs { + results[i] = process(items[i]) + } + }() + } + + wg.Wait() - return commitment, trie.RunOnTempTriePoseidon(commitmentTrieHeight, func(trie *trie.Trie) error { - for i, receipt := range receipts { - receiptTrieKey := new(felt.Felt).SetUint64(uint64(i)) - _, err := trie.Put(receiptTrieKey, receipt.hash()) - if err != nil { + for i, res := range results { + key := new(felt.Felt).SetUint64(uint64(i)) + if _, err := trie.Put(key, res); err != nil { return err } } diff --git a/core/receipt_pkg_test.go b/core/receipt_pkg_test.go new file mode 100644 index 0000000000..2b86d83001 --- /dev/null +++ b/core/receipt_pkg_test.go @@ -0,0 +1,98 @@ +package core + +import ( + "slices" + "testing" + + "github.com/NethermindEth/juno/core/felt" + "github.com/NethermindEth/juno/utils" + "github.com/stretchr/testify/require" +) + +func BenchmarkReceiptCommitment(b *testing.B) { + fromHex := func(hex string) *felt.Felt { + b.Helper() + return utils.HexToFelt(b, hex) + } + // receipts were taken from sepolia block 35748 + // we don't use adaptfeeder here because it causes cyclic import + baseReceipts := []*TransactionReceipt{ + { + TransactionHash: fromHex("0x5ac644bbd6ae98d3be2d988439854e33f0961e24f349a63b43e16d172bfe747"), + Fee: fromHex("0xd07af45c84550"), + Events: []*Event{ + { + From: fromHex("0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"), + Data: []*felt.Felt{ + fromHex("0x472aa8128e01eb0df145810c9511a92852d62a68ba8198ce5fa414e6337a365"), + fromHex("0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8"), + fromHex("0xd07af45c84550"), + fromHex("0x0"), + }, + Keys: []*felt.Felt{ + fromHex("0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"), + }, + }, + }, + ExecutionResources: &ExecutionResources{ + BuiltinInstanceCounter: BuiltinInstanceCounter{ + Pedersen: 16, + RangeCheck: 157, + Ecsda: 1, + Poseidon: 4, + }, + MemoryHoles: 0, + Steps: 3950, + DataAvailability: &DataAvailability{ + L1Gas: 0, + L1DataGas: 192, + }, + TotalGasConsumed: &GasConsumed{ + L1Gas: 117620, + L1DataGas: 192, + }, + }, + }, + { + Fee: fromHex("0x471426f16c4330"), + Events: []*Event{ + { + From: fromHex("0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"), + Data: []*felt.Felt{ + fromHex("0x472aa8128e01eb0df145810c9511a92852d62a68ba8198ce5fa414e6337a365"), + fromHex("0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8"), + fromHex("0x471426f16c4330"), + fromHex("0x0"), + }, + Keys: []*felt.Felt{ + fromHex("0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"), + }, + }, + }, + ExecutionResources: &ExecutionResources{ + BuiltinInstanceCounter: BuiltinInstanceCounter{ + Pedersen: 16, + RangeCheck: 157, + Ecsda: 1, + Poseidon: 4, + }, + Steps: 3950, + DataAvailability: &DataAvailability{ + L1Gas: 0, + L1DataGas: 192, + }, + TotalGasConsumed: &GasConsumed{ + L1Gas: 641644, + L1DataGas: 192, + }, + }, + TransactionHash: fromHex("0x21bc0afe54123b946855e1bf9389d943313df5c5c396fbf0630234a44f6f592"), + }, + } + receipts := slices.Repeat(baseReceipts, 100) + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, err := receiptCommitment(receipts) + require.NoError(b, err) + } +} diff --git a/core/state.go b/core/state.go index 340630b8c3..fb7d8e8c19 100644 --- a/core/state.go +++ b/core/state.go @@ -5,6 +5,7 @@ import ( "encoding/binary" "errors" "fmt" + "maps" "runtime" "slices" "sort" @@ -679,11 +680,7 @@ func (s *State) updateContractStorages(stateTrie *trie.Trie, diffs map[felt.Felt // sort the contracts in decending diff size order // so we start with the heaviest update first - keys := make([]felt.Felt, 0, len(diffs)) - for key := range diffs { - keys = append(keys, key) - } - slices.SortStableFunc(keys, func(a, b felt.Felt) int { return len(diffs[a]) - len(diffs[b]) }) + keys := slices.SortedStableFunc(maps.Keys(diffs), func(a, b felt.Felt) int { return len(diffs[a]) - len(diffs[b]) }) // update per-contract storage Tries concurrently contractUpdaters := pool.NewWithResults[*bufferedTransactionWithAddress]().WithErrors().WithMaxGoroutines(runtime.GOMAXPROCS(0)) @@ -825,10 +822,14 @@ func (s *State) Revert(blockNumber uint64, update *StateUpdate) error { return fmt.Errorf("remove declared classes: %v", err) } - // update contracts - reversedDiff, err := s.buildReverseDiff(blockNumber, update.StateDiff) + reversedDiff, err := s.GetReverseStateDiff(blockNumber, update.StateDiff) + if err != nil { + return fmt.Errorf("error getting reverse state diff: %v", err) + } + + err = s.performStateDeletions(blockNumber, update.StateDiff) if err != nil { - return fmt.Errorf("build reverse diff: %v", err) + return fmt.Errorf("error performing state deletions: %v", err) } stateTrie, storageCloser, err := s.storage() @@ -851,12 +852,17 @@ func (s *State) Revert(blockNumber uint64, update *StateUpdate) error { } } - // purge noClassContracts - // + if err = s.purgeNoClassContracts(); err != nil { + return err + } + + return s.verifyStateUpdateRoot(update.OldRoot) +} + +func (s *State) purgeNoClassContracts() error { // As noClassContracts are not in StateDiff.DeployedContracts we can only purge them if their storage no longer exists. // Updating contracts with reverse diff will eventually lead to the deletion of noClassContract's storage key from db. Thus, // we can use the lack of key's existence as reason for purging noClassContracts. - for addr := range noClassContracts { noClassC, err := NewContractUpdater(&addr, s.txn) if err != nil { @@ -877,8 +883,7 @@ func (s *State) Revert(blockNumber uint64, update *StateUpdate) error { } } } - - return s.verifyStateUpdateRoot(update.OldRoot) + return nil } func (s *State) removeDeclaredClasses(blockNumber uint64, v0Classes []*felt.Felt, v1Classes map[felt.Felt]*felt.Felt) error { @@ -942,7 +947,7 @@ func (s *State) purgeContract(addr *felt.Felt) error { return storageCloser() } -func (s *State) buildReverseDiff(blockNumber uint64, diff *StateDiff) (*StateDiff, error) { +func (s *State) GetReverseStateDiff(blockNumber uint64, diff *StateDiff) (*StateDiff, error) { reversed := *diff // storage diffs @@ -958,10 +963,6 @@ func (s *State) buildReverseDiff(blockNumber uint64, diff *StateDiff) (*StateDif } value = oldValue } - - if err := s.DeleteContractStorageLog(&addr, &key, blockNumber); err != nil { - return nil, err - } reversedDiffs[key] = value } reversed.StorageDiffs[addr] = reversedDiffs @@ -971,7 +972,6 @@ func (s *State) buildReverseDiff(blockNumber uint64, diff *StateDiff) (*StateDif reversed.Nonces = make(map[felt.Felt]*felt.Felt, len(diff.Nonces)) for addr := range diff.Nonces { oldNonce := &felt.Zero - if blockNumber > 0 { var err error oldNonce, err = s.ContractNonceAt(&addr, blockNumber-1) @@ -979,10 +979,6 @@ func (s *State) buildReverseDiff(blockNumber uint64, diff *StateDiff) (*StateDif return nil, err } } - - if err := s.DeleteContractNonceLog(&addr, blockNumber); err != nil { - return nil, err - } reversed.Nonces[addr] = oldNonce } @@ -997,12 +993,35 @@ func (s *State) buildReverseDiff(blockNumber uint64, diff *StateDiff) (*StateDif return nil, err } } + reversed.ReplacedClasses[addr] = classHash + } + + return &reversed, nil +} + +func (s *State) performStateDeletions(blockNumber uint64, diff *StateDiff) error { + // storage diffs + for addr, storageDiffs := range diff.StorageDiffs { + for key := range storageDiffs { + if err := s.DeleteContractStorageLog(&addr, &key, blockNumber); err != nil { + return err + } + } + } + // nonces + for addr := range diff.Nonces { + if err := s.DeleteContractNonceLog(&addr, blockNumber); err != nil { + return err + } + } + + // replaced classes + for addr := range diff.ReplacedClasses { if err := s.DeleteContractClassHashLog(&addr, blockNumber); err != nil { - return nil, err + return err } - reversed.ReplacedClasses[addr] = classHash } - return &reversed, nil + return nil } diff --git a/core/state_test.go b/core/state_test.go index c9333b1c2a..6b96d64b3b 100644 --- a/core/state_test.go +++ b/core/state_test.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "os" "reflect" "testing" @@ -25,6 +26,27 @@ var ( su1FirstDeployedAddress = *_su1FirstDeployedAddress ) +func TestMain(m *testing.M) { + txTypes := []core.Transaction{ + &core.DeclareTransaction{}, + &core.DeployTransaction{}, + &core.InvokeTransaction{}, + &core.L1HandlerTransaction{}, + &core.DeployAccountTransaction{}, + } + + for _, tx := range txTypes { + _ = encoder.RegisterType(reflect.TypeOf(tx)) + } + + _ = encoder.RegisterType(reflect.TypeOf(core.Cairo0Class{})) + _ = encoder.RegisterType(reflect.TypeOf(core.Cairo1Class{})) + + code := m.Run() + + os.Exit(code) +} + func TestUpdate(t *testing.T) { client := feeder.NewTestClient(t, &utils.Mainnet) gw := adaptfeeder.New(client) @@ -380,15 +402,6 @@ func TestClass(t *testing.T) { cairo1Class, err := gw.Class(context.Background(), cairo0Hash) require.NoError(t, err) - err = encoder.RegisterType(reflect.TypeOf(cairo0Class)) - if err != nil { - require.Contains(t, err.Error(), "already exists in TagSet") - } - err = encoder.RegisterType(reflect.TypeOf(cairo1Hash)) - if err != nil { - require.Contains(t, err.Error(), "already exists in TagSet") - } - state := core.NewState(txn) su0, err := gw.StateUpdate(context.Background(), 0) require.NoError(t, err) diff --git a/core/state_update.go b/core/state_update.go index 50501e9479..45ceeb53a4 100644 --- a/core/state_update.go +++ b/core/state_update.go @@ -143,12 +143,7 @@ func (d *StateDiff) Commitment() *felt.Felt { } func sortedFeltKeys[V any](m map[felt.Felt]V) []felt.Felt { - keys := make([]felt.Felt, 0, len(m)) - for addr := range m { - keys = append(keys, addr) - } - slices.SortFunc(keys, func(a, b felt.Felt) int { return a.Cmp(&b) }) - return keys + return slices.SortedFunc(maps.Keys(m), func(a, b felt.Felt) int { return a.Cmp(&b) }) } func updatedContractsDigest(deployedContracts, replacedClasses map[felt.Felt]*felt.Felt, digest *crypto.PoseidonDigest) { diff --git a/core/transaction.go b/core/transaction.go index 5ab0a9cd9b..7dfe9d76e4 100644 --- a/core/transaction.go +++ b/core/transaction.go @@ -5,10 +5,8 @@ import ( "errors" "fmt" "math/big" - "runtime" "slices" "strings" - "sync" "github.com/Masterminds/semver/v3" "github.com/NethermindEth/juno/core/crypto" @@ -18,7 +16,6 @@ import ( "github.com/bits-and-blooms/bloom/v3" "github.com/ethereum/go-ethereum/common" "github.com/fxamacker/cbor/v2" - "github.com/sourcegraph/conc/pool" "golang.org/x/crypto/sha3" ) @@ -632,61 +629,42 @@ const commitmentTrieHeight = 64 // transactionCommitmentPedersen is the root of a height 64 binary Merkle Patricia tree of the // transaction hashes and signatures in a block. func transactionCommitmentPedersen(transactions []Transaction, protocolVersion string) (*felt.Felt, error) { - var commitment *felt.Felt + blockVersion, err := ParseBlockVersion(protocolVersion) + if err != nil { + return nil, err + } + v0_11_1 := semver.MustParse("0.11.1") - return commitment, trie.RunOnTempTriePedersen(commitmentTrieHeight, func(trie *trie.Trie) error { - blockVersion, err := ParseBlockVersion(protocolVersion) - if err != nil { - return err + var hashFunc processFunc[Transaction] + if blockVersion.GreaterThanEqual(v0_11_1) { + hashFunc = func(transaction Transaction) *felt.Felt { + signatureHash := crypto.PedersenArray(transaction.Signature()...) + return crypto.Pedersen(transaction.Hash(), signatureHash) } - - for i, transaction := range transactions { + } else { + hashFunc = func(transaction Transaction) *felt.Felt { signatureHash := crypto.PedersenArray() - - // blockVersion >= 0.11.1 - if blockVersion.Compare(v0_11_1) != -1 { - signatureHash = crypto.PedersenArray(transaction.Signature()...) - } else if _, ok := transaction.(*InvokeTransaction); ok { + if _, ok := transaction.(*InvokeTransaction); ok { signatureHash = crypto.PedersenArray(transaction.Signature()...) } - - if _, err = trie.Put(new(felt.Felt).SetUint64(uint64(i)), - crypto.Pedersen(transaction.Hash(), signatureHash)); err != nil { - return err - } - } - root, err := trie.Root() - if err != nil { - return err + return crypto.Pedersen(transaction.Hash(), signatureHash) } - commitment = root - return nil - }) + } + return calculateCommitment(transactions, trie.RunOnTempTriePedersen, hashFunc) } func transactionCommitmentPoseidon(transactions []Transaction) (*felt.Felt, error) { - var commitment *felt.Felt - return commitment, trie.RunOnTempTriePoseidon(commitmentTrieHeight, func(trie *trie.Trie) error { - for i, transaction := range transactions { - var digest crypto.PoseidonDigest - digest.Update(transaction.Hash()) - - if txSignature := transaction.Signature(); len(txSignature) > 0 { - digest.Update(txSignature...) - } else { - digest.Update(&felt.Zero) - } - - if _, err := trie.Put(new(felt.Felt).SetUint64(uint64(i)), digest.Finish()); err != nil { - return err - } + return calculateCommitment(transactions, trie.RunOnTempTriePoseidon, func(transaction Transaction) *felt.Felt { + var digest crypto.PoseidonDigest + digest.Update(transaction.Hash()) + + if txSignature := transaction.Signature(); len(txSignature) > 0 { + digest.Update(txSignature...) + } else { + digest.Update(&felt.Zero) } - root, err := trie.Root() - if err != nil { - return err - } - commitment = root - return nil + + return digest.Finish() }) } @@ -705,125 +683,60 @@ func ParseBlockVersion(protocolVersion string) (*semver.Version, error) { return semver.NewVersion(strings.Join(digits[:3], sep)) } +type eventWithTxHash struct { + Event *Event + TxHash *felt.Felt +} + // eventCommitmentPoseidon computes the event commitment for a block. func eventCommitmentPoseidon(receipts []*TransactionReceipt) (*felt.Felt, error) { - var commitment *felt.Felt - return commitment, trie.RunOnTempTriePoseidon(commitmentTrieHeight, func(trie *trie.Trie) error { - eventCount := uint64(0) - numWorkers := runtime.GOMAXPROCS(0) - receiptPerWorker := len(receipts) / numWorkers - if receiptPerWorker == 0 { - receiptPerWorker = 1 - } - workerPool := pool.New().WithErrors().WithMaxGoroutines(numWorkers) - var trieMutex sync.Mutex - - for receiptIdx := range receipts { - if receiptIdx%receiptPerWorker == 0 { - curReceiptIdx := receiptIdx - curEventIdx := eventCount - - workerPool.Go(func() error { - maxIndex := curReceiptIdx + receiptPerWorker - if maxIndex > len(receipts) { - maxIndex = len(receipts) - } - receiptsSliced := receipts[curReceiptIdx:maxIndex] - - for _, receipt := range receiptsSliced { - for _, event := range receipt.Events { - hashElems := []*felt.Felt{event.From, receipt.TransactionHash} - hashElems = append(hashElems, new(felt.Felt).SetUint64(uint64(len(event.Keys)))) - hashElems = append(hashElems, event.Keys...) - hashElems = append(hashElems, new(felt.Felt).SetUint64(uint64(len(event.Data)))) - hashElems = append(hashElems, event.Data...) - - eventHash := crypto.PoseidonArray(hashElems...) - - eventTrieKey := new(felt.Felt).SetUint64(curEventIdx) - trieMutex.Lock() - _, err := trie.Put(eventTrieKey, eventHash) - trieMutex.Unlock() - if err != nil { - return err - } - curEventIdx++ - } - } - return nil - }) - } - eventCount += uint64(len(receipts[receiptIdx].Events)) - } - if err := workerPool.Wait(); err != nil { - return err - } - root, err := trie.Root() - if err != nil { - return err + eventCounter := 0 + for _, receipt := range receipts { + eventCounter += len(receipt.Events) + } + items := make([]*eventWithTxHash, 0, eventCounter) + for _, receipt := range receipts { + for _, event := range receipt.Events { + items = append(items, &eventWithTxHash{ + Event: event, + TxHash: receipt.TransactionHash, + }) } - commitment = root - return nil + } + return calculateCommitment(items, trie.RunOnTempTriePoseidon, func(item *eventWithTxHash) *felt.Felt { + return crypto.PoseidonArray( + slices.Concat( + []*felt.Felt{ + item.Event.From, + item.TxHash, + new(felt.Felt).SetUint64(uint64(len(item.Event.Keys))), + }, + item.Event.Keys, + []*felt.Felt{ + new(felt.Felt).SetUint64(uint64(len(item.Event.Data))), + }, + item.Event.Data, + )..., + ) }) } // eventCommitmentPedersen computes the event commitment for a block. func eventCommitmentPedersen(receipts []*TransactionReceipt) (*felt.Felt, error) { - var commitment *felt.Felt - return commitment, trie.RunOnTempTriePedersen(commitmentTrieHeight, func(trie *trie.Trie) error { - eventCount := uint64(0) - numWorkers := runtime.GOMAXPROCS(0) - receiptPerWorker := len(receipts) / numWorkers - if receiptPerWorker == 0 { - receiptPerWorker = 1 - } - workerPool := pool.New().WithErrors().WithMaxGoroutines(numWorkers) - var trieMutex sync.Mutex - - for receiptIdx := range receipts { - if receiptIdx%receiptPerWorker == 0 { - curReceiptIdx := receiptIdx - curEventIdx := eventCount - - workerPool.Go(func() error { - maxIndex := curReceiptIdx + receiptPerWorker - if maxIndex > len(receipts) { - maxIndex = len(receipts) - } - receiptsSliced := receipts[curReceiptIdx:maxIndex] - - for _, receipt := range receiptsSliced { - for _, event := range receipt.Events { - eventHash := crypto.PedersenArray( - event.From, - crypto.PedersenArray(event.Keys...), - crypto.PedersenArray(event.Data...), - ) - - eventTrieKey := new(felt.Felt).SetUint64(curEventIdx) - trieMutex.Lock() - _, err := trie.Put(eventTrieKey, eventHash) - trieMutex.Unlock() - if err != nil { - return err - } - curEventIdx++ - } - } - return nil - }) - } - eventCount += uint64(len(receipts[receiptIdx].Events)) - } - if err := workerPool.Wait(); err != nil { - return err - } - root, err := trie.Root() - if err != nil { - return err - } - commitment = root - return nil + eventCounter := 0 + for _, receipt := range receipts { + eventCounter += len(receipt.Events) + } + events := make([]*Event, 0, eventCounter) + for _, receipt := range receipts { + events = append(events, receipt.Events...) + } + return calculateCommitment(events, trie.RunOnTempTriePedersen, func(event *Event) *felt.Felt { + return crypto.PedersenArray( + event.From, + crypto.PedersenArray(event.Keys...), + crypto.PedersenArray(event.Data...), + ) }) } diff --git a/core/transaction_test.go b/core/transaction_test.go index 9b23ded7bd..5121e30a0d 100644 --- a/core/transaction_test.go +++ b/core/transaction_test.go @@ -5,7 +5,6 @@ import ( "encoding/hex" "errors" "fmt" - "reflect" "testing" "github.com/Masterminds/semver/v3" @@ -127,7 +126,6 @@ func TestTransactionEncoding(t *testing.T) { func checkTransactionSymmetry(t *testing.T, input core.Transaction) { t.Helper() - require.NoError(t, encoder.RegisterType(reflect.TypeOf(input))) data, err := encoder.Marshal(input) require.NoError(t, err) diff --git a/core/trie/node.go b/core/trie/node.go index 2975607390..b62db62807 100644 --- a/core/trie/node.go +++ b/core/trie/node.go @@ -55,12 +55,12 @@ func (n *Node) WriteTo(buf *bytes.Buffer) (int64, error) { if n.Left != nil { wrote, errInner := n.Left.WriteTo(buf) totalBytes += wrote - if err != nil { + if errInner != nil { return totalBytes, errInner } wrote, errInner = n.Right.WriteTo(buf) // n.Right is non-nil by design totalBytes += wrote - if err != nil { + if errInner != nil { return totalBytes, errInner } } diff --git a/core/trie/proof.go b/core/trie/proof.go index de8431d6d6..0744a9a119 100644 --- a/core/trie/proof.go +++ b/core/trie/proof.go @@ -7,51 +7,34 @@ import ( "github.com/NethermindEth/juno/core/felt" ) -// https://github.com/starknet-io/starknet-p2p-specs/blob/main/p2p/proto/snapshot.proto#L6 -type ProofNode struct { - Binary *Binary - Edge *Edge +var ( + ErrUnknownProofNode = errors.New("unknown proof node") + ErrChildHashNotFound = errors.New("can't determine the child hash from the parent and child") +) + +type ProofNode interface { + Hash(hash hashFunc) *felt.Felt + Len() uint8 + PrettyPrint() } -// Note: does not work for leaves -func (pn *ProofNode) Hash(hash hashFunc) *felt.Felt { - switch { - case pn.Binary != nil: - return hash(pn.Binary.LeftHash, pn.Binary.RightHash) - case pn.Edge != nil: - length := make([]byte, len(pn.Edge.Path.bitset)) - length[len(pn.Edge.Path.bitset)-1] = pn.Edge.Path.len - pathFelt := pn.Edge.Path.Felt() - lengthFelt := new(felt.Felt).SetBytes(length) - return new(felt.Felt).Add(hash(pn.Edge.Child, &pathFelt), lengthFelt) - default: - return nil - } +type Binary struct { + LeftHash *felt.Felt + RightHash *felt.Felt } -func (pn *ProofNode) Len() uint8 { - if pn.Binary != nil { - return 1 - } - return pn.Edge.Path.len +func (b *Binary) Hash(hash hashFunc) *felt.Felt { + return hash(b.LeftHash, b.RightHash) } -func (pn *ProofNode) PrettyPrint() { - if pn.Binary != nil { - fmt.Printf(" Binary:\n") - fmt.Printf(" LeftHash: %v\n", pn.Binary.LeftHash) - fmt.Printf(" RightHash: %v\n", pn.Binary.RightHash) - } - if pn.Edge != nil { - fmt.Printf(" Edge:\n") - fmt.Printf(" Child: %v\n", pn.Edge.Child) - fmt.Printf(" Path: %v\n", pn.Edge.Path) - } +func (b *Binary) Len() uint8 { + return 1 } -type Binary struct { - LeftHash *felt.Felt - RightHash *felt.Felt +func (b *Binary) PrettyPrint() { + fmt.Printf(" Binary:\n") + fmt.Printf(" LeftHash: %v\n", b.LeftHash) + fmt.Printf(" RightHash: %v\n", b.RightHash) } type Edge struct { @@ -59,6 +42,24 @@ type Edge struct { Path *Key // path from parent to child } +func (e *Edge) Hash(hash hashFunc) *felt.Felt { + length := make([]byte, len(e.Path.bitset)) + length[len(e.Path.bitset)-1] = e.Path.len + pathFelt := e.Path.Felt() + lengthFelt := new(felt.Felt).SetBytes(length) + return new(felt.Felt).Add(hash(e.Child, &pathFelt), lengthFelt) +} + +func (e *Edge) Len() uint8 { + return e.Path.Len() +} + +func (e *Edge) PrettyPrint() { + fmt.Printf(" Edge:\n") + fmt.Printf(" Child: %v\n", e.Child) + fmt.Printf(" Path: %v\n", e.Path) +} + func GetBoundaryProofs(leftBoundary, rightBoundary *Key, tri *Trie) ([2][]ProofNode, error) { proofs := [2][]ProofNode{} leftProof, err := GetProof(leftBoundary, tri) @@ -110,19 +111,19 @@ func transformNode(tri *Trie, parentKey *Key, sNode StorageNode) (*Edge, *Binary rightHash := rNode.Value if isEdge(sNode.key, StorageNode{node: rNode, key: sNode.node.Right}) { edgePath := path(sNode.node.Right, sNode.key) - rEdge := ProofNode{Edge: &Edge{ + rEdge := &Edge{ Path: &edgePath, Child: rNode.Value, - }} + } rightHash = rEdge.Hash(tri.hash) } leftHash := lNode.Value if isEdge(sNode.key, StorageNode{node: lNode, key: sNode.node.Left}) { edgePath := path(sNode.node.Left, sNode.key) - lEdge := ProofNode{Edge: &Edge{ + lEdge := &Edge{ Path: &edgePath, Child: lNode.Value, - }} + } leftHash = lEdge.Hash(tri.hash) } binary := &Binary{ @@ -133,6 +134,153 @@ func transformNode(tri *Trie, parentKey *Key, sNode StorageNode) (*Edge, *Binary return edge, binary, nil } +// pathSplitOccurredCheck checks if there happens at most one split in the merged path +// loops through the merged paths if left and right hashes of a node exist in the nodeHashes +// then a split happened in case of multiple splits it returns an error +func pathSplitOccurredCheck(mergedPath []ProofNode, nodeHashes map[felt.Felt]ProofNode) error { + splitHappened := false + for _, node := range mergedPath { + switch node := node.(type) { + case *Edge: + continue + case *Binary: + _, leftExists := nodeHashes[*node.LeftHash] + _, rightExists := nodeHashes[*node.RightHash] + if leftExists && rightExists { + if splitHappened { + return errors.New("split happened more than once") + } + splitHappened = true + } + default: + return fmt.Errorf("%w: %T", ErrUnknownProofNode, node) + } + } + return nil +} + +func rootNodeExistsCheck(rootHash *felt.Felt, nodeHashes map[felt.Felt]ProofNode) (ProofNode, error) { + currNode, rootExists := nodeHashes[*rootHash] + if !rootExists { + return currNode, errors.New("root hash not found in the merged path") + } + + return currNode, nil +} + +// traverseNodes traverses the merged proof path starting at `currNode` +// and adds nodes to `path` slice. It stops when the split node is added +// or the path is exhausted, and `currNode` children are not included +// in the path (nodeHashes) +func traverseNodes(currNode ProofNode, path *[]ProofNode, nodeHashes map[felt.Felt]ProofNode) { + *path = append(*path, currNode) + + switch currNode := currNode.(type) { + case *Binary: + nodeLeft, leftExist := nodeHashes[*currNode.LeftHash] + nodeRight, rightExist := nodeHashes[*currNode.RightHash] + + if leftExist && rightExist { + return + } else if leftExist { + traverseNodes(nodeLeft, path, nodeHashes) + } else if rightExist { + traverseNodes(nodeRight, path, nodeHashes) + } + case *Edge: + edgeNode, exist := nodeHashes[*currNode.Child] + if exist { + traverseNodes(edgeNode, path, nodeHashes) + } + } +} + +// MergeProofPaths removes duplicates and merges proof paths into a single path +// merges paths in the specified order [commonNodes..., leftNodes..., rightNodes...] +// ordering of the merged path is not important +// since SplitProofPath can discover the left and right paths using the merged path and the rootHash +func MergeProofPaths(leftPath, rightPath []ProofNode, hash hashFunc) ([]ProofNode, *felt.Felt, error) { + merged := []ProofNode{} + minLen := min(len(leftPath), len(rightPath)) + + if len(leftPath) == 0 || len(rightPath) == 0 { + return merged, nil, errors.New("empty proof paths") + } + + if !leftPath[0].Hash(hash).Equal(rightPath[0].Hash(hash)) { + return merged, nil, errors.New("roots of the proof paths are different") + } + + rootHash := leftPath[0].Hash(hash) + + // Get duplicates and insert by one + i := 0 + for i = 0; i < minLen; i++ { + leftNode := leftPath[i] + rightNode := rightPath[i] + + if leftNode.Hash(hash).Equal(rightNode.Hash(hash)) { + merged = append(merged, leftNode) + } else { + break + } + } + + // Add rest of the nodes + merged = append(merged, leftPath[i:]...) + merged = append(merged, rightPath[i:]...) + + return merged, rootHash, nil +} + +// SplitProofPath splits the merged proof path into two paths (left and right), which were merged before +// it first validates that the merged path is not circular, the split happens at most once and rootHash exists +// then calls traverseNodes to split the path to left and right paths +func SplitProofPath(mergedPath []ProofNode, rootHash *felt.Felt, hash hashFunc) ([]ProofNode, []ProofNode, error) { + commonPath := []ProofNode{} + leftPath := []ProofNode{} + rightPath := []ProofNode{} + nodeHashes := make(map[felt.Felt]ProofNode) + + for _, node := range mergedPath { + nodeHash := node.Hash(hash) + _, nodeExists := nodeHashes[*nodeHash] + + if nodeExists { + return leftPath, rightPath, errors.New("duplicate node in the merged path") + } + nodeHashes[*nodeHash] = node + } + + if len(mergedPath) == 0 { + return leftPath, rightPath, nil + } + + currNode, err := rootNodeExistsCheck(rootHash, nodeHashes) + if err != nil { + return leftPath, rightPath, err + } + + if err := pathSplitOccurredCheck(mergedPath, nodeHashes); err != nil { + return leftPath, rightPath, err + } + + traverseNodes(currNode, &commonPath, nodeHashes) + + leftPath = append(leftPath, commonPath...) + rightPath = append(rightPath, commonPath...) + + currNode = commonPath[len(commonPath)-1] + + leftNode := nodeHashes[*currNode.(*Binary).LeftHash] + rightNode := nodeHashes[*currNode.(*Binary).RightHash] + + traverseNodes(leftNode, &leftPath, nodeHashes) + traverseNodes(rightNode, &rightPath, nodeHashes) + + return leftPath, rightPath, nil +} + // https://github.com/eqlabs/pathfinder/blob/main/crates/merkle-tree/src/tree.rs#L514 // GetProof generates a set of proof nodes from the root to the leaf. // The proof never contains the leaf node if it is set, as we already know it's hash. @@ -153,11 +301,11 @@ func GetProof(key *Key, tri *Trie) ([]ProofNode, error) { isLeaf := sNode.key.len == tri.height if sNodeEdge != nil && !isLeaf { // Internal Edge - proofNodes = append(proofNodes, []ProofNode{{Edge: sNodeEdge}, {Binary: sNodeBinary}}...) + proofNodes = append(proofNodes, sNodeEdge, sNodeBinary) } else if sNodeEdge == nil && !isLeaf { // Internal Binary - proofNodes = append(proofNodes, []ProofNode{{Binary: sNodeBinary}}...) + proofNodes = append(proofNodes, sNodeBinary) } else if sNodeEdge != nil && isLeaf { // Leaf Edge - proofNodes = append(proofNodes, []ProofNode{{Edge: sNodeEdge}}...) + proofNodes = append(proofNodes, sNodeEdge) } else if sNodeEdge == nil && sNodeBinary == nil { // sNode is a binary leaf break } @@ -176,16 +324,16 @@ func VerifyProof(root *felt.Felt, key *Key, value *felt.Felt, proofs []ProofNode return false } - switch { - case proofNode.Binary != nil: + switch proofNode := proofNode.(type) { + case *Binary: if remainingPath.Test(remainingPath.Len() - 1) { - expectedHash = proofNode.Binary.RightHash + expectedHash = proofNode.RightHash } else { - expectedHash = proofNode.Binary.LeftHash + expectedHash = proofNode.LeftHash } remainingPath.RemoveLastBit() - case proofNode.Edge != nil: - subKey, err := remainingPath.SubKey(proofNode.Edge.Path.Len()) + case *Edge: + subKey, err := remainingPath.SubKey(proofNode.Path.Len()) if err != nil { return false } @@ -197,11 +345,11 @@ func VerifyProof(root *felt.Felt, key *Key, value *felt.Felt, proofs []ProofNode return true } - if !proofNode.Edge.Path.Equal(subKey) { + if !proofNode.Path.Equal(subKey) { return false } - expectedHash = proofNode.Edge.Child - remainingPath.Truncate(251 - proofNode.Edge.Path.Len()) //nolint:mnd + expectedHash = proofNode.Child + remainingPath.Truncate(251 - proofNode.Path.Len()) //nolint:mnd } } @@ -293,27 +441,33 @@ func ensureMonotonicIncreasing(proofKeys [2]*Key, keys []*felt.Felt) error { // compressNode determines if the node needs compressed, and if so, the len needed to arrive at the next key func compressNode(idx int, proofNodes []ProofNode, hashF hashFunc) (int, uint8, error) { - parent := &proofNodes[idx] + parent := proofNodes[idx] if idx == len(proofNodes)-1 { - if parent.Edge != nil { + if _, ok := parent.(*Edge); ok { return 1, parent.Len(), nil } return 0, parent.Len(), nil } - child := &proofNodes[idx+1] - - switch { - case parent.Edge != nil && child.Binary != nil: - return 1, parent.Edge.Path.len, nil - case parent.Binary != nil && child.Edge != nil: + child := proofNodes[idx+1] + _, isChildBinary := child.(*Binary) + isChildEdge := !isChildBinary + switch parent := parent.(type) { + case *Edge: + if isChildEdge { + break + } + return 1, parent.Len(), nil + case *Binary: + if isChildBinary { + break + } childHash := child.Hash(hashF) - if parent.Binary.LeftHash.Equal(childHash) || parent.Binary.RightHash.Equal(childHash) { - return 1, child.Edge.Path.len, nil - } else { - return 0, 0, errors.New("can't determine the child hash from the parent and child") + if parent.LeftHash.Equal(childHash) || parent.RightHash.Equal(childHash) { + return 1, child.Len(), nil } + return 0, 0, ErrChildHashNotFound } return 0, 1, nil @@ -394,6 +548,7 @@ func ProofToPath(proofNodes []ProofNode, leafKey *Key, hashF hashFunc) ([]Storag break } } + return pathNodes, nil } @@ -413,14 +568,20 @@ func skipNode(pNode ProofNode, pathNodes []StorageNode, hashF hashFunc) bool { } func getLeftRightHash(parentInd int, proofNodes []ProofNode) (*felt.Felt, *felt.Felt, error) { - parent := &proofNodes[parentInd] - if parent.Binary == nil { + parent := proofNodes[parentInd] + + switch parent := parent.(type) { + case *Binary: + return parent.LeftHash, parent.RightHash, nil + case *Edge: if parentInd+1 > len(proofNodes)-1 { return nil, nil, errors.New("cant get hash of children from proof node, out of range") } - parent = &proofNodes[parentInd+1] + parentBinary := proofNodes[parentInd+1].(*Binary) + return parentBinary.LeftHash, parentBinary.RightHash, nil + default: + return nil, nil, fmt.Errorf("%w: %T", ErrUnknownProofNode, parent) } - return parent.Binary.LeftHash, parent.Binary.RightHash, nil } func getParentKey(idx int, compressedParentOffset uint8, leafKey *Key, @@ -431,16 +592,14 @@ func getParentKey(idx int, compressedParentOffset uint8, leafKey *Key, var height uint8 if len(pathNodes) > 0 { - if proofNodes[idx].Edge != nil { - height = pathNodes[len(pathNodes)-1].key.len + proofNodes[idx].Edge.Path.len + if p, ok := proofNodes[idx].(*Edge); ok { + height = pathNodes[len(pathNodes)-1].key.len + p.Path.len } else { height = pathNodes[len(pathNodes)-1].key.len + 1 } - } else { - height = 0 } - if pNode.Binary != nil { + if _, ok := pNode.(*Binary); ok { crntKey, err = leafKey.SubKey(height) } else { crntKey, err = leafKey.SubKey(height + compressedParentOffset) diff --git a/core/trie/proof_test.go b/core/trie/proof_test.go index a566ac2d02..e6d8576d83 100644 --- a/core/trie/proof_test.go +++ b/core/trie/proof_test.go @@ -117,23 +117,17 @@ func buildSimpleDoubleBinaryTrie(t *testing.T) (*trie.Trie, []trie.ProofNode) { key3Bytes := new(felt.Felt).SetUint64(1).Bytes() path3 := trie.NewKey(1, key3Bytes[:]) expectedProofNodes := []trie.ProofNode{ - { - Edge: &trie.Edge{ - Path: &zero, - Child: utils.HexToFelt(t, "0x055C81F6A791FD06FC2E2CCAD922397EC76C3E35F2E06C0C0D43D551005A8DEA"), - }, + &trie.Edge{ + Path: &zero, + Child: utils.HexToFelt(t, "0x055C81F6A791FD06FC2E2CCAD922397EC76C3E35F2E06C0C0D43D551005A8DEA"), }, - { - Binary: &trie.Binary{ - LeftHash: utils.HexToFelt(t, "0x05774FA77B3D843AE9167ABD61CF80365A9B2B02218FC2F628494B5BDC9B33B8"), - RightHash: utils.HexToFelt(t, "0x07C5BC1CC68B7BC8CA2F632DE98297E6DA9594FA23EDE872DD2ABEAFDE353B43"), - }, + &trie.Binary{ + LeftHash: utils.HexToFelt(t, "0x05774FA77B3D843AE9167ABD61CF80365A9B2B02218FC2F628494B5BDC9B33B8"), + RightHash: utils.HexToFelt(t, "0x07C5BC1CC68B7BC8CA2F632DE98297E6DA9594FA23EDE872DD2ABEAFDE353B43"), }, - { - Edge: &trie.Edge{ - Path: &path3, - Child: value3, - }, + &trie.Edge{ + Path: &path3, + Child: value3, }, } @@ -252,23 +246,67 @@ func build4KeyTrie(t *testing.T) *trie.Trie { return tempTrie } +func noDuplicates(proofNodes []trie.ProofNode) bool { + seen := make(map[felt.Felt]bool) + for _, pNode := range proofNodes { + if _, ok := seen[*pNode.Hash(crypto.Pedersen)]; ok { + return false + } + seen[*pNode.Hash(crypto.Pedersen)] = true + } + return true +} + +// containsAll checks that subsetProofNodes is a subset of proofNodes +func containsAll(proofNodes, subsetProofNodes []trie.ProofNode) bool { + for _, pNode := range subsetProofNodes { + found := false + for _, p := range proofNodes { + if p.Hash(crypto.Pedersen).Equal(pNode.Hash(crypto.Pedersen)) { + found = true + break + } + } + if !found { + return false + } + } + return true +} + +func isSameProofPath(proofNodes, expectedProofNodes []trie.ProofNode) bool { + if len(proofNodes) != len(expectedProofNodes) { + return false + } + for i := range proofNodes { + if !proofNodes[i].Hash(crypto.Pedersen).Equal(expectedProofNodes[i].Hash(crypto.Pedersen)) { + return false + } + } + return true +} + +func newBinaryProofNode() *trie.Binary { + return &trie.Binary{ + LeftHash: new(felt.Felt).SetUint64(1), + RightHash: new(felt.Felt).SetUint64(2), + } +} + func TestGetProof(t *testing.T) { t.Run("GP Simple Trie - simple binary", func(t *testing.T) { tempTrie := buildSimpleTrie(t) zero := trie.NewKey(250, []byte{0}) expectedProofNodes := []trie.ProofNode{ - { - Edge: &trie.Edge{ - Path: &zero, - Child: utils.HexToFelt(t, "0x05774FA77B3D843AE9167ABD61CF80365A9B2B02218FC2F628494B5BDC9B33B8"), - }, + &trie.Edge{ + Path: &zero, + Child: utils.HexToFelt(t, "0x05774FA77B3D843AE9167ABD61CF80365A9B2B02218FC2F628494B5BDC9B33B8"), }, - { - Binary: &trie.Binary{ - LeftHash: utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000002"), - RightHash: utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000003"), - }, + + &trie.Binary{ + LeftHash: utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000002"), + RightHash: utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000003"), }, } leafFelt := new(felt.Felt).SetUint64(0).Bytes() @@ -286,11 +324,9 @@ func TestGetProof(t *testing.T) { t.Run("GP Simple Trie - simple double binary", func(t *testing.T) { tempTrie, expectedProofNodes := buildSimpleDoubleBinaryTrie(t) - expectedProofNodes[2] = trie.ProofNode{ - Binary: &trie.Binary{ - LeftHash: utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000002"), - RightHash: utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000003"), - }, + expectedProofNodes[2] = &trie.Binary{ + LeftHash: utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000002"), + RightHash: utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000003"), } leafFelt := new(felt.Felt).SetUint64(0).Bytes() @@ -325,17 +361,13 @@ func TestGetProof(t *testing.T) { key1Bytes := new(felt.Felt).SetUint64(0).Bytes() path1 := trie.NewKey(250, key1Bytes[:]) expectedProofNodes := []trie.ProofNode{ - { - Binary: &trie.Binary{ - LeftHash: utils.HexToFelt(t, "0x06E08BF82793229338CE60B65D1845F836C8E2FBFE2BC59FF24AEDBD8BA219C4"), - RightHash: utils.HexToFelt(t, "0x04F9B8E66212FB528C0C1BD02F43309C53B895AA7D9DC91180001BDD28A588FA"), - }, + &trie.Binary{ + LeftHash: utils.HexToFelt(t, "0x06E08BF82793229338CE60B65D1845F836C8E2FBFE2BC59FF24AEDBD8BA219C4"), + RightHash: utils.HexToFelt(t, "0x04F9B8E66212FB528C0C1BD02F43309C53B895AA7D9DC91180001BDD28A588FA"), }, - { - Edge: &trie.Edge{ - Path: &path1, - Child: utils.HexToFelt(t, "0xcc"), - }, + &trie.Edge{ + Path: &path1, + Child: utils.HexToFelt(t, "0xcc"), }, } leafFelt := new(felt.Felt).SetUint64(0).Bytes() @@ -376,11 +408,9 @@ func TestGetProof(t *testing.T) { child := utils.HexToFelt(t, "0x00000000000000000000000000000000000000000000000000000000000000AA") expectedProofNodes := []trie.ProofNode{ - { - Edge: &trie.Edge{ - Path: &path1, - Child: child, - }, + &trie.Edge{ + Path: &path1, + Child: child, }, } leafFelt := new(felt.Felt).SetUint64(0).Bytes() @@ -447,17 +477,13 @@ func TestVerifyProof(t *testing.T) { tempTrie := buildSimpleTrie(t) zero := trie.NewKey(250, []byte{0}) expectedProofNodes := []trie.ProofNode{ - { - Edge: &trie.Edge{ - Path: &zero, - Child: utils.HexToFelt(t, "0x05774FA77B3D843AE9167ABD61CF80365A9B2B02218FC2F628494B5BDC9B33B8"), - }, + &trie.Edge{ + Path: &zero, + Child: utils.HexToFelt(t, "0x05774FA77B3D843AE9167ABD61CF80365A9B2B02218FC2F628494B5BDC9B33B8"), }, - { - Binary: &trie.Binary{ - LeftHash: utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000002"), - RightHash: utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000003"), - }, + &trie.Binary{ + LeftHash: utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000002"), + RightHash: utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000003"), }, } @@ -475,23 +501,17 @@ func TestVerifyProof(t *testing.T) { tempTrie, _ := buildSimpleDoubleBinaryTrie(t) zero := trie.NewKey(249, []byte{0}) expectedProofNodes := []trie.ProofNode{ - { - Edge: &trie.Edge{ - Path: &zero, - Child: utils.HexToFelt(t, "0x055C81F6A791FD06FC2E2CCAD922397EC76C3E35F2E06C0C0D43D551005A8DEA"), - }, + &trie.Edge{ + Path: &zero, + Child: utils.HexToFelt(t, "0x055C81F6A791FD06FC2E2CCAD922397EC76C3E35F2E06C0C0D43D551005A8DEA"), }, - { - Binary: &trie.Binary{ - LeftHash: utils.HexToFelt(t, "0x05774FA77B3D843AE9167ABD61CF80365A9B2B02218FC2F628494B5BDC9B33B8"), - RightHash: utils.HexToFelt(t, "0x07C5BC1CC68B7BC8CA2F632DE98297E6DA9594FA23EDE872DD2ABEAFDE353B43"), - }, + &trie.Binary{ + LeftHash: utils.HexToFelt(t, "0x05774FA77B3D843AE9167ABD61CF80365A9B2B02218FC2F628494B5BDC9B33B8"), + RightHash: utils.HexToFelt(t, "0x07C5BC1CC68B7BC8CA2F632DE98297E6DA9594FA23EDE872DD2ABEAFDE353B43"), }, - { - Binary: &trie.Binary{ - LeftHash: utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000002"), - RightHash: utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000003"), - }, + &trie.Binary{ + LeftHash: utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000002"), + RightHash: utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000003"), }, } @@ -509,23 +529,17 @@ func TestVerifyProof(t *testing.T) { felt2 := new(felt.Felt).SetUint64(0).Bytes() lastPath := trie.NewKey(1, felt2[:]) expectedProofNodes := []trie.ProofNode{ - { - Edge: &trie.Edge{ - Path: &zero, - Child: utils.HexToFelt(t, "0x0768DEB8D0795D80AAAC2E5E326141F33044759F97A1BF092D8EB9C4E4BE9234"), - }, + &trie.Edge{ + Path: &zero, + Child: utils.HexToFelt(t, "0x0768DEB8D0795D80AAAC2E5E326141F33044759F97A1BF092D8EB9C4E4BE9234"), }, - { - Binary: &trie.Binary{ - LeftHash: utils.HexToFelt(t, "0x057166F9476D0A2D6875124251841EB85A9AE37462FAE3CBF7304BCD593938E7"), - RightHash: utils.HexToFelt(t, "0x060FBDE29F96F706498EFD132DC7F312A4C99A9AE051BF152C2AF2B3CAF31E5B"), - }, + &trie.Binary{ + LeftHash: utils.HexToFelt(t, "0x057166F9476D0A2D6875124251841EB85A9AE37462FAE3CBF7304BCD593938E7"), + RightHash: utils.HexToFelt(t, "0x060FBDE29F96F706498EFD132DC7F312A4C99A9AE051BF152C2AF2B3CAF31E5B"), }, - { - Edge: &trie.Edge{ - Path: &lastPath, - Child: utils.HexToFelt(t, "0x6"), - }, + &trie.Edge{ + Path: &lastPath, + Child: utils.HexToFelt(t, "0x6"), }, } @@ -580,17 +594,13 @@ func TestProofToPath(t *testing.T) { leafValue := utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000002") siblingValue := utils.HexToFelt(t, "0x0000000000000000000000000000000000000000000000000000000000000003") proofNodes := []trie.ProofNode{ - { - Edge: &trie.Edge{ - Path: &zero, - Child: utils.HexToFelt(t, "0x05774FA77B3D843AE9167ABD61CF80365A9B2B02218FC2F628494B5BDC9B33B8"), - }, + &trie.Edge{ + Path: &zero, + Child: utils.HexToFelt(t, "0x05774FA77B3D843AE9167ABD61CF80365A9B2B02218FC2F628494B5BDC9B33B8"), }, - { - Binary: &trie.Binary{ - LeftHash: leafValue, - RightHash: siblingValue, - }, + &trie.Binary{ + LeftHash: leafValue, + RightHash: siblingValue, }, } @@ -614,17 +624,13 @@ func TestProofToPath(t *testing.T) { leafkey := trie.NewKey(251, zeroFeltBytes[:]) path1 := trie.NewKey(250, zeroFeltBytes[:]) proofNodes := []trie.ProofNode{ - { - Binary: &trie.Binary{ - LeftHash: utils.HexToFelt(t, "0x06E08BF82793229338CE60B65D1845F836C8E2FBFE2BC59FF24AEDBD8BA219C4"), - RightHash: utils.HexToFelt(t, "0x04F9B8E66212FB528C0C1BD02F43309C53B895AA7D9DC91180001BDD28A588FA"), - }, + &trie.Binary{ + LeftHash: utils.HexToFelt(t, "0x06E08BF82793229338CE60B65D1845F836C8E2FBFE2BC59FF24AEDBD8BA219C4"), + RightHash: utils.HexToFelt(t, "0x04F9B8E66212FB528C0C1BD02F43309C53B895AA7D9DC91180001BDD28A588FA"), }, - { - Edge: &trie.Edge{ - Path: &path1, - Child: utils.HexToFelt(t, "0xcc"), - }, + &trie.Edge{ + Path: &path1, + Child: utils.HexToFelt(t, "0xcc"), }, } @@ -869,3 +875,265 @@ func TestVerifyRangeProof(t *testing.T) { require.True(t, verif) }) } + +func TestMergeProofPaths(t *testing.T) { + t.Run("3Key Trie no duplicates and all values exist in merged path", func(t *testing.T) { + tri := build3KeyTrie(t) + + zeroFeltBytes := new(felt.Felt).SetUint64(0).Bytes() + zeroLeafkey := trie.NewKey(251, zeroFeltBytes[:]) + + twoFeltBytes := new(felt.Felt).SetUint64(2).Bytes() + twoLeafkey := trie.NewKey(251, twoFeltBytes[:]) + + proofKeys := [2]*trie.Key{&zeroLeafkey, &twoLeafkey} + + proofs, err := trie.GetBoundaryProofs(proofKeys[0], proofKeys[1], tri) + require.NoError(t, err) + + mergedProofs, _, err := trie.MergeProofPaths(proofs[0], proofs[1], crypto.Pedersen) + require.NoError(t, err) + + require.True(t, containsAll(mergedProofs, proofs[0])) + require.True(t, containsAll(mergedProofs, proofs[1])) + require.True(t, noDuplicates(mergedProofs)) + }) + + t.Run("4Key Trie two common ancestors", func(t *testing.T) { + twoFeltBytes := new(felt.Felt).SetUint64(2).Bytes() + twoLeafkey := trie.NewKey(251, twoFeltBytes[:]) + + zeroFeltBytes := new(felt.Felt).SetUint64(0).Bytes() + zeroLeafkey := trie.NewKey(251, zeroFeltBytes[:]) + + tri := build4KeyTrie(t) + + proofKeys := [2]*trie.Key{&zeroLeafkey, &twoLeafkey} + + proofs, err := trie.GetBoundaryProofs(proofKeys[0], proofKeys[1], tri) + require.NoError(t, err) + + mergedProofs, _, err := trie.MergeProofPaths(proofs[0], proofs[1], crypto.Pedersen) + require.NoError(t, err) + + require.True(t, containsAll(mergedProofs, proofs[0])) + require.True(t, containsAll(mergedProofs, proofs[1])) + require.True(t, noDuplicates(mergedProofs)) + }) + + t.Run("Trie 4Key one ancestor", func(t *testing.T) { + tri := build4KeyTrie(t) + fourFeltBytes := new(felt.Felt).SetUint64(4).Bytes() + zeroFeltBytes := new(felt.Felt).SetUint64(0).Bytes() + + fourLeafkey := trie.NewKey(251, fourFeltBytes[:]) + zeroLeafkey := trie.NewKey(251, zeroFeltBytes[:]) + + proofKeys := [2]*trie.Key{&zeroLeafkey, &fourLeafkey} + + proofs, err := trie.GetBoundaryProofs(proofKeys[0], proofKeys[1], tri) + require.NoError(t, err) + + mergedProofs, _, err := trie.MergeProofPaths(proofs[0], proofs[1], crypto.Pedersen) + require.NoError(t, err) + + require.True(t, containsAll(mergedProofs, proofs[0])) + require.True(t, containsAll(mergedProofs, proofs[1])) + require.True(t, noDuplicates(mergedProofs)) + }) + + t.Run("Empty proof path", func(t *testing.T) { + tri := build4KeyTrie(t) + fourFeltBytes := new(felt.Felt).SetUint64(4).Bytes() + zeroFeltBytes := new(felt.Felt).SetUint64(0).Bytes() + + fourLeafkey := trie.NewKey(251, fourFeltBytes[:]) + zeroLeafkey := trie.NewKey(251, zeroFeltBytes[:]) + + proofKeys := [2]*trie.Key{&zeroLeafkey, &fourLeafkey} + + proofs, err := trie.GetBoundaryProofs(proofKeys[0], proofKeys[1], tri) + require.NoError(t, err) + + emptyPath := []trie.ProofNode{} + + _, _, err = trie.MergeProofPaths(proofs[0], emptyPath, crypto.Pedersen) + require.Error(t, err) + }) + + t.Run("Root of the proof paths are different", func(t *testing.T) { + tri := build4KeyTrie(t) + fourFeltBytes := new(felt.Felt).SetUint64(4).Bytes() + zeroFeltBytes := new(felt.Felt).SetUint64(0).Bytes() + + fourLeafkey := trie.NewKey(251, fourFeltBytes[:]) + zeroLeafkey := trie.NewKey(251, zeroFeltBytes[:]) + + proofKeys := [2]*trie.Key{&zeroLeafkey, &fourLeafkey} + + proofs, err := trie.GetBoundaryProofs(proofKeys[0], proofKeys[1], tri) + require.NoError(t, err) + + _, _, err = trie.MergeProofPaths(proofs[0], proofs[1][1:], crypto.Pedersen) + require.Error(t, err) + }) +} + +func TestSplitProofPaths(t *testing.T) { + t.Run("3Key Trie retrieved right and left proofs are same with the merged ones", func(t *testing.T) { + zeroFeltBytes := new(felt.Felt).SetUint64(0).Bytes() + zeroLeafkey := trie.NewKey(251, zeroFeltBytes[:]) + twoFeltBytes := new(felt.Felt).SetUint64(2).Bytes() + twoLeafkey := trie.NewKey(251, twoFeltBytes[:]) + + tri := build3KeyTrie(t) + proofKeys := [2]*trie.Key{&zeroLeafkey, &twoLeafkey} + + proofs, err := trie.GetBoundaryProofs(proofKeys[0], proofKeys[1], tri) + require.NoError(t, err) + + mergedProofs, rootHash, err := trie.MergeProofPaths(proofs[0], proofs[1], crypto.Pedersen) + require.NoError(t, err) + + leftSplit, rightSplit, err := trie.SplitProofPath(mergedProofs, rootHash, crypto.Pedersen) + require.NoError(t, err) + + require.True(t, isSameProofPath(leftSplit, proofs[0])) + require.True(t, isSameProofPath(rightSplit, proofs[1])) + }) + + t.Run("4Key Trie two common ancestors retrieved right and left proofs are same with the merged ones", func(t *testing.T) { + tri := build4KeyTrie(t) + + twoFeltBytes := new(felt.Felt).SetUint64(2).Bytes() + zeroFeltBytes := new(felt.Felt).SetUint64(0).Bytes() + + twoLeafkey := trie.NewKey(251, twoFeltBytes[:]) + zeroLeafkey := trie.NewKey(251, zeroFeltBytes[:]) + + proofKeys := [2]*trie.Key{&zeroLeafkey, &twoLeafkey} + + proofs, err := trie.GetBoundaryProofs(proofKeys[0], proofKeys[1], tri) + require.NoError(t, err) + + mergedProofs, rootHash, err := trie.MergeProofPaths(proofs[0], proofs[1], crypto.Pedersen) + require.NoError(t, err) + + leftSplit, rightSplit, err := trie.SplitProofPath(mergedProofs, rootHash, crypto.Pedersen) + require.NoError(t, err) + + require.True(t, isSameProofPath(leftSplit, proofs[0])) + require.True(t, isSameProofPath(rightSplit, proofs[1])) + }) + + t.Run("4Key Trie one common ancestor retrieved right and left proofs are same with the merged ones", func(t *testing.T) { + tri := build4KeyTrie(t) + zeroFeltBytes := new(felt.Felt).SetUint64(0).Bytes() + zeroLeafkey := trie.NewKey(251, zeroFeltBytes[:]) + fourFeltBytes := new(felt.Felt).SetUint64(4).Bytes() + fourLeafkey := trie.NewKey(251, fourFeltBytes[:]) + + proofKeys := [2]*trie.Key{&zeroLeafkey, &fourLeafkey} + + proofs, err := trie.GetBoundaryProofs(proofKeys[0], proofKeys[1], tri) + require.NoError(t, err) + + mergedProofs, rootHash, err := trie.MergeProofPaths(proofs[0], proofs[1], crypto.Pedersen) + require.NoError(t, err) + + leftSplit, rightSplit, err := trie.SplitProofPath(mergedProofs, rootHash, crypto.Pedersen) + require.NoError(t, err) + + require.True(t, isSameProofPath(leftSplit, proofs[0])) + require.True(t, isSameProofPath(rightSplit, proofs[1])) + }) + + t.Run("4Key Trie reversed merge path", func(t *testing.T) { + tri := build4KeyTrie(t) + zeroFeltBytes := new(felt.Felt).SetUint64(0).Bytes() + zeroLeafkey := trie.NewKey(251, zeroFeltBytes[:]) + fourFeltBytes := new(felt.Felt).SetUint64(4).Bytes() + fourLeafkey := trie.NewKey(251, fourFeltBytes[:]) + + proofKeys := [2]*trie.Key{&zeroLeafkey, &fourLeafkey} + + proofs, err := trie.GetBoundaryProofs(proofKeys[0], proofKeys[1], tri) + require.NoError(t, err) + + mergedProofs, rootHash, err := trie.MergeProofPaths(proofs[0], proofs[1], crypto.Pedersen) + require.NoError(t, err) + + for i := 0; i < len(mergedProofs)/2; i++ { + j := len(mergedProofs) - 1 - i + mergedProofs[i], mergedProofs[j] = mergedProofs[j], mergedProofs[i] + } + + leftSplit, rightSplit, err := trie.SplitProofPath(mergedProofs, rootHash, crypto.Pedersen) + require.NoError(t, err) + + require.True(t, isSameProofPath(leftSplit, proofs[0])) + require.True(t, isSameProofPath(rightSplit, proofs[1])) + }) + + t.Run("Roothash does not exist", func(t *testing.T) { + tri := build4KeyTrie(t) + zeroFeltBytes := new(felt.Felt).SetUint64(0).Bytes() + zeroLeafkey := trie.NewKey(251, zeroFeltBytes[:]) + fourFeltBytes := new(felt.Felt).SetUint64(4).Bytes() + fourLeafkey := trie.NewKey(251, fourFeltBytes[:]) + + proofKeys := [2]*trie.Key{&zeroLeafkey, &fourLeafkey} + + proofs, err := trie.GetBoundaryProofs(proofKeys[0], proofKeys[1], tri) + require.NoError(t, err) + + mergedProofs, _, err := trie.MergeProofPaths(proofs[0], proofs[1], crypto.Pedersen) + require.NoError(t, err) + + rootHashFalse := new(felt.Felt).SetUint64(0) + + _, _, err = trie.SplitProofPath(mergedProofs, rootHashFalse, crypto.Pedersen) + require.Error(t, err) + }) + + t.Run("Two splits in the merged path", func(t *testing.T) { + p1 := newBinaryProofNode() + p2 := newBinaryProofNode() + p3 := newBinaryProofNode() + p4 := newBinaryProofNode() + p5 := newBinaryProofNode() + + p4.LeftHash = new(felt.Felt).SetUint64(3) + p2.RightHash = new(felt.Felt).SetUint64(4) + + p3.RightHash = p5.Hash(crypto.Pedersen) + p3.LeftHash = p4.Hash(crypto.Pedersen) + p1.RightHash = p3.Hash(crypto.Pedersen) + p1.LeftHash = p2.Hash(crypto.Pedersen) + + mergedProofs := []trie.ProofNode{p1, p2, p3, p4, p5} + rootHash := p1.Hash(crypto.Pedersen) + + _, _, err := trie.SplitProofPath(mergedProofs, rootHash, crypto.Pedersen) + require.Error(t, err) + }) + + t.Run("Duplicate nodes in the merged path", func(t *testing.T) { + p1 := newBinaryProofNode() + p2 := newBinaryProofNode() + p3 := newBinaryProofNode() + p4 := newBinaryProofNode() + p5 := newBinaryProofNode() + + p3.RightHash = p5.Hash(crypto.Pedersen) + p3.LeftHash = p4.Hash(crypto.Pedersen) + p1.RightHash = p3.Hash(crypto.Pedersen) + p1.LeftHash = p2.Hash(crypto.Pedersen) + + mergedProofs := []trie.ProofNode{p1, p2, p3, p4, p5} + rootHash := p1.Hash(crypto.Pedersen) + + _, _, err := trie.SplitProofPath(mergedProofs, rootHash, crypto.Pedersen) + require.Error(t, err) + }) +} diff --git a/core/trie/snap_support.go b/core/trie/snap_support.go index 6caf6b834d..7c2ae76363 100644 --- a/core/trie/snap_support.go +++ b/core/trie/snap_support.go @@ -175,25 +175,24 @@ func buildKeys(currentKey Key, currentNode *felt.Felt, proofMap map[felt.Felt]Pr return nil } - if proofNode.Edge != nil { - chKey := currentKey.Append(proofNode.Edge.Path) - ch := proofNode.Edge.Child + switch node := proofNode.(type) { + case *Edge: + chKey := currentKey.Append(node.Path) + ch := node.Child err := buildKeys(chKey, ch, proofMap, keys, depth+1) if err != nil { return err } - } else { - binary := proofNode.Binary - + case *Binary: chKey := currentKey.AppendBit(false) - ch := binary.LeftHash + ch := node.LeftHash err := buildKeys(chKey, ch, proofMap, keys, depth+1) if err != nil { return err } chKey = currentKey.AppendBit(true) - ch = binary.RightHash + ch = node.RightHash err = buildKeys(chKey, ch, proofMap, keys, depth+1) if err != nil { return err diff --git a/db/db.go b/db/db.go index 4e60e7b339..1ff7b101f7 100644 --- a/db/db.go +++ b/db/db.go @@ -79,9 +79,6 @@ type Transaction interface { // Get fetches the value for the given key, should return ErrKeyNotFound if key is not present // Caller should not assume that the slice would stay valid after the call to cb Get(key []byte, cb func([]byte) error) error - - // Impl returns the underlying transaction object - Impl() any } // View : see db.DB.View diff --git a/db/pebble/batch.go b/db/pebble/batch.go new file mode 100644 index 0000000000..5646f341c8 --- /dev/null +++ b/db/pebble/batch.go @@ -0,0 +1,115 @@ +package pebble + +import ( + "errors" + "sync" + "time" + + "github.com/NethermindEth/juno/db" + "github.com/NethermindEth/juno/utils" + "github.com/cockroachdb/pebble" +) + +var _ db.Transaction = (*batch)(nil) + +type batch struct { + batch *pebble.Batch + dbLock *sync.Mutex + rwlock sync.RWMutex + listener db.EventListener +} + +func NewBatch(dbBatch *pebble.Batch, dbLock *sync.Mutex, listener db.EventListener) *batch { + return &batch{ + batch: dbBatch, + dbLock: dbLock, + listener: listener, + } +} + +// Discard : see db.Transaction.Discard +func (b *batch) Discard() error { + if b.batch == nil { + return nil + } + + err := b.batch.Close() + b.batch = nil + b.dbLock.Unlock() + b.dbLock = nil + + return err +} + +// Commit : see db.Transaction.Commit +func (b *batch) Commit() error { + if b.batch == nil { + return ErrDiscardedTransaction + } + + start := time.Now() + defer func() { b.listener.OnCommit(time.Since(start)) }() + return utils.RunAndWrapOnError(b.Discard, b.batch.Commit(pebble.Sync)) +} + +// Set : see db.Transaction.Set +func (b *batch) Set(key, val []byte) error { + b.rwlock.Lock() + defer b.rwlock.Unlock() + + start := time.Now() + if len(key) == 0 { + return errors.New("empty key") + } + + if b.batch == nil { + return ErrDiscardedTransaction + } + + defer func() { b.listener.OnIO(true, time.Since(start)) }() + + return b.batch.Set(key, val, pebble.Sync) +} + +// Delete : see db.Transaction.Delete +func (b *batch) Delete(key []byte) error { + b.rwlock.Lock() + defer b.rwlock.Unlock() + + if b.batch == nil { + return ErrDiscardedTransaction + } + + start := time.Now() + defer func() { b.listener.OnIO(true, time.Since(start)) }() + + return b.batch.Delete(key, pebble.Sync) +} + +// Get : see db.Transaction.Get +func (b *batch) Get(key []byte, cb func([]byte) error) error { + b.rwlock.RLock() + defer b.rwlock.RUnlock() + + if b.batch == nil { + return ErrDiscardedTransaction + } + return get(b.batch, key, cb, b.listener) +} + +// NewIterator : see db.Transaction.NewIterator +func (b *batch) NewIterator() (db.Iterator, error) { + var iter *pebble.Iterator + var err error + + if b.batch == nil { + return nil, ErrDiscardedTransaction + } + + iter, err = b.batch.NewIter(nil) + if err != nil { + return nil, err + } + + return &iterator{iter: iter}, nil +} diff --git a/db/pebble/common.go b/db/pebble/common.go new file mode 100644 index 0000000000..a67c905acd --- /dev/null +++ b/db/pebble/common.go @@ -0,0 +1,34 @@ +package pebble + +import ( + "errors" + "io" + "time" + + "github.com/NethermindEth/juno/db" + "github.com/NethermindEth/juno/utils" + "github.com/cockroachdb/pebble" +) + +type getter interface { + Get([]byte) ([]byte, io.Closer, error) +} + +func get(g getter, key []byte, cb func([]byte) error, listener db.EventListener) error { + start := time.Now() + var val []byte + var closer io.Closer + + val, closer, err := g.Get(key) + + // We need it evaluated immediately so the duration doesn't include the runtime of the user callback that we call below. + defer listener.OnIO(false, time.Since(start)) //nolint:govet + if err != nil { + if errors.Is(err, pebble.ErrNotFound) { + return db.ErrKeyNotFound + } + return err + } + + return utils.RunAndWrapOnError(closer.Close, cb(val)) +} diff --git a/db/pebble/db.go b/db/pebble/db.go index 6025e7f0df..079bbd064d 100644 --- a/db/pebble/db.go +++ b/db/pebble/db.go @@ -2,6 +2,7 @@ package pebble import ( "context" + "errors" "fmt" "sync" "testing" @@ -18,6 +19,10 @@ const ( minCacheSizeMB = 8 ) +var ( + ErrDiscardedTransaction = errors.New("discarded transaction") + ErrReadOnlyTransaction = errors.New("read-only transaction") +) var _ db.DB = (*DB)(nil) type DB struct { @@ -83,20 +88,14 @@ func (d *DB) WithListener(listener db.EventListener) db.DB { } // NewTransaction : see db.DB.NewTransaction +// Batch is used for read-write operations, while snapshot is used for read-only operations func (d *DB) NewTransaction(update bool) (db.Transaction, error) { - txn := &Transaction{ - listener: d.listener, - } if update { d.wMutex.Lock() - txn.lock = d.wMutex - txn.batch = d.pebble.NewIndexedBatch() - } else { - txn.snapshot = d.pebble.NewSnapshot() + return NewBatch(d.pebble.NewIndexedBatch(), d.wMutex, d.listener), nil } - txn.rwlock = &sync.RWMutex{} - return txn, nil + return NewSnapshot(d.pebble.NewSnapshot(), d.listener), nil } // Close : see io.Closer.Close diff --git a/db/pebble/db_test.go b/db/pebble/db_test.go index c239764cee..896d5fac5c 100644 --- a/db/pebble/db_test.go +++ b/db/pebble/db_test.go @@ -408,7 +408,7 @@ func TestPanic(t *testing.T) { require.ErrorIs(t, testDB.View(func(txn db.Transaction) error { return txn.Get([]byte{0}, func(b []byte) error { return nil }) }), db.ErrKeyNotFound) - require.EqualError(t, panicingTxn.Get([]byte{0}, func(b []byte) error { return nil }), "discarded txn") + require.EqualError(t, panicingTxn.Get([]byte{0}, func(b []byte) error { return nil }), "discarded transaction") }() require.NoError(t, testDB.Update(func(txn db.Transaction) error { diff --git a/db/pebble/snapshot.go b/db/pebble/snapshot.go new file mode 100644 index 0000000000..b8ce545e3e --- /dev/null +++ b/db/pebble/snapshot.go @@ -0,0 +1,75 @@ +package pebble + +import ( + "github.com/NethermindEth/juno/db" + "github.com/cockroachdb/pebble" +) + +var _ db.Transaction = (*snapshot)(nil) + +type snapshot struct { + snapshot *pebble.Snapshot + listener db.EventListener +} + +func NewSnapshot(dbSnapshot *pebble.Snapshot, listener db.EventListener) *snapshot { + return &snapshot{ + snapshot: dbSnapshot, + listener: listener, + } +} + +// Discard : see db.Transaction.Discard +func (s *snapshot) Discard() error { + if s.snapshot == nil { + return nil + } + + if err := s.snapshot.Close(); err != nil { + return err + } + + s.snapshot = nil + + return nil +} + +// Commit : see db.Transaction.Commit +func (s *snapshot) Commit() error { + return ErrReadOnlyTransaction +} + +// Set : see db.Transaction.Set +func (s *snapshot) Set(key, val []byte) error { + return ErrReadOnlyTransaction +} + +// Delete : see db.Transaction.Delete +func (s *snapshot) Delete(key []byte) error { + return ErrReadOnlyTransaction +} + +// Get : see db.Transaction.Get +func (s *snapshot) Get(key []byte, cb func([]byte) error) error { + if s.snapshot == nil { + return ErrDiscardedTransaction + } + return get(s.snapshot, key, cb, s.listener) +} + +// NewIterator : see db.Transaction.NewIterator +func (s *snapshot) NewIterator() (db.Iterator, error) { + var iter *pebble.Iterator + var err error + + if s.snapshot == nil { + return nil, ErrDiscardedTransaction + } + + iter, err = s.snapshot.NewIter(nil) + if err != nil { + return nil, err + } + + return &iterator{iter: iter}, nil +} diff --git a/db/pebble/transaction.go b/db/pebble/transaction.go deleted file mode 100644 index 1963694c28..0000000000 --- a/db/pebble/transaction.go +++ /dev/null @@ -1,145 +0,0 @@ -package pebble - -import ( - "errors" - "io" - "sync" - "time" - - "github.com/NethermindEth/juno/db" - "github.com/NethermindEth/juno/utils" - "github.com/cockroachdb/pebble" -) - -var ErrDiscardedTransaction = errors.New("discarded txn") - -var _ db.Transaction = (*Transaction)(nil) - -type Transaction struct { - batch *pebble.Batch - snapshot *pebble.Snapshot - lock *sync.Mutex - rwlock *sync.RWMutex - listener db.EventListener -} - -// Discard : see db.Transaction.Discard -func (t *Transaction) Discard() error { - if t.batch != nil { - if err := t.batch.Close(); err != nil { - return err - } - t.batch = nil - } - if t.snapshot != nil { - if err := t.snapshot.Close(); err != nil { - return err - } - t.snapshot = nil - } - - if t.lock != nil { - t.lock.Unlock() - t.lock = nil - } - return nil -} - -// Commit : see db.Transaction.Commit -func (t *Transaction) Commit() error { - start := time.Now() - defer func() { t.listener.OnCommit(time.Since(start)) }() - if t.batch != nil { - return utils.RunAndWrapOnError(t.Discard, t.batch.Commit(pebble.Sync)) - } - return utils.RunAndWrapOnError(t.Discard, ErrDiscardedTransaction) -} - -// Set : see db.Transaction.Set -func (t *Transaction) Set(key, val []byte) error { - t.rwlock.Lock() - defer t.rwlock.Unlock() - start := time.Now() - if t.batch == nil { - return errors.New("read only transaction") - } - if len(key) == 0 { - return errors.New("empty key") - } - - defer func() { t.listener.OnIO(true, time.Since(start)) }() - return t.batch.Set(key, val, pebble.Sync) -} - -// Delete : see db.Transaction.Delete -func (t *Transaction) Delete(key []byte) error { - t.rwlock.Lock() - defer t.rwlock.Unlock() - start := time.Now() - if t.batch == nil { - return errors.New("read only transaction") - } - - defer func() { t.listener.OnIO(true, time.Since(start)) }() - return t.batch.Delete(key, pebble.Sync) -} - -// Get : see db.Transaction.Get -func (t *Transaction) Get(key []byte, cb func([]byte) error) error { - t.rwlock.RLock() - defer t.rwlock.RUnlock() - start := time.Now() - var val []byte - var closer io.Closer - - var err error - if t.batch != nil { - val, closer, err = t.batch.Get(key) - } else if t.snapshot != nil { - val, closer, err = t.snapshot.Get(key) - } else { - return ErrDiscardedTransaction - } - - // We need it evaluated immediately so the duration doesn't include the runtime of the user callback that we call below. - defer t.listener.OnIO(false, time.Since(start)) //nolint:govet - if err != nil { - if errors.Is(err, pebble.ErrNotFound) { - return db.ErrKeyNotFound - } - - return err - } - return utils.RunAndWrapOnError(closer.Close, cb(val)) -} - -// Impl : see db.Transaction.Impl -func (t *Transaction) Impl() any { - if t.batch != nil { - return t.batch - } - - if t.snapshot != nil { - return t.snapshot - } - return nil -} - -// NewIterator : see db.Transaction.NewIterator -func (t *Transaction) NewIterator() (db.Iterator, error) { - var iter *pebble.Iterator - var err error - if t.batch != nil { - iter, err = t.batch.NewIter(nil) - } else if t.snapshot != nil { - iter, err = t.snapshot.NewIter(nil) - } else { - return nil, ErrDiscardedTransaction - } - - if err != nil { - return nil, err - } - - return &iterator{iter: iter}, nil -} diff --git a/db/remote/db.go b/db/remote/db.go index 6e7984f771..45b1768a2c 100644 --- a/db/remote/db.go +++ b/db/remote/db.go @@ -4,6 +4,7 @@ import ( "context" "errors" "math" + "time" "github.com/NethermindEth/juno/db" "github.com/NethermindEth/juno/grpc/gen" @@ -14,11 +15,11 @@ import ( var _ db.DB = (*DB)(nil) type DB struct { - ctx context.Context - + ctx context.Context grpcClient *grpc.ClientConn kvClient gen.KVClient log utils.SimpleLogger + listener db.EventListener } func New(rawURL string, ctx context.Context, log utils.SimpleLogger, opts ...grpc.DialOption) (*DB, error) { @@ -27,20 +28,30 @@ func New(rawURL string, ctx context.Context, log utils.SimpleLogger, opts ...grp return nil, err } + listener := &db.SelectiveListener{ + OnIOCb: func(write bool, duration time.Duration) {}, + OnCommitCb: func(duration time.Duration) {}, + } + return &DB{ ctx: ctx, grpcClient: grpcClient, kvClient: gen.NewKVClient(grpcClient), log: log, + listener: listener, }, nil } func (d *DB) NewTransaction(write bool) (db.Transaction, error) { + start := time.Now() + txClient, err := d.kvClient.Tx(d.ctx, grpc.MaxCallSendMsgSize(math.MaxInt), grpc.MaxCallRecvMsgSize(math.MaxInt)) if err != nil { return nil, err } + d.listener.OnIO(write, time.Since(start)) + return &transaction{client: txClient, log: d.log}, nil } @@ -49,10 +60,17 @@ func (d *DB) View(fn func(txn db.Transaction) error) error { } func (d *DB) Update(fn func(txn db.Transaction) error) error { + start := time.Now() + + defer func() { + d.listener.OnCommit(time.Since(start)) + }() + return db.Update(d, fn) } func (d *DB) WithListener(listener db.EventListener) db.DB { + d.listener = listener return d } diff --git a/docs/docs/configuring.md b/docs/docs/configuring.md index ebd3dc9dcb..f05104da4f 100644 --- a/docs/docs/configuring.md +++ b/docs/docs/configuring.md @@ -109,6 +109,7 @@ Juno provides several subcommands to perform specific tasks or operations. Here - `db`: Perform database-related operations - `db info`: Retrieve information about the database. - `db size`: Calculate database size information for each data type. + - `db revert`: Reverts the database to a specific block number. To use a subcommand, append it when running Juno: diff --git a/docs/docs/plugins.md b/docs/docs/plugins.md new file mode 100644 index 0000000000..816f028906 --- /dev/null +++ b/docs/docs/plugins.md @@ -0,0 +1,82 @@ +--- +title: Juno Plugins +--- + +Juno supports plugins that satisfy the `JunoPlugin` interface, enabling developers to extend and customize Juno's behaviour and functionality by dynamically loading external plugins during runtime. + +The `JunoPlugin` interface provides a structured way for plugins to interact with the blockchain by sending notifications when new blocks are added or reverted. This ensures state consistency, especially during blockchain reorganizations, while abstracting away the complexity of implementing block syncing and revert logic. + +## JunoPlugin Interface + +Your plugin must implement the `JunoPlugin` interface, which includes methods for initializing, shutting down, and handling new and reverted blocks. + +```go +type JunoPlugin interface { + Init() error + Shutdown() error + NewBlock(block *core.Block, stateUpdate *core.StateUpdate, newClasses map[felt.Felt]core.Class) error + RevertBlock(from, to *BlockAndStateUpdate, reverseStateDiff *core.StateDiff) error +} +``` + +**Init**: Called when the plugin is initialized. This can be used to set up database connections or any other necessary resources. + +**Shutdown**: Called when the Juno node is shut down. This can be used to clean up resources like database connections. + +**NewBlock**: Triggered when a new block is synced by the Juno client. Juno will send the block, the corresponding state update, and any new classes. Importantly, Juno waits for the plugin to finish processing this function call before continuing. This ensures that the plugin completes its task before Juno proceeds with the blockchain sync. + +**RevertBlock**: Called during a blockchain reorganization (reorg). Juno will invoke this method for each block that needs to be reverted. Similar to NewBlock, the client will wait for the plugin to finish handling the revert before moving on to the next block. + +## Example plugin + +Here is a basic example of a plugin that satisfies the `JunoPlugin` interface: + +```go +// go:generate go build -buildmode=plugin -o ../../build/plugin.so ./example.go +type examplePlugin string + +// Important: "JunoPluginInstance" needs to be exported for Juno to load the plugin correctly +var JunoPluginInstance examplePlugin + +var _ junoplugin.JunoPlugin = (*examplePlugin)(nil) + +func (p *examplePlugin) Init() error { + fmt.Println("ExamplePlugin initialized") + return nil +} + +func (p *examplePlugin) Shutdown() error { + fmt.Println("ExamplePlugin shutdown") + return nil +} + +func (p *examplePlugin) NewBlock(block *core.Block, stateUpdate *core.StateUpdate, newClasses map[felt.Felt]core.Class) error { + fmt.Println("ExamplePlugin NewBlock called") + return nil +} + +func (p *examplePlugin) RevertBlock(from, to *junoplugin.BlockAndStateUpdate, reverseStateDiff *core.StateDiff) error { + fmt.Println("ExamplePlugin RevertBlock called") + return nil +} +``` + +The `JunoPluginInstance` variable must be exported for Juno to correctly load the plugin: +`var JunoPluginInstance examplePlugin` + +We ensure the plugin implements the `JunoPlugin` interface, with the following line: +`var _ junoplugin.JunoPlugin = (*examplePlugin)(nil)` + +## Building and loading the plugin + +Once you have written your plugin, you can compile it into a shared object file (.so) using the following command: + +```shell +go build -buildmode=plugin -o ./plugin.so /path/to/your/plugin.go +``` + +This command compiles the plugin into a shared object file (`plugin.so`), which can then be loaded by the Juno client using the `--plugin-path` flag. + +## Running Juno with the plugin + +Once your plugin has been compiled into a `.so` file, you can run Juno with your plugin by providing the `--plugin-path` flag. This flag tells Juno where to find and load your plugin at runtime. diff --git a/docs/docs/snapshots.md b/docs/docs/snapshots.md index ba31407f7a..9feb3769f7 100644 --- a/docs/docs/snapshots.md +++ b/docs/docs/snapshots.md @@ -18,6 +18,12 @@ You can download a snapshot of the Juno database to reduce the network syncing t | ------- | ------------- | | **>=v0.9.2** | [**juno_sepolia.tar**](https://juno-snapshots.nethermind.dev/files/sepolia/latest) | +## Sepolia-Integration + +| Version | Download Link | +| ------- | ------------- | +| **>=v0.9.2** | [**juno_sepolia_integration.tar**](https://juno-snapshots.nethermind.dev/files/sepolia-integration/latest) | + ## Getting snapshot sizes ```console @@ -29,6 +35,9 @@ $curl -s -I -L https://juno-snapshots.nethermind.dev/files/mainnet/latest | gawk $curl -s -I -L https://juno-snapshots.nethermind.dev/files/sepolia/latest | gawk -v IGNORECASE=1 '/^Content-Length/ { printf "%.2f GB\n", $2/1024/1024/1024 }' 5.67 GB + +$curl -s -I -L https://juno-snapshots.nethermind.dev/files/sepolia-integration/latest | gawk -v IGNORECASE=1 '/^Content-Length/ { printf "%.2f GB\n", $2/1024/1024/1024 }' +2.4 GB ``` ## Run Juno with a snapshot diff --git a/docs/package-lock.json b/docs/package-lock.json index 8c8d94a325..124c752d15 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -5141,24 +5141,6 @@ "@types/ms": "*" } }, - "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -5625,10 +5607,10 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", "peerDependencies": { "acorn": "^8" } @@ -5997,9 +5979,9 @@ } }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -6009,7 +5991,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -6677,9 +6659,9 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "engines": { "node": ">= 0.6" } @@ -7515,17 +7497,17 @@ } }, "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "engines": { "node": ">= 0.8" } }, "node_modules/enhanced-resolve": { - "version": "5.16.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz", - "integrity": "sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -7821,36 +7803,36 @@ } }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -7886,9 +7868,9 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" }, "node_modules/express/node_modules/range-parser": { "version": "1.2.1", @@ -8073,12 +8055,12 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -10364,9 +10346,12 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-stream": { "version": "2.0.0", @@ -12061,9 +12046,9 @@ ] }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -12318,9 +12303,12 @@ } }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -13479,11 +13467,11 @@ } }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -14485,9 +14473,9 @@ } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -14520,6 +14508,14 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -14632,14 +14628,14 @@ } }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" @@ -15976,20 +15972,19 @@ } }, "node_modules/webpack": { - "version": "5.91.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", - "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dependencies": { - "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", + "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.16.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", diff --git a/docs/sidebars.js b/docs/sidebars.js index 10125a3020..b98fd7bacf 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -12,6 +12,7 @@ const sidebars = { "hardware-requirements", "running-juno", "configuring", + "plugins", "running-on-gcp", "updating", ], diff --git a/docs/versioned_docs/version-0.11.8/snapshots.md b/docs/versioned_docs/version-0.11.8/snapshots.md index 6011ca4c03..94fbd0c1b0 100644 --- a/docs/versioned_docs/version-0.11.8/snapshots.md +++ b/docs/versioned_docs/version-0.11.8/snapshots.md @@ -18,6 +18,12 @@ You can download a snapshot of the Juno database to reduce the network syncing t | ------- | ------------- | | **>=v0.9.2** | [**juno_sepolia.tar**](https://juno-snapshots.nethermind.dev/files/sepolia/latest) | +## Sepolia-Integration + +| Version | Download Link | +| ------- | ------------- | +| **>=v0.9.2** | [**juno_sepolia_integration.tar**](https://juno-snapshots.nethermind.dev/files/sepolia-integration/latest) | + ### Getting the size for each snapshot ```console $date @@ -28,6 +34,9 @@ $curl -s -I -L https://juno-snapshots.nethermind.dev/files/mainnet/latest | gawk $curl -s -I -L https://juno-snapshots.nethermind.dev/files/sepolia/latest | gawk -v IGNORECASE=1 '/^Content-Length/ { printf "%.2f GB\n", $2/1024/1024/1024 }' 5.67 GB + +$curl -s -I -L https://juno-snapshots.nethermind.dev/files/sepolia-integration/latest | gawk -v IGNORECASE=1 '/^Content-Length/ { printf "%.2f GB\n", $2/1024/1024/1024 }' +2.4 GB ``` ## Run Juno with a snapshot diff --git a/go.mod b/go.mod index 5e064920fd..8526f8a8f2 100644 --- a/go.mod +++ b/go.mod @@ -1,42 +1,41 @@ module github.com/NethermindEth/juno // if version specified as "1.22" (without bugfix) it breaks CodeQL github build -go 1.23.0 +go 1.23.1 require ( - github.com/Masterminds/semver/v3 v3.2.1 - github.com/bits-and-blooms/bitset v1.13.0 - github.com/bits-and-blooms/bloom/v3 v3.6.0 - github.com/cockroachdb/pebble v1.1.1 - github.com/consensys/gnark-crypto v0.13.0 + github.com/Masterminds/semver/v3 v3.3.0 + github.com/bits-and-blooms/bitset v1.14.3 + github.com/bits-and-blooms/bloom/v3 v3.7.0 + github.com/cockroachdb/pebble v1.1.2 + github.com/coder/websocket v1.8.12 + github.com/consensys/gnark-crypto v0.14.0 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc - github.com/ethereum/go-ethereum v1.14.7 + github.com/ethereum/go-ethereum v1.14.11 github.com/fxamacker/cbor/v2 v2.7.0 - github.com/go-playground/validator/v10 v10.22.0 + github.com/go-playground/validator/v10 v10.22.1 github.com/jinzhu/copier v0.4.0 - github.com/libp2p/go-libp2p v0.34.0 - github.com/libp2p/go-libp2p-kad-dht v0.25.2 - github.com/libp2p/go-libp2p-pubsub v0.11.0 + github.com/libp2p/go-libp2p v0.36.2 + github.com/libp2p/go-libp2p-kad-dht v0.27.0 + github.com/libp2p/go-libp2p-pubsub v0.12.0 github.com/mitchellh/mapstructure v1.5.0 github.com/multiformats/go-multiaddr v0.13.0 github.com/olekukonko/tablewriter v0.0.5 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.19.1 - github.com/rs/cors v1.11.0 + github.com/prometheus/client_golang v1.20.5 + github.com/rs/cors v1.11.1 github.com/sourcegraph/conc v0.3.0 - github.com/spf13/cobra v1.8.0 + github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 - go.uber.org/automaxprocs v1.5.3 - go.uber.org/mock v0.4.0 + go.uber.org/automaxprocs v1.6.0 + go.uber.org/mock v0.5.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.26.0 - golang.org/x/sync v0.8.0 - google.golang.org/grpc v1.65.0 - google.golang.org/protobuf v1.34.2 + golang.org/x/crypto v0.28.0 + google.golang.org/grpc v1.67.1 + google.golang.org/protobuf v1.35.1 gopkg.in/yaml.v3 v3.0.1 - nhooyr.io/websocket v1.8.11 ) require ( @@ -44,7 +43,7 @@ require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cockroachdb/errors v1.11.3 // indirect github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect @@ -54,50 +53,51 @@ require ( github.com/consensys/bavard v0.1.13 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c // indirect github.com/crate-crypto/go-kzg-4844 v1.1.0 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/elastic/gosigar v0.14.2 // indirect + github.com/elastic/gosigar v0.14.3 // indirect github.com/ethereum/c-kzg-4844 v1.0.0 // indirect + github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gabriel-vasile/mimetype v1.4.4 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect + github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/gorilla/websocket v1.5.1 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/holiman/uint256 v1.3.0 // indirect + github.com/holiman/uint256 v1.3.1 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/ipfs/boxo v0.17.0 // indirect + github.com/ipfs/boxo v0.22.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect - github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/compress v1.17.8 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -106,9 +106,9 @@ require ( github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect - github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect + github.com/libp2p/go-libp2p-kbucket v0.6.4 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.7.3 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.7.4 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect @@ -118,7 +118,7 @@ require ( github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect - github.com/miekg/dns v1.1.58 // indirect + github.com/miekg/dns v1.1.62 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -133,34 +133,34 @@ require ( github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.15.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/onsi/ginkgo/v2 v2.20.0 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect - github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/pion/datachannel v1.5.6 // indirect - github.com/pion/dtls/v2 v2.2.11 // indirect - github.com/pion/ice/v2 v2.3.24 // indirect - github.com/pion/interceptor v0.1.29 // indirect + github.com/pion/datachannel v1.5.8 // indirect + github.com/pion/dtls/v2 v2.2.12 // indirect + github.com/pion/ice/v2 v2.3.34 // indirect + github.com/pion/interceptor v0.1.30 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/mdns v0.0.12 // indirect github.com/pion/randutil v0.1.0 // indirect github.com/pion/rtcp v1.2.14 // indirect - github.com/pion/rtp v1.8.6 // indirect - github.com/pion/sctp v1.8.16 // indirect + github.com/pion/rtp v1.8.9 // indirect + github.com/pion/sctp v1.8.33 // indirect github.com/pion/sdp/v3 v3.0.9 // indirect - github.com/pion/srtp/v2 v2.0.18 // indirect + github.com/pion/srtp/v2 v2.0.20 // indirect github.com/pion/stun v0.6.1 // indirect - github.com/pion/transport/v2 v2.2.5 // indirect + github.com/pion/transport/v2 v2.2.10 // indirect github.com/pion/turn/v2 v2.1.6 // indirect - github.com/pion/webrtc/v3 v3.2.40 // indirect + github.com/pion/webrtc/v3 v3.3.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.51.1 // indirect - github.com/prometheus/procfs v0.13.0 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.44.0 // indirect + github.com/quic-go/quic-go v0.46.0 // indirect github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rivo/uniseg v0.4.2 // indirect @@ -172,28 +172,30 @@ require ( github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/supranational/blst v0.3.11 // indirect + github.com/supranational/blst v0.3.13 // indirect github.com/tklauser/go-sysconf v0.3.13 // indirect github.com/tklauser/numcpus v0.7.0 // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect + github.com/wlynxg/anet v0.0.4 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.24.0 // indirect - go.opentelemetry.io/otel/metric v1.24.0 // indirect - go.opentelemetry.io/otel/trace v1.24.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.21.1 // indirect + go.opentelemetry.io/otel v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 // indirect + go.opentelemetry.io/otel/trace v1.27.0 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.25.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - gonum.org/v1/gonum v0.14.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect + golang.org/x/tools v0.24.0 // indirect + gonum.org/v1/gonum v0.15.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - lukechampine.com/blake3 v1.2.1 // indirect + lukechampine.com/blake3 v1.3.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index 2549df1b7b..a48d73a00e 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGy github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e h1:ZIWapoIRN1VqT8GR8jAwb1Ie9GyehWjVcGh32Y2MznE= github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= -github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= @@ -25,13 +25,13 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 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/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= -github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/bits-and-blooms/bloom/v3 v3.6.0 h1:dTU0OVLJSoOhz9m68FTXMFfA39nR8U/nTCs1zb26mOI= -github.com/bits-and-blooms/bloom/v3 v3.6.0/go.mod h1:VKlUSvp0lFIYqxJjzdnSsZEw4iHb1kOL2tfHTgyJBHg= +github.com/bits-and-blooms/bitset v1.14.3 h1:Gd2c8lSNf9pKXom5JtD7AaKO8o7fGQ2LtFj1436qilA= +github.com/bits-and-blooms/bitset v1.14.3/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bloom/v3 v3.7.0 h1:VfknkqV4xI+PsaDIsoHueyxVDZrfvMn56jeWUzvzdls= +github.com/bits-and-blooms/bloom/v3 v3.7.0/go.mod h1:VKlUSvp0lFIYqxJjzdnSsZEw4iHb1kOL2tfHTgyJBHg= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= 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/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= @@ -51,16 +51,18 @@ github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/e github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= 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 v1.1.1 h1:XnKU22oiCLy2Xn8vp1re67cXg4SAasg/WDt1NtcRFaw= -github.com/cockroachdb/pebble v1.1.1/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= +github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo= +github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.13.0 h1:VPULb/v6bbYELAPTDFINEVaMTTybV5GLxDdcjnS+4oc= -github.com/consensys/gnark-crypto v0.13.0/go.mod h1:wKqwsieaKPThcFkHe0d0zMsbHEUWFmZcG7KBCse210o= +github.com/consensys/gnark-crypto v0.14.0 h1:DDBdl4HaBtdQsq/wfMwJvZNE80sHidrK3Nfrefatm0E= +github.com/consensys/gnark-crypto v0.14.0/go.mod h1:CU4UijNPsHawiVGNxe9co07FkzCeWHHrb1li/n1XoU0= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= @@ -70,8 +72,8 @@ github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8 github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLRPrZhHjHxufI8+2UG/i25QG92j0Er9p6I= github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= @@ -94,20 +96,18 @@ github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4 github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= -github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo= +github.com/elastic/gosigar v0.14.3/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= 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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/go-ethereum v1.14.7 h1:EHpv3dE8evQmpVEQ/Ne2ahB06n2mQptdwqaMNhAT29g= -github.com/ethereum/go-ethereum v1.14.7/go.mod h1:Mq0biU2jbdmKSZoqOj29017ygFrMnB5/Rifwp980W4o= -github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0 h1:KrE8I4reeVvf7C1tm8elRjj4BdscTYzz/WAbYyf/JI4= -github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0/go.mod h1:D9AJLVXSyZQXJQVk8oh1EwjISE+sJTn2duYIZC0dy3w= -github.com/fjl/memsize v0.0.2 h1:27txuSD9or+NZlnOWdKUxeBzTAUkWCVh+4Gf2dWFOzA= -github.com/fjl/memsize v0.0.2/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/ethereum/go-ethereum v1.14.11 h1:8nFDCUUE67rPc6AKxFj7JKaOa2W/W1Rse3oS6LvvxEY= +github.com/ethereum/go-ethereum v1.14.11/go.mod h1:+l/fr42Mma+xBnhefL/+z11/hcmJ2egl+ScIVPjhc7E= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 h1:8NfxH2iXvJ60YRB8ChToFTUzl8awsc3cJ8CbLjGIl/A= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= @@ -120,8 +120,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= +github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= @@ -132,8 +132,8 @@ github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm 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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= @@ -145,10 +145,10 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= -github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= +github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -179,8 +179,6 @@ 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.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -201,9 +199,8 @@ github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= 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.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -214,8 +211,8 @@ github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE0 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -235,14 +232,16 @@ github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6w github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= 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.3.0 h1:4wdcm/tnd0xXdu7iS3ruNvxkWwrb4aeBQv19ayYn8F4= -github.com/holiman/uint256 v1.3.0/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= +github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/ipfs/boxo v0.17.0 h1:fVXAb12dNbraCX1Cdid5BB6Kl62gVLNVA+e0EYMqAU0= -github.com/ipfs/boxo v0.17.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= +github.com/ipfs/boxo v0.22.0 h1:QTC+P5uhsBNq6HzX728nsLyFW6rYDeR/5hggf9YZX78= +github.com/ipfs/boxo v0.22.0/go.mod h1:yp1loimX0BDYOR0cyjtcXHv15muEh5V1FqO2QLlzykw= +github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= +github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= @@ -251,11 +250,10 @@ github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= -github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= -github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= -github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= +github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew= +github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI= github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= @@ -275,10 +273,10 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV 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.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -292,8 +290,8 @@ 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 v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= -github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= @@ -302,20 +300,20 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.34.0 h1:J+SL3DMz+zPz06OHSRt42GKA5n5hmwgY1l7ckLUz3+c= -github.com/libp2p/go-libp2p v0.34.0/go.mod h1:snyJQix4ET6Tj+LeI0VPjjxTtdWpeOhYt5lEY0KirkQ= +github.com/libp2p/go-libp2p v0.36.2 h1:BbqRkDaGC3/5xfaJakLV/BrpjlAuYqSB0lRvtzL3B/U= +github.com/libp2p/go-libp2p v0.36.2/go.mod h1:XO3joasRE4Eup8yCTTP/+kX+g92mOgRaadk46LmPhHY= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= -github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= -github.com/libp2p/go-libp2p-kad-dht v0.25.2/go.mod h1:6za56ncRHYXX4Nc2vn8z7CZK0P4QiMcrn77acKLM2Oo= -github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= -github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= -github.com/libp2p/go-libp2p-pubsub v0.11.0 h1:+JvS8Kty0OiyUiN0i8H5JbaCgjnJTRnTHe4rU88dLFc= -github.com/libp2p/go-libp2p-pubsub v0.11.0/go.mod h1:QEb+hEV9WL9wCiUAnpY29FZR6W3zK8qYlaml8R4q6gQ= +github.com/libp2p/go-libp2p-kad-dht v0.27.0 h1:1Ea32tVTPiAfaLpPMbaBWFJgbsi/JpMqC2YBuFdf32o= +github.com/libp2p/go-libp2p-kad-dht v0.27.0/go.mod h1:ixhjLuzaXSGtWsKsXTj7erySNuVC4UP7NO015cRrF14= +github.com/libp2p/go-libp2p-kbucket v0.6.4 h1:OjfiYxU42TKQSB8t8WYd8MKhYhMJeO2If+NiuKfb6iQ= +github.com/libp2p/go-libp2p-kbucket v0.6.4/go.mod h1:jp6w82sczYaBsAypt5ayACcRJi0lgsba7o4TzJKEfWA= +github.com/libp2p/go-libp2p-pubsub v0.12.0 h1:PENNZjSfk8KYxANRlpipdS7+BfLmOl3L2E/6vSNjbdI= +github.com/libp2p/go-libp2p-pubsub v0.12.0/go.mod h1:Oi0zw9aw8/Y5GC99zt+Ef2gYAl+0nZlwdJonDyOz/sE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= -github.com/libp2p/go-libp2p-routing-helpers v0.7.3/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= +github.com/libp2p/go-libp2p-routing-helpers v0.7.4 h1:6LqS1Bzn5CfDJ4tzvP9uwh42IB7TJLNFJA6dEeGBv84= +github.com/libp2p/go-libp2p-routing-helpers v0.7.4/go.mod h1:we5WDj9tbolBXOuF1hGOkR+r7Uh1408tQbAKaT5n1LE= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= @@ -345,8 +343,8 @@ github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= -github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= +github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= +github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -393,19 +391,19 @@ github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dy github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= 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/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= -github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= -github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= +github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= @@ -413,15 +411,15 @@ github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6 github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg= -github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4= +github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo= +github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks= -github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.24 h1:RYgzhH/u5lH0XO+ABatVKCtRd+4U1GEaCXSMjNr13tI= -github.com/pion/ice/v2 v2.3.24/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= -github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= -github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= +github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= +github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM= +github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= +github.com/pion/interceptor v0.1.30 h1:au5rlVHsgmxNi+v/mjOPazbW1SHzfx7/hYOEYQnUcxA= +github.com/pion/interceptor v0.1.30/go.mod h1:RQuKT5HTdkP2Fi0cuOS5G5WNymTjzXaGF75J4k7z2nc= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= @@ -432,31 +430,29 @@ github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9 github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/rtp v1.8.6 h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw= -github.com/pion/rtp v1.8.6/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/sctp v1.8.13/go.mod h1:YKSgO/bO/6aOMP9LCie1DuD7m+GamiK2yIiPM6vH+GA= -github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY= -github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE= +github.com/pion/rtp v1.8.9 h1:E2HX740TZKaqdcPmf4pw6ZZuG8u5RlMMt+l3dxeu6Wk= +github.com/pion/rtp v1.8.9/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.33 h1:dSE4wX6uTJBcNm8+YlMg7lw1wqyKHggsP5uKbdj+NZw= +github.com/pion/sctp v1.8.33/go.mod h1:beTnqSzewI53KWoG3nqB282oDMGrhNxBdb+JZnkCwRM= github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= -github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= -github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= +github.com/pion/srtp/v2 v2.0.20/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= -github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc= github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= -github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc= -github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= +github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= -github.com/pion/transport/v3 v3.0.2 h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkLg4= -github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37m0IlWa/D0= +github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0= +github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo= github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.40 h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU= -github.com/pion/webrtc/v3 v3.2.40/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= +github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I= +github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -469,22 +465,22 @@ github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.51.1 h1:eIjN50Bwglz6a/c3hAgSMcofL3nD+nFQkV6Dd4DsQCw= -github.com/prometheus/common v0.51.1/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= -github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0= -github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek= +github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y= +github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -492,12 +488,11 @@ github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtD github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8= github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= -github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= 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= @@ -548,8 +543,8 @@ github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= @@ -563,7 +558,6 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/ 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.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.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -574,8 +568,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= -github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= +github.com/supranational/blst v0.3.13/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/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= @@ -598,6 +592,9 @@ github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSD github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= +github.com/wlynxg/anet v0.0.4 h1:0de1OFQxnNqAu+x2FAKKCVIrnfGKQbs7FQz++tB0+Uw= +github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= @@ -611,31 +608,27 @@ github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQ go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= -go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= -go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= +go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= +go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= +go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= +go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= +go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= -go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.21.1 h1:RqBh3cYdzZS0uqwVeEjOX2p73dddLpym315myy/Bpb0= -go.uber.org/fx v1.21.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= @@ -644,7 +637,6 @@ golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+ golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/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-20190313024323-a1f597ede03a/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-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -652,31 +644,27 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 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-20190313153728-d0100b6bd8b3/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-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/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.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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= @@ -698,13 +686,10 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -748,34 +733,27 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= 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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= @@ -789,9 +767,6 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/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-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -799,14 +774,14 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= -gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= -gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= +gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= +gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= @@ -821,8 +796,8 @@ google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -831,8 +806,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= 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= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -842,14 +817,13 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 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.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= 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-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/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -869,11 +843,8 @@ honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWh 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-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= -lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= -nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= -nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= +lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= +lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= diff --git a/jsonrpc/http.go b/jsonrpc/http.go index 68dccd642f..e9f5a0bb1b 100644 --- a/jsonrpc/http.go +++ b/jsonrpc/http.go @@ -1,6 +1,7 @@ package jsonrpc import ( + "maps" "net/http" "github.com/NethermindEth/juno/utils" @@ -46,8 +47,11 @@ func (h *HTTP) ServeHTTP(writer http.ResponseWriter, req *http.Request) { req.Body = http.MaxBytesReader(writer, req.Body, MaxRequestBodySize) h.listener.OnNewRequest("any") - resp, err := h.rpc.HandleReader(req.Context(), req.Body) + resp, header, err := h.rpc.HandleReader(req.Context(), req.Body) + writer.Header().Set("Content-Type", "application/json") + maps.Copy(writer.Header(), header) // overwrites duplicate headers + if err != nil { h.log.Errorw("Handler failure", "err", err) writer.WriteHeader(http.StatusInternalServerError) diff --git a/jsonrpc/server.go b/jsonrpc/server.go index b75aeae6d0..c63f15c849 100644 --- a/jsonrpc/server.go +++ b/jsonrpc/server.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "io" + "net/http" "reflect" "strings" "sync" @@ -183,11 +184,18 @@ func (s *Server) registerMethod(method Method) error { if numArgs != len(method.Params) { return errors.New("number of non-context function params and param names must match") } - if handlerT.NumOut() != 2 { - return errors.New("handler must return 2 values") + outSize := handlerT.NumOut() + if outSize < 2 || outSize > 3 { + return errors.New("handler must return 2 or 3 values") } - if handlerT.Out(1) != reflect.TypeOf(&Error{}) { - return errors.New("second return value must be a *jsonrpc.Error") + if outSize == 2 && handlerT.Out(1) != reflect.TypeOf(&Error{}) { + return errors.New("second return value must be a *jsonrpc.Error for 2 tuple handler") + } else if outSize == 3 && handlerT.Out(2) != reflect.TypeOf(&Error{}) { + return errors.New("third return value must be a *jsonrpc.Error for 3 tuple handler") + } + + if outSize == 3 && handlerT.Out(1) != reflect.TypeOf(http.Header{}) { + return errors.New("second return value must be a http.Header for 3 tuple handler") } // The method is valid. Mutate the appropriate fields and register on the server. @@ -255,7 +263,8 @@ func (s *Server) HandleReadWriter(ctx context.Context, rw io.ReadWriter) error { activated: activated, } msgCtx := context.WithValue(ctx, ConnKey{}, conn) - resp, err := s.HandleReader(msgCtx, rw) + // header is unnecessary for read-writer(websocket) + resp, _, err := s.HandleReader(msgCtx, rw) if err != nil { conn.initialErr = err return err @@ -272,13 +281,15 @@ func (s *Server) HandleReadWriter(ctx context.Context, rw io.ReadWriter) error { // HandleReader processes a request to the server // It returns the response in a byte array, only returns an // error if it can not create the response byte array -func (s *Server) HandleReader(ctx context.Context, reader io.Reader) ([]byte, error) { +func (s *Server) HandleReader(ctx context.Context, reader io.Reader) ([]byte, http.Header, error) { bufferedReader := bufio.NewReaderSize(reader, bufferSize) requestIsBatch := isBatch(bufferedReader) res := &response{ Version: "2.0", } + header := http.Header{} + dec := json.NewDecoder(bufferedReader) dec.UseNumber() @@ -286,13 +297,15 @@ func (s *Server) HandleReader(ctx context.Context, reader io.Reader) ([]byte, er req := new(Request) if jsonErr := dec.Decode(req); jsonErr != nil { res.Error = Err(InvalidJSON, jsonErr.Error()) - } else if resObject, handleErr := s.handleRequest(ctx, req); handleErr != nil { + } else if resObject, httpHeader, handleErr := s.handleRequest(ctx, req); handleErr != nil { if !errors.Is(handleErr, ErrInvalidID) { res.ID = req.ID } res.Error = Err(InvalidRequest, handleErr.Error()) + header = httpHeader } else { res = resObject + header = httpHeader } } else { var batchReq []json.RawMessage @@ -307,23 +320,27 @@ func (s *Server) HandleReader(ctx context.Context, reader io.Reader) ([]byte, er } if res == nil { - return nil, nil + return nil, header, nil } - return json.Marshal(res) + + result, err := json.Marshal(res) + return result, header, err } -func (s *Server) handleBatchRequest(ctx context.Context, batchReq []json.RawMessage) ([]byte, error) { +func (s *Server) handleBatchRequest(ctx context.Context, batchReq []json.RawMessage) ([]byte, http.Header, error) { var ( - responses []json.RawMessage mutex sync.Mutex + responses []json.RawMessage + headers []http.Header ) - addResponse := func(response any) { + addResponse := func(response any, header http.Header) { if responseJSON, err := json.Marshal(response); err != nil { s.log.Errorw("failed to marshal response", "err", err) } else { mutex.Lock() responses = append(responses, responseJSON) + headers = append(headers, header) mutex.Unlock() } } @@ -341,7 +358,7 @@ func (s *Server) handleBatchRequest(ctx context.Context, batchReq []json.RawMess addResponse(&response{ Version: "2.0", Error: Err(InvalidRequest, err.Error()), - }) + }, http.Header{}) continue } @@ -349,7 +366,7 @@ func (s *Server) handleBatchRequest(ctx context.Context, batchReq []json.RawMess s.pool.Go(func() { defer wg.Done() - resp, err := s.handleRequest(ctx, req) + resp, header, err := s.handleRequest(ctx, req) if err != nil { resp = &response{ Version: "2.0", @@ -359,20 +376,33 @@ func (s *Server) handleBatchRequest(ctx context.Context, batchReq []json.RawMess resp.ID = req.ID } } - // for notification request response is nil + // for notification request response is nil and header is irrelevant for now if resp != nil { - addResponse(resp) + addResponse(resp, header) } }) } wg.Wait() + + // merge headers + finalHeaders := http.Header{} + for _, header := range headers { + for k, v := range header { + for _, e := range v { + finalHeaders.Add(k, e) + } + } + } + // according to the spec if there are no response objects server must not return empty array if len(responses) == 0 { - return nil, nil + return nil, finalHeaders, nil } - return json.Marshal(responses) + result, err := json.Marshal(responses) + + return result, finalHeaders, err // todo: fix batch request aggregate header } func isBatch(reader *bufio.Reader) bool { @@ -396,11 +426,13 @@ func isNil(i any) bool { return i == nil || reflect.ValueOf(i).IsNil() } -func (s *Server) handleRequest(ctx context.Context, req *Request) (*response, error) { +func (s *Server) handleRequest(ctx context.Context, req *Request) (*response, http.Header, error) { s.log.Tracew("Received request", "req", req) + + header := http.Header{} if err := req.isSane(); err != nil { s.log.Tracew("Request sanity check failed", "err", err) - return nil, err + return nil, header, err } res := &response{ @@ -412,7 +444,7 @@ func (s *Server) handleRequest(ctx context.Context, req *Request) (*response, er if !found { res.Error = Err(MethodNotFound, nil) s.log.Tracew("Method not found in request", "method", req.Method) - return res, nil + return res, header, nil } handlerTimer := time.Now() @@ -421,7 +453,7 @@ func (s *Server) handleRequest(ctx context.Context, req *Request) (*response, er if err != nil { res.Error = Err(InvalidParams, err.Error()) s.log.Tracew("Error building arguments for RPC call", "err", err) - return res, nil + return res, header, nil } defer func() { s.listener.OnRequestHandled(req.Method, time.Since(handlerTimer)) @@ -430,10 +462,16 @@ func (s *Server) handleRequest(ctx context.Context, req *Request) (*response, er tuple := reflect.ValueOf(calledMethod.Handler).Call(args) if res.ID == nil { // notification s.log.Tracew("Notification received, no response expected") - return nil, nil + return nil, header, nil + } + + errorIndex := 1 + if len(tuple) == 3 { + errorIndex = 2 + header = (tuple[1].Interface()).(http.Header) } - if errAny := tuple[1].Interface(); !isNil(errAny) { + if errAny := tuple[errorIndex].Interface(); !isNil(errAny) { res.Error = errAny.(*Error) if res.Error.Code == InternalError { s.listener.OnRequestFailed(req.Method, res.Error) @@ -441,11 +479,11 @@ func (s *Server) handleRequest(ctx context.Context, req *Request) (*response, er errJSON, _ := json.Marshal(res.Error) s.log.Debugw("Failed handing RPC request", "req", string(reqJSON), "res", string(errJSON)) } - return res, nil + return res, header, nil } res.Result = tuple[0].Interface() - return res, nil + return res, header, nil } func (s *Server) buildArguments(ctx context.Context, params any, method Method) ([]reflect.Value, error) { diff --git a/jsonrpc/server_test.go b/jsonrpc/server_test.go index 36794456ed..196aec253e 100644 --- a/jsonrpc/server_test.go +++ b/jsonrpc/server_test.go @@ -40,17 +40,27 @@ func TestServer_RegisterMethod(t *testing.T) { "no return": { handler: func(param1, param2 int) {}, paramNames: []jsonrpc.Parameter{{Name: "param1"}, {Name: "param2"}}, - want: "handler must return 2 values", + want: "handler must return 2 or 3 values", }, "int return": { handler: func(param1, param2 int) (int, int) { return 0, 0 }, paramNames: []jsonrpc.Parameter{{Name: "param1"}, {Name: "param2"}}, - want: "second return value must be a *jsonrpc.Error", + want: "second return value must be a *jsonrpc.Error for 2 tuple handler", + }, + "no error return 3": { + handler: func(param1, param2 int) (int, int, int) { return 0, 0, 0 }, + paramNames: []jsonrpc.Parameter{{Name: "param1"}, {Name: "param2"}}, + want: "third return value must be a *jsonrpc.Error for 3 tuple handler", + }, + "no header return 3": { + handler: func(param1, param2 int) (int, int, *jsonrpc.Error) { return 0, 0, &jsonrpc.Error{} }, + paramNames: []jsonrpc.Parameter{{Name: "param1"}, {Name: "param2"}}, + want: "second return value must be a http.Header for 3 tuple handler", }, "no error return": { handler: func(param1, param2 int) (any, int) { return 0, 0 }, paramNames: []jsonrpc.Parameter{{Name: "param1"}, {Name: "param2"}}, - want: "second return value must be a *jsonrpc.Error", + want: "second return value must be a *jsonrpc.Error for 2 tuple handler", }, } @@ -472,8 +482,9 @@ func TestHandle(t *testing.T) { oldRequestFailedEventCount := len(listener.OnRequestFailedCalls) oldRequestHandledCalls := len(listener.OnRequestHandledCalls) - res, err := server.HandleReader(context.Background(), strings.NewReader(test.req)) + res, httpHeader, err := server.HandleReader(context.Background(), strings.NewReader(test.req)) require.NoError(t, err) + assert.NotNil(t, httpHeader) if test.isBatch { assertBatchResponse(t, test.res, string(res)) @@ -515,8 +526,9 @@ func BenchmarkHandle(b *testing.B) { const request = `{"jsonrpc":"2.0","id":1,"method":"test"}` for i := 0; i < b.N; i++ { - _, err := server.HandleReader(context.Background(), strings.NewReader(request)) + _, header, err := server.HandleReader(context.Background(), strings.NewReader(request)) require.NoError(b, err) + require.NotNil(b, header) } } @@ -531,9 +543,10 @@ func TestCannotWriteToConnInHandler(t *testing.T) { return 0, nil }, })) - res, err := server.HandleReader(context.Background(), strings.NewReader(`{"jsonrpc":"2.0","id":1,"method":"test"}`)) + res, header, err := server.HandleReader(context.Background(), strings.NewReader(`{"jsonrpc":"2.0","id":1,"method":"test"}`)) require.NoError(t, err) require.Equal(t, `{"jsonrpc":"2.0","result":0,"id":1}`, string(res)) + require.NotNil(t, header) } type fakeConn struct{} diff --git a/jsonrpc/websocket.go b/jsonrpc/websocket.go index 80fda596a8..b3e436703a 100644 --- a/jsonrpc/websocket.go +++ b/jsonrpc/websocket.go @@ -8,7 +8,7 @@ import ( "time" "github.com/NethermindEth/juno/utils" - "nhooyr.io/websocket" + "github.com/coder/websocket" ) const closeReasonMaxBytes = 125 @@ -128,7 +128,7 @@ func (wsc *websocketConn) Read(p []byte) (int, error) { // Write returns the number of bytes of p sent, not including the header. func (wsc *websocketConn) Write(p []byte) (int, error) { - // TODO write responses concurrently. Unlike gorilla/websocket, nhooyr.io/websocket + // TODO write responses concurrently. Unlike gorilla/websocket, github.com/coder/websocket // permits concurrent writes. writeCtx, writeCancel := context.WithTimeout(wsc.ctx, wsc.params.WriteDuration) diff --git a/jsonrpc/websocket_test.go b/jsonrpc/websocket_test.go index c1a95a3e1d..9baf704ae9 100644 --- a/jsonrpc/websocket_test.go +++ b/jsonrpc/websocket_test.go @@ -8,10 +8,10 @@ import ( "github.com/NethermindEth/juno/jsonrpc" "github.com/NethermindEth/juno/utils" + "github.com/coder/websocket" "github.com/sourcegraph/conc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "nhooyr.io/websocket" ) // The caller is responsible for closing the connection. diff --git a/l1/eth_subscriber.go b/l1/eth_subscriber.go index 38e7d377db..6ddb213b1e 100644 --- a/l1/eth_subscriber.go +++ b/l1/eth_subscriber.go @@ -20,6 +20,7 @@ type EthSubscriber struct { ethClient *ethclient.Client client *rpc.Client filterer *contract.StarknetFilterer + listener EventListener } var _ Subscriber = (*EthSubscriber)(nil) @@ -42,6 +43,7 @@ func NewEthSubscriber(ethClientAddress string, coreContractAddress common.Addres ethClient: ethClient, client: client, filterer: filterer, + listener: SelectiveListener{}, }, nil } @@ -50,14 +52,25 @@ func (s *EthSubscriber) WatchLogStateUpdate(ctx context.Context, sink chan<- *co } func (s *EthSubscriber) ChainID(ctx context.Context) (*big.Int, error) { - return s.ethClient.ChainID(ctx) + reqTimer := time.Now() + chainID, err := s.ethClient.ChainID(ctx) + if err != nil { + return nil, fmt.Errorf("get chain ID: %w", err) + } + s.listener.OnL1Call("eth_chainId", time.Since(reqTimer)) + + return chainID, nil } func (s *EthSubscriber) FinalisedHeight(ctx context.Context) (uint64, error) { + const method = "eth_getBlockByNumber" + reqTimer := time.Now() + var raw json.RawMessage - if err := s.client.CallContext(ctx, &raw, "eth_getBlockByNumber", "finalized", false); err != nil { //nolint:misspell + if err := s.client.CallContext(ctx, &raw, method, "finalized", false); err != nil { //nolint:misspell return 0, fmt.Errorf("get finalised Ethereum block: %w", err) } + s.listener.OnL1Call(method, time.Since(reqTimer)) var head *types.Header if err := json.Unmarshal(raw, &head); err != nil { diff --git a/l1/event_listener.go b/l1/event_listener.go index f5e9a10a32..077fde4cb1 100644 --- a/l1/event_listener.go +++ b/l1/event_listener.go @@ -1,15 +1,19 @@ package l1 import ( + "time" + "github.com/NethermindEth/juno/core" ) type EventListener interface { OnNewL1Head(head *core.L1Head) + OnL1Call(method string, took time.Duration) } type SelectiveListener struct { OnNewL1HeadCb func(head *core.L1Head) + OnL1CallCb func(method string, took time.Duration) } func (l SelectiveListener) OnNewL1Head(head *core.L1Head) { @@ -17,3 +21,9 @@ func (l SelectiveListener) OnNewL1Head(head *core.L1Head) { l.OnNewL1HeadCb(head) } } + +func (l SelectiveListener) OnL1Call(method string, took time.Duration) { + if l.OnL1CallCb != nil { + l.OnL1CallCb(method, took) + } +} diff --git a/migration/migration.go b/migration/migration.go index 3e39c1831f..f3a8dd2a72 100644 --- a/migration/migration.go +++ b/migration/migration.go @@ -7,6 +7,7 @@ import ( "encoding/json" "errors" "fmt" + "maps" "runtime" "sync" @@ -598,9 +599,7 @@ func changeStateDiffStruct(txn db.Transaction, key, value []byte, _ *utils.Netwo } nonces := make(map[felt.Felt]*felt.Felt, len(old.StateDiff.Nonces)) - for addr, nonce := range old.StateDiff.Nonces { - nonces[addr] = nonce - } + maps.Copy(nonces, old.StateDiff.Nonces) deployedContracts := make(map[felt.Felt]*felt.Felt, len(old.StateDiff.DeployedContracts)) for _, deployedContract := range old.StateDiff.DeployedContracts { diff --git a/mocks/mock_plugin.go b/mocks/mock_plugin.go new file mode 100644 index 0000000000..7c1d4a4391 --- /dev/null +++ b/mocks/mock_plugin.go @@ -0,0 +1,98 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/NethermindEth/juno/plugin (interfaces: JunoPlugin) +// +// Generated by this command: +// +// mockgen -destination=../mocks/mock_plugin.go -package=mocks github.com/NethermindEth/juno/plugin JunoPlugin +// + +// Package mocks is a generated GoMock package. +package mocks + +import ( + reflect "reflect" + + core "github.com/NethermindEth/juno/core" + felt "github.com/NethermindEth/juno/core/felt" + junoplugin "github.com/NethermindEth/juno/plugin" + gomock "go.uber.org/mock/gomock" +) + +// MockJunoPlugin is a mock of JunoPlugin interface. +type MockJunoPlugin struct { + ctrl *gomock.Controller + recorder *MockJunoPluginMockRecorder +} + +// MockJunoPluginMockRecorder is the mock recorder for MockJunoPlugin. +type MockJunoPluginMockRecorder struct { + mock *MockJunoPlugin +} + +// NewMockJunoPlugin creates a new mock instance. +func NewMockJunoPlugin(ctrl *gomock.Controller) *MockJunoPlugin { + mock := &MockJunoPlugin{ctrl: ctrl} + mock.recorder = &MockJunoPluginMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockJunoPlugin) EXPECT() *MockJunoPluginMockRecorder { + return m.recorder +} + +// Init mocks base method. +func (m *MockJunoPlugin) Init() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Init") + ret0, _ := ret[0].(error) + return ret0 +} + +// Init indicates an expected call of Init. +func (mr *MockJunoPluginMockRecorder) Init() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockJunoPlugin)(nil).Init)) +} + +// NewBlock mocks base method. +func (m *MockJunoPlugin) NewBlock(arg0 *core.Block, arg1 *core.StateUpdate, arg2 map[felt.Felt]core.Class) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewBlock", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// NewBlock indicates an expected call of NewBlock. +func (mr *MockJunoPluginMockRecorder) NewBlock(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewBlock", reflect.TypeOf((*MockJunoPlugin)(nil).NewBlock), arg0, arg1, arg2) +} + +// RevertBlock mocks base method. +func (m *MockJunoPlugin) RevertBlock(arg0, arg1 *junoplugin.BlockAndStateUpdate, arg2 *core.StateDiff) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RevertBlock", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// RevertBlock indicates an expected call of RevertBlock. +func (mr *MockJunoPluginMockRecorder) RevertBlock(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertBlock", reflect.TypeOf((*MockJunoPlugin)(nil).RevertBlock), arg0, arg1, arg2) +} + +// Shutdown mocks base method. +func (m *MockJunoPlugin) Shutdown() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Shutdown") + ret0, _ := ret[0].(error) + return ret0 +} + +// Shutdown indicates an expected call of Shutdown. +func (mr *MockJunoPluginMockRecorder) Shutdown() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Shutdown", reflect.TypeOf((*MockJunoPlugin)(nil).Shutdown)) +} diff --git a/mocks/mock_vm.go b/mocks/mock_vm.go index 134c8bb952..fce753bd37 100644 --- a/mocks/mock_vm.go +++ b/mocks/mock_vm.go @@ -43,33 +43,34 @@ func (m *MockVM) EXPECT() *MockVMMockRecorder { } // Call mocks base method. -func (m *MockVM) Call(arg0 *vm.CallInfo, arg1 *vm.BlockInfo, arg2 core.StateReader, arg3 *utils.Network, arg4 uint64, arg5 bool) ([]*felt.Felt, error) { +func (m *MockVM) Call(arg0 *vm.CallInfo, arg1 *vm.BlockInfo, arg2 core.StateReader, arg3 *utils.Network, arg4 uint64) ([]*felt.Felt, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Call", arg0, arg1, arg2, arg3, arg4, arg5) + ret := m.ctrl.Call(m, "Call", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].([]*felt.Felt) ret1, _ := ret[1].(error) return ret0, ret1 } // Call indicates an expected call of Call. -func (mr *MockVMMockRecorder) Call(arg0, arg1, arg2, arg3, arg4, arg5 any) *gomock.Call { +func (mr *MockVMMockRecorder) Call(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Call", reflect.TypeOf((*MockVM)(nil).Call), arg0, arg1, arg2, arg3, arg4, arg5) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Call", reflect.TypeOf((*MockVM)(nil).Call), arg0, arg1, arg2, arg3, arg4) } // Execute mocks base method. -func (m *MockVM) Execute(arg0 []core.Transaction, arg1 []core.Class, arg2 []*felt.Felt, arg3 *vm.BlockInfo, arg4 core.StateReader, arg5 *utils.Network, arg6, arg7, arg8, arg9 bool) ([]*felt.Felt, []*felt.Felt, []vm.TransactionTrace, error) { +func (m *MockVM) Execute(arg0 []core.Transaction, arg1 []core.Class, arg2 []*felt.Felt, arg3 *vm.BlockInfo, arg4 core.StateReader, arg5 *utils.Network, arg6, arg7, arg8 bool) ([]*felt.Felt, []core.GasConsumed, []vm.TransactionTrace, uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Execute", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) + ret := m.ctrl.Call(m, "Execute", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) ret0, _ := ret[0].([]*felt.Felt) - ret1, _ := ret[1].([]*felt.Felt) + ret1, _ := ret[1].([]core.GasConsumed) ret2, _ := ret[2].([]vm.TransactionTrace) - ret3, _ := ret[3].(error) - return ret0, ret1, ret2, ret3 + ret3, _ := ret[3].(uint64) + ret4, _ := ret[4].(error) + return ret0, ret1, ret2, ret3, ret4 } // Execute indicates an expected call of Execute. -func (mr *MockVMMockRecorder) Execute(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 any) *gomock.Call { +func (mr *MockVMMockRecorder) Execute(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Execute", reflect.TypeOf((*MockVM)(nil).Execute), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Execute", reflect.TypeOf((*MockVM)(nil).Execute), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) } diff --git a/node/http.go b/node/http.go index 84f3d99c48..4226564b0a 100644 --- a/node/http.go +++ b/node/http.go @@ -11,11 +11,13 @@ import ( "strings" "time" + "github.com/NethermindEth/juno/blockchain" "github.com/NethermindEth/juno/db" junogrpc "github.com/NethermindEth/juno/grpc" "github.com/NethermindEth/juno/grpc/gen" "github.com/NethermindEth/juno/jsonrpc" "github.com/NethermindEth/juno/service" + "github.com/NethermindEth/juno/sync" "github.com/NethermindEth/juno/utils" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -72,7 +74,7 @@ func exactPathServer(path string, handler http.Handler) http.HandlerFunc { } func makeRPCOverHTTP(host string, port uint16, servers map[string]*jsonrpc.Server, - log utils.SimpleLogger, metricsEnabled bool, corsEnabled bool, + httpHandlers map[string]http.HandlerFunc, log utils.SimpleLogger, metricsEnabled bool, corsEnabled bool, ) *httpService { var listener jsonrpc.NewRequestListener if metricsEnabled { @@ -87,6 +89,9 @@ func makeRPCOverHTTP(host string, port uint16, servers map[string]*jsonrpc.Serve } mux.Handle(path, exactPathServer(path, httpHandler)) } + for path, handler := range httpHandlers { + mux.HandleFunc(path, handler) + } var handler http.Handler = mux if corsEnabled { @@ -110,6 +115,7 @@ func makeRPCOverWebsocket(host string, port uint16, servers map[string]*jsonrpc. wsHandler = wsHandler.WithListener(listener) } mux.Handle(path, exactPathServer(path, wsHandler)) + wsPrefixedPath := strings.TrimSuffix("/ws"+path, "/") mux.Handle(wsPrefixedPath, exactPathServer(wsPrefixedPath, wsHandler)) } @@ -179,3 +185,43 @@ func makePPROF(host string, port uint16) *httpService { mux.HandleFunc("/debug/pprof/trace", pprof.Trace) return makeHTTPService(host, port, mux) } + +const SyncBlockRange = 6 + +type readinessHandlers struct { + bcReader blockchain.Reader + syncReader sync.Reader +} + +func NewReadinessHandlers(bcReader blockchain.Reader, syncReader sync.Reader) *readinessHandlers { + return &readinessHandlers{ + bcReader: bcReader, + syncReader: syncReader, + } +} + +func (h *readinessHandlers) HandleReadySync(w http.ResponseWriter, r *http.Request) { + if !h.isSynced() { + w.WriteHeader(http.StatusServiceUnavailable) + return + } + + w.WriteHeader(http.StatusOK) +} + +func (h *readinessHandlers) isSynced() bool { + head, err := h.bcReader.HeadsHeader() + if err != nil { + return false + } + highestBlockHeader := h.syncReader.HighestBlockHeader() + if highestBlockHeader == nil { + return false + } + + if head.Number > highestBlockHeader.Number { + return false + } + + return head.Number+SyncBlockRange >= highestBlockHeader.Number +} diff --git a/node/http_test.go b/node/http_test.go new file mode 100644 index 0000000000..8c6795a0c8 --- /dev/null +++ b/node/http_test.go @@ -0,0 +1,75 @@ +package node_test + +import ( + "context" + "net/http" + "net/http/httptest" + "testing" + + "github.com/NethermindEth/juno/core" + "github.com/NethermindEth/juno/core/felt" + "github.com/NethermindEth/juno/mocks" + "github.com/NethermindEth/juno/node" + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" +) + +func TestHandleReadySync(t *testing.T) { + mockCtrl := gomock.NewController(t) + t.Cleanup(mockCtrl.Finish) + + synchronizer := mocks.NewMockSyncReader(mockCtrl) + mockReader := mocks.NewMockReader(mockCtrl) + readinessHandlers := node.NewReadinessHandlers(mockReader, synchronizer) + ctx := context.Background() + + t.Run("ready and blockNumber outside blockRange to highestBlock", func(t *testing.T) { + blockNum := uint64(2) + highestBlock := blockNum + node.SyncBlockRange + 1 + mockReader.EXPECT().HeadsHeader().Return(&core.Header{Number: blockNum}, nil) + synchronizer.EXPECT().HighestBlockHeader().Return(&core.Header{Number: highestBlock, Hash: new(felt.Felt).SetUint64(highestBlock)}) + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, "/ready/sync", http.NoBody) + assert.Nil(t, err) + + rr := httptest.NewRecorder() + + readinessHandlers.HandleReadySync(rr, req) + + assert.Equal(t, http.StatusServiceUnavailable, rr.Code) + }) + + t.Run("ready & blockNumber is larger than highestBlock", func(t *testing.T) { + blockNum := uint64(2) + highestBlock := uint64(1) + + mockReader.EXPECT().HeadsHeader().Return(&core.Header{Number: blockNum}, nil) + synchronizer.EXPECT().HighestBlockHeader().Return(&core.Header{Number: highestBlock, Hash: new(felt.Felt).SetUint64(highestBlock)}) + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, "/ready/sync", http.NoBody) + assert.Nil(t, err) + + rr := httptest.NewRecorder() + + readinessHandlers.HandleReadySync(rr, req) + + assert.Equal(t, http.StatusServiceUnavailable, rr.Code) + }) + + t.Run("ready & blockNumber is in blockRange of highestBlock", func(t *testing.T) { + blockNum := uint64(3) + highestBlock := blockNum + node.SyncBlockRange + + mockReader.EXPECT().HeadsHeader().Return(&core.Header{Number: blockNum}, nil) + synchronizer.EXPECT().HighestBlockHeader().Return(&core.Header{Number: highestBlock, Hash: new(felt.Felt).SetUint64(highestBlock)}) + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, "/ready/sync", http.NoBody) + assert.Nil(t, err) + + rr := httptest.NewRecorder() + + readinessHandlers.HandleReadySync(rr, req) + + assert.Equal(t, http.StatusOK, rr.Code) + }) +} diff --git a/node/metrics.go b/node/metrics.go index a10ae75a3b..9ac489b5fe 100644 --- a/node/metrics.go +++ b/node/metrics.go @@ -226,11 +226,20 @@ func makeL1Metrics() l1.EventListener { Name: "height", }) prometheus.MustRegister(l1Height) + requestLatencies := prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: "l1", + Subsystem: "client", + Name: "request_latency", + }, []string{"method"}) + prometheus.MustRegister(requestLatencies) return l1.SelectiveListener{ OnNewL1HeadCb: func(head *core.L1Head) { l1Height.Set(float64(head.BlockNumber)) }, + OnL1CallCb: func(method string, took time.Duration) { + requestLatencies.WithLabelValues(method).Observe(took.Seconds()) + }, } } diff --git a/node/node.go b/node/node.go index a770c01f79..fd30973832 100644 --- a/node/node.go +++ b/node/node.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "net/http" "net/url" "os" "reflect" @@ -22,6 +23,7 @@ import ( "github.com/NethermindEth/juno/l1" "github.com/NethermindEth/juno/migration" "github.com/NethermindEth/juno/p2p" + "github.com/NethermindEth/juno/plugin" "github.com/NethermindEth/juno/rpc" "github.com/NethermindEth/juno/service" adaptfeeder "github.com/NethermindEth/juno/starknetdata/feeder" @@ -89,6 +91,8 @@ type Config struct { GatewayAPIKey string `mapstructure:"gw-api-key"` GatewayTimeout time.Duration `mapstructure:"gw-timeout"` + + PluginPath string `mapstructure:"plugin-path"` } type Node struct { @@ -160,6 +164,15 @@ func New(cfg *Config, version string) (*Node, error) { //nolint:gocyclo,funlen synchronizer := sync.New(chain, adaptfeeder.New(client), log, cfg.PendingPollInterval, dbIsRemote) gatewayClient := gateway.NewClient(cfg.Network.GatewayURL, log).WithUserAgent(ua).WithAPIKey(cfg.GatewayAPIKey) + if cfg.PluginPath != "" { + p, err := plugin.Load(cfg.PluginPath) + if err != nil { + return nil, err + } + synchronizer.WithPlugin(p) + services = append(services, plugin.NewService(p)) + } + var p2pService *p2p.Service if cfg.P2P { if cfg.Network != utils.Sepolia { @@ -205,7 +218,7 @@ func New(cfg *Config, version string) (*Node, error) { //nolint:gocyclo,funlen return nil, err } jsonrpcServerLegacy := jsonrpc.NewServer(maxGoroutines, log).WithValidator(validator.Validator()) - legacyMethods, legacyPath := rpcHandler.MethodsV0_6() + legacyMethods, legacyPath := rpcHandler.MethodsV0_7() if err = jsonrpcServerLegacy.RegisterMethods(legacyMethods...); err != nil { return nil, err } @@ -218,10 +231,15 @@ func New(cfg *Config, version string) (*Node, error) { //nolint:gocyclo,funlen "/rpc" + legacyPath: jsonrpcServerLegacy, } if cfg.HTTP { - services = append(services, makeRPCOverHTTP(cfg.HTTPHost, cfg.HTTPPort, rpcServers, log, cfg.Metrics, cfg.RPCCorsEnable)) + readinessHandlers := NewReadinessHandlers(chain, synchronizer) + httpHandlers := map[string]http.HandlerFunc{ + "/ready/sync": readinessHandlers.HandleReadySync, + } + services = append(services, makeRPCOverHTTP(cfg.HTTPHost, cfg.HTTPPort, rpcServers, httpHandlers, log, cfg.Metrics, cfg.RPCCorsEnable)) } if cfg.Websocket { - services = append(services, makeRPCOverWebsocket(cfg.WebsocketHost, cfg.WebsocketPort, rpcServers, log, cfg.Metrics, cfg.RPCCorsEnable)) + services = append(services, + makeRPCOverWebsocket(cfg.WebsocketHost, cfg.WebsocketPort, rpcServers, log, cfg.Metrics, cfg.RPCCorsEnable)) } var metricsService service.Service if cfg.Metrics { @@ -243,6 +261,7 @@ func New(cfg *Config, version string) (*Node, error) { //nolint:gocyclo,funlen } else if p2pService != nil { // regular p2p node p2pService.WithListener(makeSyncMetrics(&sync.NoopSynchronizer{}, chain)) + p2pService.WithGossipTracer() } } if cfg.GRPC { @@ -293,9 +312,6 @@ func newL1Client(cfg *Config, chain *blockchain.Blockchain, log utils.SimpleLogg } network := chain.Network() - if err != nil { - return nil, fmt.Errorf("find core contract address for network %s: %w", network.String(), err) - } var ethSubscriber *l1.EthSubscriber ethSubscriber, err = l1.NewEthSubscriber(cfg.EthNode, network.CoreContractAddress) @@ -303,10 +319,7 @@ func newL1Client(cfg *Config, chain *blockchain.Blockchain, log utils.SimpleLogg return nil, fmt.Errorf("set up ethSubscriber: %w", err) } - l1Client, err := l1.NewClient(ethSubscriber, chain, log), nil - if err != nil { - return nil, fmt.Errorf("set up l1 client: %w", err) - } + l1Client := l1.NewClient(ethSubscriber, chain, log) if cfg.Metrics { l1Client.WithEventListener(makeL1Metrics()) @@ -361,7 +374,6 @@ func (n *Node) Run(ctx context.Context) { } for _, s := range n.services { - s := s wg.Go(func() { // Immediately acknowledge panicing services by shutting down the node // Without the deffered cancel(), we would have to wait for user to hit Ctrl+C diff --git a/node/throttled_vm.go b/node/throttled_vm.go index 7151867c00..f50c66be1c 100644 --- a/node/throttled_vm.go +++ b/node/throttled_vm.go @@ -20,27 +20,27 @@ func NewThrottledVM(res vm.VM, concurrenyBudget uint, maxQueueLen int32) *Thrott } func (tvm *ThrottledVM) Call(callInfo *vm.CallInfo, blockInfo *vm.BlockInfo, state core.StateReader, - network *utils.Network, maxSteps uint64, useBlobData bool, + network *utils.Network, maxSteps uint64, ) ([]*felt.Felt, error) { var ret []*felt.Felt return ret, tvm.Do(func(vm *vm.VM) error { var err error - ret, err = (*vm).Call(callInfo, blockInfo, state, network, maxSteps, useBlobData) + ret, err = (*vm).Call(callInfo, blockInfo, state, network, maxSteps) return err }) } func (tvm *ThrottledVM) Execute(txns []core.Transaction, declaredClasses []core.Class, paidFeesOnL1 []*felt.Felt, - blockInfo *vm.BlockInfo, state core.StateReader, network *utils.Network, skipChargeFee, skipValidate, errOnRevert, - useBlobData bool, -) ([]*felt.Felt, []*felt.Felt, []vm.TransactionTrace, error) { + blockInfo *vm.BlockInfo, state core.StateReader, network *utils.Network, skipChargeFee, skipValidate, errOnRevert bool, +) ([]*felt.Felt, []core.GasConsumed, []vm.TransactionTrace, uint64, error) { var ret []*felt.Felt var traces []vm.TransactionTrace - var dataGasConsumed []*felt.Felt - return ret, dataGasConsumed, traces, tvm.Do(func(vm *vm.VM) error { + var daGas []core.GasConsumed + var numSteps uint64 + return ret, daGas, traces, numSteps, tvm.Do(func(vm *vm.VM) error { var err error - ret, dataGasConsumed, traces, err = (*vm).Execute(txns, declaredClasses, paidFeesOnL1, blockInfo, state, network, - skipChargeFee, skipValidate, errOnRevert, useBlobData) + ret, daGas, traces, numSteps, err = (*vm).Execute(txns, declaredClasses, paidFeesOnL1, blockInfo, state, network, + skipChargeFee, skipValidate, errOnRevert) return err }) } diff --git a/p2p/gossip_tracer.go b/p2p/gossip_tracer.go new file mode 100644 index 0000000000..da07eabfc2 --- /dev/null +++ b/p2p/gossip_tracer.go @@ -0,0 +1,218 @@ +package p2p + +import ( + "strings" + + "github.com/libp2p/go-libp2p-pubsub" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/protocol" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +var ( + _ pubsub.RawTracer = (*gossipTracer)(nil) + knownAgentVersions = []string{"juno", "papyrus", "pathfinder", "madara"} +) + +// Metrics collection for gossipsub +type gossipTracer struct { + host host.Host + + p2PPeerCount *prometheus.GaugeVec + psMsgDeliver *prometheus.CounterVec + psMsgUndeliverable *prometheus.CounterVec + psMsgValidate *prometheus.CounterVec + psMsgDuplicate *prometheus.CounterVec + psMsgReject *prometheus.CounterVec + psTopicsActive *prometheus.GaugeVec + psTopicsPrune *prometheus.CounterVec + psTopicsGraft *prometheus.CounterVec + psThrottlePeer *prometheus.CounterVec + psRPCRecv *prometheus.CounterVec + psRPCSubRecv prometheus.Counter + psRPCPubRecv *prometheus.CounterVec + psRPCDrop *prometheus.CounterVec + psRPCSubDrop prometheus.Counter + psRPCPubDrop *prometheus.CounterVec + psRPCSent *prometheus.CounterVec + psRPCSubSent prometheus.Counter + psRPCPubSent *prometheus.CounterVec +} + +func NewGossipTracer(h host.Host) *gossipTracer { + return &gossipTracer{ + host: h, + p2PPeerCount: promauto.NewGaugeVec(prometheus.GaugeOpts{ + Name: "p2p_peer_count", + Help: "The number of connected libp2p peers by agent string", + }, []string{"agent"}), + psMsgDeliver: promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "p2p_pubsub_deliver_total", + Help: "The number of messages received for delivery", + }, []string{"topic"}), + psMsgUndeliverable: promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "p2p_pubsub_undeliverable_total", + Help: "The number of messages received which weren't able to be delivered", + }, []string{"topic"}), + psMsgValidate: promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "p2p_pubsub_validate_total", + Help: "The number of messages received for validation", + }, []string{"topic"}), + psMsgDuplicate: promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "p2p_pubsub_duplicate_total", + Help: "The number of duplicate messages sent", + }, []string{"topic"}), + psMsgReject: promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "p2p_pubsub_reject_total", + Help: "The number of messages rejected", + }, []string{"topic", "reason"}), + psTopicsActive: promauto.NewGaugeVec(prometheus.GaugeOpts{ + Name: "p2p_pubsub_topic_active", + Help: "The topics that the peer is participating in gossipsub", + }, []string{"topic"}), + psTopicsPrune: promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "p2p_pubsub_prune_total", + Help: "The number of prune messages sent by the peer", + }, []string{"topic"}), + psTopicsGraft: promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "p2p_pubsub_graft_total", + Help: "The number of graft messages sent by the peer", + }, []string{"topic"}), + psThrottlePeer: promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "p2p_pubsub_throttle_total", + Help: "The number of times the peer has been throttled", + }, []string{"topic"}), + psRPCRecv: promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "p2p_pubsub_rpc_recv_total", + Help: "The number of messages received via rpc for a particular control message", + }, []string{"control_message"}), + psRPCSubRecv: promauto.NewCounter(prometheus.CounterOpts{ + Name: "p2p_pubsub_rpc_recv_sub_total", + Help: "The number of subscription messages received via rpc", + }), + psRPCPubRecv: promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "p2p_pubsub_rpc_recv_pub_total", + Help: "The number of publish messages received via rpc", + }, []string{"topic"}), + psRPCDrop: promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "p2p_pubsub_rpc_drop_total", + Help: "The number of messages dropped via rpc for a particular control message", + }, []string{"control_message"}), + psRPCSubDrop: promauto.NewCounter(prometheus.CounterOpts{ + Name: "p2p_pubsub_rpc_drop_sub_total", + Help: "The number of subscription messages dropped via rpc", + }), + psRPCPubDrop: promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "p2p_pubsub_rpc_drop_pub_total", + Help: "The number of publish messages dropped via rpc", + }, []string{"topic"}), + psRPCSent: promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "p2p_pubsub_rpc_sent_total", + Help: "The number of messages sent via rpc for a particular control message", + }, []string{"control_message"}), + psRPCSubSent: promauto.NewCounter(prometheus.CounterOpts{ + Name: "p2p_pubsub_rpc_sent_sub_total", + Help: "The number of subscription messages sent via rpc", + }), + psRPCPubSent: promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "p2p_pubsub_rpc_sent_pub_total", + Help: "The number of publish messages sent via rpc", + }, []string{"topic"}), + } +} + +func (g *gossipTracer) AddPeer(p peer.ID, proto protocol.ID) { + g.p2PPeerCount.WithLabelValues(agentNameFromPeerID(p, g.host.Peerstore())).Inc() +} + +func (g *gossipTracer) RemovePeer(p peer.ID) { + g.p2PPeerCount.WithLabelValues(agentNameFromPeerID(p, g.host.Peerstore())).Dec() +} + +func (g *gossipTracer) Join(topic string) { + g.psTopicsActive.WithLabelValues(topic).Set(1) +} + +func (g *gossipTracer) Leave(topic string) { + g.psTopicsActive.WithLabelValues(topic).Set(0) +} + +func (g *gossipTracer) Graft(p peer.ID, topic string) { + g.psTopicsGraft.WithLabelValues(topic).Inc() +} + +func (g *gossipTracer) Prune(p peer.ID, topic string) { + g.psTopicsPrune.WithLabelValues(topic).Inc() +} + +func (g *gossipTracer) DeliverMessage(msg *pubsub.Message) { + g.psMsgDeliver.WithLabelValues(*msg.Topic).Inc() +} + +func (g *gossipTracer) ValidateMessage(msg *pubsub.Message) { + g.psMsgValidate.WithLabelValues(*msg.Topic).Inc() +} + +func (g *gossipTracer) RejectMessage(msg *pubsub.Message, reason string) { + g.psMsgReject.WithLabelValues(*msg.Topic, reason).Inc() +} + +func (g *gossipTracer) DuplicateMessage(msg *pubsub.Message) { + g.psMsgDuplicate.WithLabelValues(*msg.Topic).Inc() +} + +func (g *gossipTracer) UndeliverableMessage(msg *pubsub.Message) { + g.psMsgUndeliverable.WithLabelValues(*msg.Topic).Inc() +} + +func (g *gossipTracer) ThrottlePeer(p peer.ID) { + g.psThrottlePeer.WithLabelValues(agentNameFromPeerID(p, g.host.Peerstore())).Inc() +} + +func (g *gossipTracer) RecvRPC(rpc *pubsub.RPC) { + g.setRPCMetrics(g.psRPCSubRecv, g.psRPCPubRecv, g.psRPCRecv, rpc) +} + +func (g *gossipTracer) SendRPC(rpc *pubsub.RPC, p peer.ID) { + g.setRPCMetrics(g.psRPCSubSent, g.psRPCPubSent, g.psRPCSent, rpc) +} + +func (g *gossipTracer) DropRPC(rpc *pubsub.RPC, p peer.ID) { + g.setRPCMetrics(g.psRPCSubDrop, g.psRPCPubDrop, g.psRPCDrop, rpc) +} + +func (g *gossipTracer) setRPCMetrics(subCtr prometheus.Counter, pubCtr, ctrlCtr *prometheus.CounterVec, rpc *pubsub.RPC) { + subCtr.Add(float64(len(rpc.Subscriptions))) + if rpc.Control != nil { + ctrlCtr.WithLabelValues("ihave").Add(float64(len(rpc.Control.Ihave))) + ctrlCtr.WithLabelValues("iwant").Add(float64(len(rpc.Control.Iwant))) + ctrlCtr.WithLabelValues("graft").Add(float64(len(rpc.Control.Graft))) + ctrlCtr.WithLabelValues("prune").Add(float64(len(rpc.Control.Prune))) + ctrlCtr.WithLabelValues("idontwant").Add(float64(len(rpc.Control.Idontwant))) + } + + for _, msg := range rpc.Publish { + pubCtr.WithLabelValues(*msg.Topic).Inc() + } +} + +func agentNameFromPeerID(pid peer.ID, store peerstore.PeerMetadata) string { + const unknownAgent = "unknown" + + rawAgent, err := store.Get(pid, "AgentVersion") + agent, ok := rawAgent.(string) + if err != nil || !ok { + return unknownAgent + } + + agent = strings.ToLower(agent) + for _, knownAgent := range knownAgentVersions { + if strings.Contains(agent, knownAgent) { + return knownAgent + } + } + return unknownAgent +} diff --git a/p2p/metrics.go b/p2p/metrics.go deleted file mode 100644 index 4e0b6b3102..0000000000 --- a/p2p/metrics.go +++ /dev/null @@ -1,18 +0,0 @@ -package p2p - -import ( - "github.com/libp2p/go-libp2p/core/peerstore" - "github.com/prometheus/client_golang/prometheus" -) - -func runMetrics(store peerstore.Peerstore) { - numberOfPeersGauge := prometheus.NewGaugeFunc(prometheus.GaugeOpts{ - Namespace: "p2p", - Name: "number_of_peers", - }, func() float64 { - peersLen := store.Peers().Len() - return float64(peersLen) - }) - - prometheus.MustRegister(numberOfPeersGauge) -} diff --git a/p2p/p2p.go b/p2p/p2p.go index 79a7d17577..c5dfca89ad 100644 --- a/p2p/p2p.go +++ b/p2p/p2p.go @@ -48,7 +48,11 @@ type Service struct { topics map[string]*pubsub.Topic topicsLock sync.RWMutex - downloader *Downloader + downloader *Downloader + synchroniser *SyncService + gossipTracer *gossipTracer + + feederNode bool database db.DB } @@ -163,7 +167,7 @@ func NewWithHost(p2phost host.Host, peers string, feederNode bool, syncMode Sync func makeDHT(p2phost host.Host, addrInfos []peer.AddrInfo) (*dht.IpfsDHT, error) { return dht.New(context.Background(), p2phost, - dht.ProtocolPrefix(starknet.KadPrefix()), + dht.ProtocolPrefix(starknet.Prefix), dht.BootstrapPeers(addrInfos...), dht.RoutingTableRefreshPeriod(routingTableRefreshPeriod), dht.Mode(dht.ModeServer), @@ -231,14 +235,23 @@ func (s *Service) SubscribePeerConnectednessChanged(ctx context.Context) (<-chan // Run starts the p2p service. Calling any other function before run is undefined behaviour func (s *Service) Run(ctx context.Context) error { - defer s.host.Close() + defer func() { + if err := s.host.Close(); err != nil { + s.log.Warnw("Failed to close host", "err", err) + } + }() err := s.dht.Bootstrap(ctx) if err != nil { return err } - s.pubsub, err = pubsub.NewGossipSub(ctx, s.host) + var options []pubsub.Option + if s.gossipTracer != nil { + options = append(options, pubsub.WithRawTracer(s.gossipTracer)) + } + + s.pubsub, err = pubsub.NewGossipSub(ctx, s.host, options...) if err != nil { return err } @@ -265,7 +278,7 @@ func (s *Service) Run(ctx context.Context) error { if err := s.dht.Close(); err != nil { s.log.Warnw("Failed stopping DHT", "err", err.Error()) } - return s.host.Close() + return nil } func (s *Service) setProtocolHandlers() { @@ -396,8 +409,11 @@ func (s *Service) SetProtocolHandler(pid protocol.ID, handler func(network.Strea } func (s *Service) WithListener(l junoSync.EventListener) { - runMetrics(s.host.Peerstore()) - s.downloader.WithListener(l) + s.synchroniser.WithListener(l) +} + +func (s *Service) WithGossipTracer() { + s.gossipTracer = NewGossipTracer(s.host) } // persistPeers stores the given peers in the peers database @@ -408,7 +424,9 @@ func (s *Service) persistPeers() error { } store := s.host.Peerstore() - peers := store.Peers() + peers := utils.Filter(store.Peers(), func(peerID peer.ID) bool { + return peerID != s.host.ID() + }) for _, peerID := range peers { peerInfo := store.PeerInfo(peerID) diff --git a/p2p/snap_server.go b/p2p/snap_server.go index bb698fb68f..33612d04ef 100644 --- a/p2p/snap_server.go +++ b/p2p/snap_server.go @@ -1,6 +1,7 @@ package p2p import ( + "iter" "math/big" "github.com/NethermindEth/juno/utils" @@ -13,7 +14,6 @@ import ( "github.com/NethermindEth/juno/core/felt" "github.com/NethermindEth/juno/core/trie" "github.com/NethermindEth/juno/p2p/starknet/spec" - "github.com/NethermindEth/juno/utils/iter" "github.com/ethereum/go-ethereum/log" ) @@ -426,26 +426,24 @@ func Core2P2pProof(proofs []trie.ProofNode) *spec.PatriciaRangeProof { nodes := make([]*spec.PatriciaNode, len(proofs)) for i := range proofs { - if proofs[i].Binary != nil { - binary := proofs[i].Binary + switch node := proofs[i].(type) { + case *trie.Edge: + pathFelt := node.Path.Felt() nodes[i] = &spec.PatriciaNode{ - Node: &spec.PatriciaNode_Binary_{ - Binary: &spec.PatriciaNode_Binary{ - Left: core2p2p.AdaptFelt(binary.LeftHash), - Right: core2p2p.AdaptFelt(binary.RightHash), + Node: &spec.PatriciaNode_Edge_{ + Edge: &spec.PatriciaNode_Edge{ + Length: uint32(node.Path.Len()), + Path: core2p2p.AdaptFelt(&pathFelt), + Value: core2p2p.AdaptFelt(node.Child), }, }, } - } - if proofs[i].Edge != nil { - edge := proofs[i].Edge - pathfeld := edge.Path.Felt() + case *trie.Binary: nodes[i] = &spec.PatriciaNode{ - Node: &spec.PatriciaNode_Edge_{ - Edge: &spec.PatriciaNode_Edge{ - Length: uint32(edge.Path.Len()), - Path: core2p2p.AdaptFelt(&pathfeld), - Value: core2p2p.AdaptFelt(edge.Child), + Node: &spec.PatriciaNode_Binary_{ + Binary: &spec.PatriciaNode_Binary{ + Left: core2p2p.AdaptFelt(node.LeftHash), + Right: core2p2p.AdaptFelt(node.RightHash), }, }, } diff --git a/p2p/snap_syncer.go b/p2p/snap_syncer.go index 5494bca192..44231742a4 100644 --- a/p2p/snap_syncer.go +++ b/p2p/snap_syncer.go @@ -1230,21 +1230,17 @@ func P2pProofToTrieProofs(proof *spec.PatriciaRangeProof) []trie.ProofNode { for i, node := range proof.Nodes { if node.GetBinary() != nil { binary := node.GetBinary() - proofs[i] = trie.ProofNode{ - Binary: &trie.Binary{ - LeftHash: p2p2core.AdaptFelt(binary.Left), - RightHash: p2p2core.AdaptFelt(binary.Right), - }, + proofs[i] = &trie.Binary{ + LeftHash: p2p2core.AdaptFelt(binary.Left), + RightHash: p2p2core.AdaptFelt(binary.Right), } } else { edge := node.GetEdge() // TODO. What if edge is nil too? key := trie.NewKey(uint8(edge.Length), edge.Path.Elements) - proofs[i] = trie.ProofNode{ - Edge: &trie.Edge{ - Child: p2p2core.AdaptFelt(edge.Value), - Path: &key, - }, + proofs[i] = &trie.Edge{ + Child: p2p2core.AdaptFelt(edge.Value), + Path: &key, } } } diff --git a/p2p/starknet/client.go b/p2p/starknet/client.go index 9dcd4a1a5c..f4c113f5a7 100644 --- a/p2p/starknet/client.go +++ b/p2p/starknet/client.go @@ -4,11 +4,11 @@ import ( "context" "errors" "io" + "iter" "time" "github.com/NethermindEth/juno/p2p/starknet/spec" "github.com/NethermindEth/juno/utils" - "github.com/NethermindEth/juno/utils/iter" "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/protocol" "google.golang.org/protobuf/encoding/protodelim" @@ -16,9 +16,8 @@ import ( ) const ( - unmarshalMaxSize = 30 * utils.Megabyte - // TODO: allow a looot and tweak it later if needed, was 5 seconds before - readTimeout = 60 * time.Second + unmarshalMaxSize = 15 * utils.Megabyte + readTimeout = 10 * time.Second ) type NewStreamFunc func(ctx context.Context, pids ...protocol.ID) (network.Stream, error) diff --git a/p2p/starknet/handlers.go b/p2p/starknet/handlers.go index d785bc3645..d80de690d9 100644 --- a/p2p/starknet/handlers.go +++ b/p2p/starknet/handlers.go @@ -6,6 +6,7 @@ import ( "bytes" "context" "fmt" + "iter" "sync" "github.com/NethermindEth/juno/adapters/core2p2p" @@ -15,7 +16,6 @@ import ( "github.com/NethermindEth/juno/core/felt" "github.com/NethermindEth/juno/p2p/starknet/spec" "github.com/NethermindEth/juno/utils" - "github.com/NethermindEth/juno/utils/iter" "github.com/libp2p/go-libp2p/core/network" "google.golang.org/protobuf/encoding/protodelim" "google.golang.org/protobuf/proto" @@ -97,19 +97,17 @@ func streamHandler[ReqT proto.Message](ctx context.Context, wg *sync.WaitGroup, return } - // todo add write timeout - responseIterator(func(msg proto.Message) bool { + for msg := range responseIterator { if ctx.Err() != nil { - return false + break } + // todo add write timeout if _, err := protodelim.MarshalTo(stream, msg); err != nil { // todo: figure out if we need buffered io here log.Debugw("Error writing response", "peer", stream.ID(), "protocol", stream.Protocol(), "err", err) - return false + break } - - return true - }) + } } func (h *Handler) HeadersHandler(stream network.Stream) { @@ -189,7 +187,7 @@ func (h *Handler) onHeadersRequest(req *spec.BlockHeadersRequest) (iter.Seq[prot return &spec.BlockHeadersResponse{ HeaderMessage: &spec.BlockHeadersResponse_Header{ - Header: core2p2p.AdaptHeader(header, commitments, stateUpdate.StateDiff.Commitment(), + Header: core2p2p.AdaptHeader(header, commitments, stateUpdate.StateDiff.Hash(), stateUpdate.StateDiff.Length()), }, }, nil diff --git a/p2p/starknet/ids.go b/p2p/starknet/ids.go index dc1ab6fd5d..741ac436e8 100644 --- a/p2p/starknet/ids.go +++ b/p2p/starknet/ids.go @@ -6,10 +6,6 @@ import ( const Prefix = "/starknet" -func KadPrefix() protocol.ID { - return Prefix + "/kad" -} - func HeadersPID() protocol.ID { return Prefix + "/headers/0.1.0-rc.0" } diff --git a/p2p/starknet/p2p/proto/common.proto b/p2p/starknet/p2p/proto/common.proto index b1debc3bd2..3ee397e9b9 100644 --- a/p2p/starknet/p2p/proto/common.proto +++ b/p2p/starknet/p2p/proto/common.proto @@ -6,10 +6,17 @@ message Felt252 { bytes elements = 1; } +// A hash value representable as a Felt252 message Hash { bytes elements = 1; } +// A 256 bit hash value (like Keccak256) +message Hash256 { + // Required to be 32 bytes long + bytes elements = 1; +} + message Hashes { repeated Hash items = 1; } diff --git a/p2p/starknet/p2p/proto/receipt.proto b/p2p/starknet/p2p/proto/receipt.proto index 084ced5d65..9526f9fec7 100644 --- a/p2p/starknet/p2p/proto/receipt.proto +++ b/p2p/starknet/p2p/proto/receipt.proto @@ -57,7 +57,7 @@ message Receipt { message L1Handler { Common common = 1; - Hash msg_hash = 2; + Hash256 msg_hash = 2; } message Declare { diff --git a/p2p/starknet/snap_provider.go b/p2p/starknet/snap_provider.go index 8832a9f6ac..59ede0d192 100644 --- a/p2p/starknet/snap_provider.go +++ b/p2p/starknet/snap_provider.go @@ -1,8 +1,9 @@ package starknet import ( + "iter" + "github.com/NethermindEth/juno/p2p/starknet/spec" - "github.com/NethermindEth/juno/utils/iter" "google.golang.org/protobuf/proto" ) diff --git a/p2p/starknet/spec/common.pb.go b/p2p/starknet/spec/common.pb.go index b8c2fee32f..1b18c7c9c7 100644 --- a/p2p/starknet/spec/common.pb.go +++ b/p2p/starknet/spec/common.pb.go @@ -155,7 +155,7 @@ func (x Iteration_Direction) Number() protoreflect.EnumNumber { // Deprecated: Use Iteration_Direction.Descriptor instead. func (Iteration_Direction) EnumDescriptor() ([]byte, []int) { - return file_p2p_proto_common_proto_rawDescGZIP(), []int{10, 0} + return file_p2p_proto_common_proto_rawDescGZIP(), []int{11, 0} } type Felt252 struct { @@ -205,6 +205,7 @@ func (x *Felt252) GetElements() []byte { return nil } +// A hash value representable as a Felt252 type Hash struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -252,6 +253,55 @@ func (x *Hash) GetElements() []byte { return nil } +// A 256 bit hash value (like Keccak256) +type Hash256 struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required to be 32 bytes long + Elements []byte `protobuf:"bytes,1,opt,name=elements,proto3" json:"elements,omitempty"` +} + +func (x *Hash256) Reset() { + *x = Hash256{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_proto_common_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Hash256) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Hash256) ProtoMessage() {} + +func (x *Hash256) ProtoReflect() protoreflect.Message { + mi := &file_p2p_proto_common_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Hash256.ProtoReflect.Descriptor instead. +func (*Hash256) Descriptor() ([]byte, []int) { + return file_p2p_proto_common_proto_rawDescGZIP(), []int{2} +} + +func (x *Hash256) GetElements() []byte { + if x != nil { + return x.Elements + } + return nil +} + type Hashes struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -263,7 +313,7 @@ type Hashes struct { func (x *Hashes) Reset() { *x = Hashes{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_proto_common_proto_msgTypes[2] + mi := &file_p2p_proto_common_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -276,7 +326,7 @@ func (x *Hashes) String() string { func (*Hashes) ProtoMessage() {} func (x *Hashes) ProtoReflect() protoreflect.Message { - mi := &file_p2p_proto_common_proto_msgTypes[2] + mi := &file_p2p_proto_common_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -289,7 +339,7 @@ func (x *Hashes) ProtoReflect() protoreflect.Message { // Deprecated: Use Hashes.ProtoReflect.Descriptor instead. func (*Hashes) Descriptor() ([]byte, []int) { - return file_p2p_proto_common_proto_rawDescGZIP(), []int{2} + return file_p2p_proto_common_proto_rawDescGZIP(), []int{3} } func (x *Hashes) GetItems() []*Hash { @@ -310,7 +360,7 @@ type Address struct { func (x *Address) Reset() { *x = Address{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_proto_common_proto_msgTypes[3] + mi := &file_p2p_proto_common_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -323,7 +373,7 @@ func (x *Address) String() string { func (*Address) ProtoMessage() {} func (x *Address) ProtoReflect() protoreflect.Message { - mi := &file_p2p_proto_common_proto_msgTypes[3] + mi := &file_p2p_proto_common_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -336,7 +386,7 @@ func (x *Address) ProtoReflect() protoreflect.Message { // Deprecated: Use Address.ProtoReflect.Descriptor instead. func (*Address) Descriptor() ([]byte, []int) { - return file_p2p_proto_common_proto_rawDescGZIP(), []int{3} + return file_p2p_proto_common_proto_rawDescGZIP(), []int{4} } func (x *Address) GetElements() []byte { @@ -357,7 +407,7 @@ type PeerID struct { func (x *PeerID) Reset() { *x = PeerID{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_proto_common_proto_msgTypes[4] + mi := &file_p2p_proto_common_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -370,7 +420,7 @@ func (x *PeerID) String() string { func (*PeerID) ProtoMessage() {} func (x *PeerID) ProtoReflect() protoreflect.Message { - mi := &file_p2p_proto_common_proto_msgTypes[4] + mi := &file_p2p_proto_common_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -383,7 +433,7 @@ func (x *PeerID) ProtoReflect() protoreflect.Message { // Deprecated: Use PeerID.ProtoReflect.Descriptor instead. func (*PeerID) Descriptor() ([]byte, []int) { - return file_p2p_proto_common_proto_rawDescGZIP(), []int{4} + return file_p2p_proto_common_proto_rawDescGZIP(), []int{5} } func (x *PeerID) GetId() []byte { @@ -405,7 +455,7 @@ type Uint128 struct { func (x *Uint128) Reset() { *x = Uint128{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_proto_common_proto_msgTypes[5] + mi := &file_p2p_proto_common_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -418,7 +468,7 @@ func (x *Uint128) String() string { func (*Uint128) ProtoMessage() {} func (x *Uint128) ProtoReflect() protoreflect.Message { - mi := &file_p2p_proto_common_proto_msgTypes[5] + mi := &file_p2p_proto_common_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -431,7 +481,7 @@ func (x *Uint128) ProtoReflect() protoreflect.Message { // Deprecated: Use Uint128.ProtoReflect.Descriptor instead. func (*Uint128) Descriptor() ([]byte, []int) { - return file_p2p_proto_common_proto_rawDescGZIP(), []int{5} + return file_p2p_proto_common_proto_rawDescGZIP(), []int{6} } func (x *Uint128) GetLow() uint64 { @@ -460,7 +510,7 @@ type ConsensusSignature struct { func (x *ConsensusSignature) Reset() { *x = ConsensusSignature{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_proto_common_proto_msgTypes[6] + mi := &file_p2p_proto_common_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -473,7 +523,7 @@ func (x *ConsensusSignature) String() string { func (*ConsensusSignature) ProtoMessage() {} func (x *ConsensusSignature) ProtoReflect() protoreflect.Message { - mi := &file_p2p_proto_common_proto_msgTypes[6] + mi := &file_p2p_proto_common_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -486,7 +536,7 @@ func (x *ConsensusSignature) ProtoReflect() protoreflect.Message { // Deprecated: Use ConsensusSignature.ProtoReflect.Descriptor instead. func (*ConsensusSignature) Descriptor() ([]byte, []int) { - return file_p2p_proto_common_proto_rawDescGZIP(), []int{6} + return file_p2p_proto_common_proto_rawDescGZIP(), []int{7} } func (x *ConsensusSignature) GetR() *Felt252 { @@ -516,7 +566,7 @@ type Patricia struct { func (x *Patricia) Reset() { *x = Patricia{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_proto_common_proto_msgTypes[7] + mi := &file_p2p_proto_common_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -529,7 +579,7 @@ func (x *Patricia) String() string { func (*Patricia) ProtoMessage() {} func (x *Patricia) ProtoReflect() protoreflect.Message { - mi := &file_p2p_proto_common_proto_msgTypes[7] + mi := &file_p2p_proto_common_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -542,7 +592,7 @@ func (x *Patricia) ProtoReflect() protoreflect.Message { // Deprecated: Use Patricia.ProtoReflect.Descriptor instead. func (*Patricia) Descriptor() ([]byte, []int) { - return file_p2p_proto_common_proto_rawDescGZIP(), []int{7} + return file_p2p_proto_common_proto_rawDescGZIP(), []int{8} } func (x *Patricia) GetNLeaves() uint64 { @@ -571,7 +621,7 @@ type StateDiffCommitment struct { func (x *StateDiffCommitment) Reset() { *x = StateDiffCommitment{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_proto_common_proto_msgTypes[8] + mi := &file_p2p_proto_common_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -584,7 +634,7 @@ func (x *StateDiffCommitment) String() string { func (*StateDiffCommitment) ProtoMessage() {} func (x *StateDiffCommitment) ProtoReflect() protoreflect.Message { - mi := &file_p2p_proto_common_proto_msgTypes[8] + mi := &file_p2p_proto_common_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -597,7 +647,7 @@ func (x *StateDiffCommitment) ProtoReflect() protoreflect.Message { // Deprecated: Use StateDiffCommitment.ProtoReflect.Descriptor instead. func (*StateDiffCommitment) Descriptor() ([]byte, []int) { - return file_p2p_proto_common_proto_rawDescGZIP(), []int{8} + return file_p2p_proto_common_proto_rawDescGZIP(), []int{9} } func (x *StateDiffCommitment) GetStateDiffLength() uint64 { @@ -626,7 +676,7 @@ type BlockID struct { func (x *BlockID) Reset() { *x = BlockID{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_proto_common_proto_msgTypes[9] + mi := &file_p2p_proto_common_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -639,7 +689,7 @@ func (x *BlockID) String() string { func (*BlockID) ProtoMessage() {} func (x *BlockID) ProtoReflect() protoreflect.Message { - mi := &file_p2p_proto_common_proto_msgTypes[9] + mi := &file_p2p_proto_common_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -652,7 +702,7 @@ func (x *BlockID) ProtoReflect() protoreflect.Message { // Deprecated: Use BlockID.ProtoReflect.Descriptor instead. func (*BlockID) Descriptor() ([]byte, []int) { - return file_p2p_proto_common_proto_rawDescGZIP(), []int{9} + return file_p2p_proto_common_proto_rawDescGZIP(), []int{10} } func (x *BlockID) GetNumber() uint64 { @@ -687,7 +737,7 @@ type Iteration struct { func (x *Iteration) Reset() { *x = Iteration{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_proto_common_proto_msgTypes[10] + mi := &file_p2p_proto_common_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -700,7 +750,7 @@ func (x *Iteration) String() string { func (*Iteration) ProtoMessage() {} func (x *Iteration) ProtoReflect() protoreflect.Message { - mi := &file_p2p_proto_common_proto_msgTypes[10] + mi := &file_p2p_proto_common_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -713,7 +763,7 @@ func (x *Iteration) ProtoReflect() protoreflect.Message { // Deprecated: Use Iteration.ProtoReflect.Descriptor instead. func (*Iteration) Descriptor() ([]byte, []int) { - return file_p2p_proto_common_proto_rawDescGZIP(), []int{10} + return file_p2p_proto_common_proto_rawDescGZIP(), []int{11} } func (m *Iteration) GetStart() isIteration_Start { @@ -785,7 +835,7 @@ type Fin struct { func (x *Fin) Reset() { *x = Fin{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_proto_common_proto_msgTypes[11] + mi := &file_p2p_proto_common_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -798,7 +848,7 @@ func (x *Fin) String() string { func (*Fin) ProtoMessage() {} func (x *Fin) ProtoReflect() protoreflect.Message { - mi := &file_p2p_proto_common_proto_msgTypes[11] + mi := &file_p2p_proto_common_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -811,7 +861,7 @@ func (x *Fin) ProtoReflect() protoreflect.Message { // Deprecated: Use Fin.ProtoReflect.Descriptor instead. func (*Fin) Descriptor() ([]byte, []int) { - return file_p2p_proto_common_proto_rawDescGZIP(), []int{11} + return file_p2p_proto_common_proto_rawDescGZIP(), []int{12} } var File_p2p_proto_common_proto protoreflect.FileDescriptor @@ -823,58 +873,61 @@ var file_p2p_proto_common_proto_rawDesc = []byte{ 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x22, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x22, 0x25, 0x0a, 0x06, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x1b, 0x0a, - 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x48, - 0x61, 0x73, 0x68, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x25, 0x0a, 0x07, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x22, 0x18, 0x0a, 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x2f, 0x0a, 0x07, 0x55, - 0x69, 0x6e, 0x74, 0x31, 0x32, 0x38, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x03, 0x6c, 0x6f, 0x77, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x67, 0x68, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x68, 0x69, 0x67, 0x68, 0x22, 0x44, 0x0a, 0x12, - 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x12, 0x16, 0x0a, 0x01, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, - 0x46, 0x65, 0x6c, 0x74, 0x32, 0x35, 0x32, 0x52, 0x01, 0x72, 0x12, 0x16, 0x0a, 0x01, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x46, 0x65, 0x6c, 0x74, 0x32, 0x35, 0x32, 0x52, - 0x01, 0x73, 0x22, 0x40, 0x0a, 0x08, 0x50, 0x61, 0x74, 0x72, 0x69, 0x63, 0x69, 0x61, 0x12, 0x19, - 0x0a, 0x08, 0x6e, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x07, 0x6e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x04, 0x72, 0x6f, 0x6f, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x04, - 0x72, 0x6f, 0x6f, 0x74, 0x22, 0x5c, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x74, 0x65, 0x44, 0x69, 0x66, - 0x66, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x44, 0x69, 0x66, - 0x66, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x19, 0x0a, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x04, 0x72, 0x6f, - 0x6f, 0x74, 0x22, 0x40, 0x0a, 0x07, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x12, 0x16, 0x0a, - 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x06, 0x68, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x22, 0xe0, 0x01, 0x0a, 0x09, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x48, 0x00, - 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x49, 0x74, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6c, 0x69, 0x6d, - 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x74, 0x65, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x04, 0x73, 0x74, 0x65, 0x70, 0x22, 0x26, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x10, 0x00, - 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x61, 0x63, 0x6b, 0x77, 0x61, 0x72, 0x64, 0x10, 0x01, 0x42, 0x07, - 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0x05, 0x0a, 0x03, 0x46, 0x69, 0x6e, 0x2a, 0x30, - 0x0a, 0x16, 0x4c, 0x31, 0x44, 0x61, 0x74, 0x61, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x61, 0x6c, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x6c, 0x6f, 0x62, 0x10, 0x01, - 0x2a, 0x20, 0x0a, 0x0e, 0x56, 0x6f, 0x6c, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x6d, 0x61, - 0x69, 0x6e, 0x12, 0x06, 0x0a, 0x02, 0x4c, 0x31, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x4c, 0x32, - 0x10, 0x01, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x64, 0x45, 0x74, 0x68, 0x2f, 0x6a, - 0x75, 0x6e, 0x6f, 0x2f, 0x70, 0x32, 0x70, 0x2f, 0x73, 0x74, 0x61, 0x72, 0x6b, 0x6e, 0x65, 0x74, - 0x2f, 0x73, 0x70, 0x65, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x74, 0x73, 0x22, 0x25, 0x0a, 0x07, 0x48, 0x61, 0x73, 0x68, 0x32, 0x35, 0x36, 0x12, 0x1a, + 0x0a, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x25, 0x0a, 0x06, 0x48, 0x61, + 0x73, 0x68, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, + 0x73, 0x22, 0x25, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x08, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x18, 0x0a, 0x06, 0x50, 0x65, 0x65, 0x72, + 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, + 0x69, 0x64, 0x22, 0x2f, 0x0a, 0x07, 0x55, 0x69, 0x6e, 0x74, 0x31, 0x32, 0x38, 0x12, 0x10, 0x0a, + 0x03, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6c, 0x6f, 0x77, 0x12, + 0x12, 0x0a, 0x04, 0x68, 0x69, 0x67, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x68, + 0x69, 0x67, 0x68, 0x22, 0x44, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, + 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x01, 0x72, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x46, 0x65, 0x6c, 0x74, 0x32, 0x35, 0x32, 0x52, 0x01, + 0x72, 0x12, 0x16, 0x0a, 0x01, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x46, + 0x65, 0x6c, 0x74, 0x32, 0x35, 0x32, 0x52, 0x01, 0x73, 0x22, 0x40, 0x0a, 0x08, 0x50, 0x61, 0x74, + 0x72, 0x69, 0x63, 0x69, 0x61, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, + 0x12, 0x19, 0x0a, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x05, + 0x2e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x22, 0x5c, 0x0a, 0x13, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x44, 0x69, 0x66, 0x66, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, + 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x69, 0x66, 0x66, + 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x44, 0x69, 0x66, 0x66, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x19, + 0x0a, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x48, + 0x61, 0x73, 0x68, 0x52, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x22, 0x40, 0x0a, 0x07, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x06, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x48, + 0x61, 0x73, 0x68, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0xe0, 0x01, 0x0a, 0x09, + 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x48, + 0x00, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1f, + 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x05, + 0x2e, 0x48, 0x61, 0x73, 0x68, 0x48, 0x00, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, + 0x32, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x74, 0x65, + 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x74, 0x65, 0x70, 0x22, 0x26, 0x0a, + 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x6f, + 0x72, 0x77, 0x61, 0x72, 0x64, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x61, 0x63, 0x6b, 0x77, + 0x61, 0x72, 0x64, 0x10, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0x05, + 0x0a, 0x03, 0x46, 0x69, 0x6e, 0x2a, 0x30, 0x0a, 0x16, 0x4c, 0x31, 0x44, 0x61, 0x74, 0x61, 0x41, + 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, + 0x0c, 0x0a, 0x08, 0x43, 0x61, 0x6c, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x10, 0x00, 0x12, 0x08, 0x0a, + 0x04, 0x42, 0x6c, 0x6f, 0x62, 0x10, 0x01, 0x2a, 0x20, 0x0a, 0x0e, 0x56, 0x6f, 0x6c, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x06, 0x0a, 0x02, 0x4c, 0x31, 0x10, + 0x00, 0x12, 0x06, 0x0a, 0x02, 0x4c, 0x32, 0x10, 0x01, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x64, 0x45, 0x74, 0x68, 0x2f, 0x6a, 0x75, 0x6e, 0x6f, 0x2f, 0x70, 0x32, 0x70, 0x2f, 0x73, + 0x74, 0x61, 0x72, 0x6b, 0x6e, 0x65, 0x74, 0x2f, 0x73, 0x70, 0x65, 0x63, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -890,23 +943,24 @@ func file_p2p_proto_common_proto_rawDescGZIP() []byte { } var file_p2p_proto_common_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_p2p_proto_common_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_p2p_proto_common_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_p2p_proto_common_proto_goTypes = []any{ (L1DataAvailabilityMode)(0), // 0: L1DataAvailabilityMode (VolitionDomain)(0), // 1: VolitionDomain (Iteration_Direction)(0), // 2: Iteration.Direction (*Felt252)(nil), // 3: Felt252 (*Hash)(nil), // 4: Hash - (*Hashes)(nil), // 5: Hashes - (*Address)(nil), // 6: Address - (*PeerID)(nil), // 7: PeerID - (*Uint128)(nil), // 8: Uint128 - (*ConsensusSignature)(nil), // 9: ConsensusSignature - (*Patricia)(nil), // 10: Patricia - (*StateDiffCommitment)(nil), // 11: StateDiffCommitment - (*BlockID)(nil), // 12: BlockID - (*Iteration)(nil), // 13: Iteration - (*Fin)(nil), // 14: Fin + (*Hash256)(nil), // 5: Hash256 + (*Hashes)(nil), // 6: Hashes + (*Address)(nil), // 7: Address + (*PeerID)(nil), // 8: PeerID + (*Uint128)(nil), // 9: Uint128 + (*ConsensusSignature)(nil), // 10: ConsensusSignature + (*Patricia)(nil), // 11: Patricia + (*StateDiffCommitment)(nil), // 12: StateDiffCommitment + (*BlockID)(nil), // 13: BlockID + (*Iteration)(nil), // 14: Iteration + (*Fin)(nil), // 15: Fin } var file_p2p_proto_common_proto_depIdxs = []int32{ 4, // 0: Hashes.items:type_name -> Hash @@ -955,7 +1009,7 @@ func file_p2p_proto_common_proto_init() { } } file_p2p_proto_common_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*Hashes); i { + switch v := v.(*Hash256); i { case 0: return &v.state case 1: @@ -967,7 +1021,7 @@ func file_p2p_proto_common_proto_init() { } } file_p2p_proto_common_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*Address); i { + switch v := v.(*Hashes); i { case 0: return &v.state case 1: @@ -979,7 +1033,7 @@ func file_p2p_proto_common_proto_init() { } } file_p2p_proto_common_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*PeerID); i { + switch v := v.(*Address); i { case 0: return &v.state case 1: @@ -991,7 +1045,7 @@ func file_p2p_proto_common_proto_init() { } } file_p2p_proto_common_proto_msgTypes[5].Exporter = func(v any, i int) any { - switch v := v.(*Uint128); i { + switch v := v.(*PeerID); i { case 0: return &v.state case 1: @@ -1003,7 +1057,7 @@ func file_p2p_proto_common_proto_init() { } } file_p2p_proto_common_proto_msgTypes[6].Exporter = func(v any, i int) any { - switch v := v.(*ConsensusSignature); i { + switch v := v.(*Uint128); i { case 0: return &v.state case 1: @@ -1015,7 +1069,7 @@ func file_p2p_proto_common_proto_init() { } } file_p2p_proto_common_proto_msgTypes[7].Exporter = func(v any, i int) any { - switch v := v.(*Patricia); i { + switch v := v.(*ConsensusSignature); i { case 0: return &v.state case 1: @@ -1027,7 +1081,7 @@ func file_p2p_proto_common_proto_init() { } } file_p2p_proto_common_proto_msgTypes[8].Exporter = func(v any, i int) any { - switch v := v.(*StateDiffCommitment); i { + switch v := v.(*Patricia); i { case 0: return &v.state case 1: @@ -1039,7 +1093,7 @@ func file_p2p_proto_common_proto_init() { } } file_p2p_proto_common_proto_msgTypes[9].Exporter = func(v any, i int) any { - switch v := v.(*BlockID); i { + switch v := v.(*StateDiffCommitment); i { case 0: return &v.state case 1: @@ -1051,7 +1105,7 @@ func file_p2p_proto_common_proto_init() { } } file_p2p_proto_common_proto_msgTypes[10].Exporter = func(v any, i int) any { - switch v := v.(*Iteration); i { + switch v := v.(*BlockID); i { case 0: return &v.state case 1: @@ -1063,6 +1117,18 @@ func file_p2p_proto_common_proto_init() { } } file_p2p_proto_common_proto_msgTypes[11].Exporter = func(v any, i int) any { + switch v := v.(*Iteration); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_proto_common_proto_msgTypes[12].Exporter = func(v any, i int) any { switch v := v.(*Fin); i { case 0: return &v.state @@ -1075,7 +1141,7 @@ func file_p2p_proto_common_proto_init() { } } } - file_p2p_proto_common_proto_msgTypes[10].OneofWrappers = []any{ + file_p2p_proto_common_proto_msgTypes[11].OneofWrappers = []any{ (*Iteration_BlockNumber)(nil), (*Iteration_Header)(nil), } @@ -1085,7 +1151,7 @@ func file_p2p_proto_common_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_p2p_proto_common_proto_rawDesc, NumEnums: 3, - NumMessages: 12, + NumMessages: 13, NumExtensions: 0, NumServices: 0, }, diff --git a/p2p/starknet/spec/receipt.pb.go b/p2p/starknet/spec/receipt.pb.go index 66f4772d24..5e29680442 100644 --- a/p2p/starknet/spec/receipt.pb.go +++ b/p2p/starknet/spec/receipt.pb.go @@ -518,7 +518,7 @@ type Receipt_L1Handler struct { unknownFields protoimpl.UnknownFields Common *Receipt_Common `protobuf:"bytes,1,opt,name=common,proto3" json:"common,omitempty"` - MsgHash *Hash `protobuf:"bytes,2,opt,name=msg_hash,json=msgHash,proto3" json:"msg_hash,omitempty"` + MsgHash *Hash256 `protobuf:"bytes,2,opt,name=msg_hash,json=msgHash,proto3" json:"msg_hash,omitempty"` } func (x *Receipt_L1Handler) Reset() { @@ -560,7 +560,7 @@ func (x *Receipt_L1Handler) GetCommon() *Receipt_Common { return nil } -func (x *Receipt_L1Handler) GetMsgHash() *Hash { +func (x *Receipt_L1Handler) GetMsgHash() *Hash256 { if x != nil { return x.MsgHash } @@ -869,7 +869,7 @@ var file_p2p_proto_receipt_proto_rawDesc = []byte{ 0x65, 0x73, 0x73, 0x22, 0x2d, 0x0a, 0x0f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x22, 0x99, 0x0c, 0x0a, 0x07, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x12, 0x29, + 0x74, 0x73, 0x22, 0x9c, 0x0c, 0x0a, 0x07, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x12, 0x29, 0x0a, 0x06, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x48, 0x00, 0x52, 0x06, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x6c, 0x31, 0x5f, @@ -944,35 +944,35 @@ var file_p2p_proto_receipt_proto_rawDesc = []byte{ 0x1a, 0x31, 0x0a, 0x06, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x06, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x1a, 0x56, 0x0a, 0x09, 0x4c, 0x31, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, + 0x6d, 0x6f, 0x6e, 0x1a, 0x59, 0x0a, 0x09, 0x4c, 0x31, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x08, 0x6d, 0x73, 0x67, - 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x48, 0x61, - 0x73, 0x68, 0x52, 0x07, 0x6d, 0x73, 0x67, 0x48, 0x61, 0x73, 0x68, 0x1a, 0x32, 0x0a, 0x07, 0x44, - 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, - 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x1a, - 0x66, 0x0a, 0x06, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x12, 0x27, 0x0a, 0x06, 0x63, 0x6f, 0x6d, + 0x6e, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x08, 0x6d, 0x73, 0x67, + 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x48, 0x61, + 0x73, 0x68, 0x32, 0x35, 0x36, 0x52, 0x07, 0x6d, 0x73, 0x67, 0x48, 0x61, 0x73, 0x68, 0x1a, 0x32, + 0x0a, 0x07, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x46, - 0x65, 0x6c, 0x74, 0x32, 0x35, 0x32, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x1a, 0x6d, 0x0a, 0x0d, 0x44, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, - 0x70, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x12, 0x33, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x46, 0x65, - 0x6c, 0x74, 0x32, 0x35, 0x32, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x1d, - 0x0a, 0x09, 0x50, 0x72, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x07, 0x0a, 0x03, 0x57, - 0x65, 0x69, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x46, 0x72, 0x69, 0x10, 0x01, 0x42, 0x31, 0x5a, - 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4e, 0x65, 0x74, 0x68, - 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x64, 0x45, 0x74, 0x68, 0x2f, 0x6a, 0x75, 0x6e, 0x6f, 0x2f, 0x70, - 0x32, 0x70, 0x2f, 0x73, 0x74, 0x61, 0x72, 0x6b, 0x6e, 0x65, 0x74, 0x2f, 0x73, 0x70, 0x65, 0x63, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6e, 0x1a, 0x66, 0x0a, 0x06, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x12, 0x27, 0x0a, 0x06, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x52, + 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x06, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, + 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x08, 0x2e, 0x46, 0x65, 0x6c, 0x74, 0x32, 0x35, 0x32, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x1a, 0x6d, 0x0a, 0x0d, 0x44, 0x65, + 0x70, 0x6c, 0x6f, 0x79, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x06, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x52, 0x65, + 0x63, 0x65, 0x69, 0x70, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x06, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, + 0x2e, 0x46, 0x65, 0x6c, 0x74, 0x32, 0x35, 0x32, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, + 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x2a, 0x1d, 0x0a, 0x09, 0x50, 0x72, 0x69, 0x63, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x07, + 0x0a, 0x03, 0x57, 0x65, 0x69, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x46, 0x72, 0x69, 0x10, 0x01, + 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4e, + 0x65, 0x74, 0x68, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x64, 0x45, 0x74, 0x68, 0x2f, 0x6a, 0x75, 0x6e, + 0x6f, 0x2f, 0x70, 0x32, 0x70, 0x2f, 0x73, 0x74, 0x61, 0x72, 0x6b, 0x6e, 0x65, 0x74, 0x2f, 0x73, + 0x70, 0x65, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1003,7 +1003,7 @@ var file_p2p_proto_receipt_proto_goTypes = []any{ (*Receipt_DeployAccount)(nil), // 10: Receipt.DeployAccount (*Receipt_ExecutionResources_BuiltinCounter)(nil), // 11: Receipt.ExecutionResources.BuiltinCounter (*Felt252)(nil), // 12: Felt252 - (*Hash)(nil), // 13: Hash + (*Hash256)(nil), // 13: Hash256 } var file_p2p_proto_receipt_proto_depIdxs = []int32{ 12, // 0: MessageToL1.from_address:type_name -> Felt252 @@ -1024,7 +1024,7 @@ var file_p2p_proto_receipt_proto_depIdxs = []int32{ 4, // 15: Receipt.Common.execution_resources:type_name -> Receipt.ExecutionResources 5, // 16: Receipt.Invoke.common:type_name -> Receipt.Common 5, // 17: Receipt.L1Handler.common:type_name -> Receipt.Common - 13, // 18: Receipt.L1Handler.msg_hash:type_name -> Hash + 13, // 18: Receipt.L1Handler.msg_hash:type_name -> Hash256 5, // 19: Receipt.Declare.common:type_name -> Receipt.Common 5, // 20: Receipt.Deploy.common:type_name -> Receipt.Common 12, // 21: Receipt.Deploy.contract_address:type_name -> Felt252 diff --git a/p2p/starknet/stream.go b/p2p/starknet/stream.go deleted file mode 100644 index b835c08442..0000000000 --- a/p2p/starknet/stream.go +++ /dev/null @@ -1,17 +0,0 @@ -package starknet - -// Stream represents a series of messages that can be accessed by invoking Stream a number of times. -// After stream is entirely consumed of elements, it should return false as its second return value -type Stream[T any] func() (T, bool) - -func StaticStream[T any](elems ...T) Stream[T] { - index := 0 - return func() (T, bool) { - var zero T - if index >= len(elems) { - return zero, false - } - index++ - return elems[index-1], true - } -} diff --git a/p2p/starknet/stream_test.go b/p2p/starknet/stream_test.go deleted file mode 100644 index 0df7fa5c18..0000000000 --- a/p2p/starknet/stream_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package starknet_test - -import ( - "testing" - - "github.com/NethermindEth/juno/p2p/starknet" - "github.com/stretchr/testify/require" -) - -func TestStream(t *testing.T) { - stream := starknet.StaticStream[int](0, 1, 2, 3) - for i := range 4 { - next, valid := stream() - require.True(t, valid) - require.Equal(t, i, next) - } - _, valid := stream() - require.False(t, valid) -} diff --git a/p2p/sync.go b/p2p/sync.go index c335adb227..1c11ba64e0 100644 --- a/p2p/sync.go +++ b/p2p/sync.go @@ -66,83 +66,86 @@ func (s *SyncService) Start(ctx context.Context) { s.log.Debugw("Continuous iteration", "i", i) iterCtx, cancelIteration := context.WithCancel(ctx) - - var nextHeight int - if curHeight, err := s.blockchain.Height(); err == nil { - nextHeight = int(curHeight) + 1 - } else if !errors.Is(err, db.ErrKeyNotFound) { - s.log.Errorw("Failed to get current height", "err", err) + nextHeight, err := s.getNextHeight() + if err != nil { + s.logError("Failed to get current height", err) + cancelIteration() + continue } s.log.Infow("Start Pipeline", "Current height", nextHeight-1, "Start", nextHeight) // todo change iteration to fetch several objects uint64(min(blockBehind, maxBlocks)) blockNumber := uint64(nextHeight) - headersAndSigsCh, err := s.genHeadersAndSigs(iterCtx, blockNumber) - if err != nil { - s.logError("Failed to get block headers parts", err) + if err := s.processBlock(iterCtx, blockNumber); err != nil { + s.logError("Failed to process block", fmt.Errorf("blockNumber: %d, err: %w", blockNumber, err)) cancelIteration() continue } - txsCh, err := s.genTransactions(iterCtx, blockNumber) - if err != nil { - s.logError("Failed to get transactions", err) - cancelIteration() - continue - } + cancelIteration() + } +} - eventsCh, err := s.genEvents(iterCtx, blockNumber) - if err != nil { - s.logError("Failed to get classes", err) - cancelIteration() - continue - } +func (s *SyncService) getNextHeight() (int, error) { + curHeight, err := s.blockchain.Height() + if err == nil { + return int(curHeight) + 1, nil + } else if errors.Is(err, db.ErrKeyNotFound) { + return 0, nil + } + return 0, err +} - classesCh, err := s.genClasses(iterCtx, blockNumber) - if err != nil { - s.logError("Failed to get classes", err) - cancelIteration() - continue - } +func (s *SyncService) processBlock(ctx context.Context, blockNumber uint64) error { + headersAndSigsCh, err := s.genHeadersAndSigs(ctx, blockNumber) + if err != nil { + return fmt.Errorf("failed to get block headers parts: %w", err) + } - stateDiffsCh, err := s.genStateDiffs(iterCtx, blockNumber) - if err != nil { - s.logError("Failed to get state diffs", err) - cancelIteration() - continue - } + txsCh, err := s.genTransactions(ctx, blockNumber) + if err != nil { + return fmt.Errorf("failed to get transactions: %w", err) + } - blocksCh := pipeline.Bridge(iterCtx, s.processSpecBlockParts(iterCtx, uint64(nextHeight), pipeline.FanIn(iterCtx, - pipeline.Stage(iterCtx, headersAndSigsCh, specBlockPartsFunc[specBlockHeaderAndSigs]), - pipeline.Stage(iterCtx, classesCh, specBlockPartsFunc[specClasses]), - pipeline.Stage(iterCtx, stateDiffsCh, specBlockPartsFunc[specContractDiffs]), - pipeline.Stage(iterCtx, txsCh, specBlockPartsFunc[specTxWithReceipts]), - pipeline.Stage(iterCtx, eventsCh, specBlockPartsFunc[specEvents]), - ))) - - for b := range blocksCh { - if b.err != nil { - // cannot process any more blocks - s.log.Errorw("Failed to process block", "err", b.err) - cancelIteration() - break - } + eventsCh, err := s.genEvents(ctx, blockNumber) + if err != nil { + return fmt.Errorf("failed to get events: %w", err) + } - storeTimer := time.Now() - err = s.blockchain.Store(b.block, b.commitments, b.stateUpdate, b.newClasses) - if err != nil { - s.log.Errorw("Failed to Store Block", "number", b.block.Number, "err", err) - cancelIteration() - break - } + classesCh, err := s.genClasses(ctx, blockNumber) + if err != nil { + return fmt.Errorf("failed to get classes: %w", err) + } - s.log.Infow("Stored Block", "number", b.block.Number, "hash", b.block.Hash.ShortString(), - "root", b.block.GlobalStateRoot.ShortString()) - s.listener.OnSyncStepDone(junoSync.OpStore, b.block.Number, time.Since(storeTimer)) + stateDiffsCh, err := s.genStateDiffs(ctx, blockNumber) + if err != nil { + return fmt.Errorf("failed to get state diffs: %w", err) + } + + blocksCh := pipeline.Bridge(ctx, s.processSpecBlockParts(ctx, blockNumber, pipeline.FanIn(ctx, + pipeline.Stage(ctx, headersAndSigsCh, specBlockPartsFunc[specBlockHeaderAndSigs]), + pipeline.Stage(ctx, classesCh, specBlockPartsFunc[specClasses]), + pipeline.Stage(ctx, stateDiffsCh, specBlockPartsFunc[specContractDiffs]), + pipeline.Stage(ctx, txsCh, specBlockPartsFunc[specTxWithReceipts]), + pipeline.Stage(ctx, eventsCh, specBlockPartsFunc[specEvents]), + ))) + + for b := range blocksCh { + if b.err != nil { + return fmt.Errorf("failed to process block: %w", b.err) } - cancelIteration() + + storeTimer := time.Now() + if err := s.blockchain.Store(b.block, b.commitments, b.stateUpdate, b.newClasses); err != nil { + return fmt.Errorf("failed to store block: %w", err) + } + + s.log.Infow("Stored Block", "number", b.block.Number, "hash", b.block.Hash.ShortString(), + "root", b.block.GlobalStateRoot.ShortString()) + s.listener.OnSyncStepDone(junoSync.OpStore, b.block.Number, time.Since(storeTimer)) } + return nil } func specBlockPartsFunc[T specBlockHeaderAndSigs | specTxWithReceipts | specEvents | specClasses | specContractDiffs](i T) specBlockParts { @@ -267,7 +270,7 @@ func (s *SyncService) processSpecBlockParts( return orderedBlockBodiesCh } -//nolint:gocyclo,funlen +//nolint:gocyclo func (s *SyncService) adaptAndSanityCheckBlock(ctx context.Context, header *spec.SignedBlockHeader, contractDiffs []*spec.ContractDiff, classes []*spec.Class, txs []*spec.Transaction, receipts []*spec.Receipt, events []*spec.Event, prevBlockRoot *felt.Felt, ) <-chan blockBody { @@ -332,17 +335,10 @@ func (s *SyncService) adaptAndSanityCheckBlock(ctx context.Context, header *spec return } - h, err := core.BlockHash(coreBlock) - if err != nil { - bodyCh <- blockBody{err: fmt.Errorf("block hash calculation error: %v", err)} - return - } - coreBlock.Hash = h - newClasses := make(map[felt.Felt]core.Class) for _, cls := range classes { coreC := p2p2core.AdaptClass(cls) - h, err = coreC.Hash() + h, err := coreC.Hash() if err != nil { bodyCh <- blockBody{err: fmt.Errorf("class hash calculation error: %v", err)} return @@ -415,26 +411,25 @@ func (s *SyncService) genHeadersAndSigs(ctx context.Context, blockNumber uint64) go func() { defer close(headersAndSigCh) - headersIt(func(res *spec.BlockHeadersResponse) bool { + loop: + for res := range headersIt { headerAndSig := specBlockHeaderAndSigs{} switch v := res.HeaderMessage.(type) { case *spec.BlockHeadersResponse_Header: headerAndSig.header = v.Header case *spec.BlockHeadersResponse_Fin: - return false + break loop default: s.log.Warnw("Unexpected HeaderMessage from getBlockHeaders", "v", v) - return false + break loop } select { case <-ctx.Done(): - return false + break case headersAndSigCh <- headerAndSig: } - - return true - }) + } }() return headersAndSigCh, nil @@ -461,18 +456,18 @@ func (s *SyncService) genClasses(ctx context.Context, blockNumber uint64) (<-cha defer close(classesCh) var classes []*spec.Class - classesIt(func(res *spec.ClassesResponse) bool { + loop: + for res := range classesIt { switch v := res.ClassMessage.(type) { case *spec.ClassesResponse_Class: classes = append(classes, v.Class) - return true case *spec.ClassesResponse_Fin: - return false + break loop default: s.log.Warnw("Unexpected ClassMessage from getClasses", "v", v) - return false + break loop } - }) + } select { case <-ctx.Done(): @@ -507,21 +502,21 @@ func (s *SyncService) genStateDiffs(ctx context.Context, blockNumber uint64) (<- defer close(stateDiffsCh) var contractDiffs []*spec.ContractDiff - stateDiffsIt(func(res *spec.StateDiffsResponse) bool { + + loop: + for res := range stateDiffsIt { switch v := res.StateDiffMessage.(type) { case *spec.StateDiffsResponse_ContractDiff: contractDiffs = append(contractDiffs, v.ContractDiff) - return true case *spec.StateDiffsResponse_DeclaredClass: s.log.Warnw("Unimplemented message StateDiffsResponse_DeclaredClass") - return true case *spec.StateDiffsResponse_Fin: - return false + break loop default: s.log.Warnw("Unexpected ClassMessage from getStateDiffs", "v", v) - return false + break loop } - }) + } select { case <-ctx.Done(): @@ -555,18 +550,19 @@ func (s *SyncService) genEvents(ctx context.Context, blockNumber uint64) (<-chan defer close(eventsCh) var events []*spec.Event - eventsIt(func(res *spec.EventsResponse) bool { + + loop: + for res := range eventsIt { switch v := res.EventMessage.(type) { case *spec.EventsResponse_Event: events = append(events, v.Event) - return true case *spec.EventsResponse_Fin: - return false + break loop default: s.log.Warnw("Unexpected EventMessage from getEvents", "v", v) - return false + break loop } - }) + } select { case <-ctx.Done(): @@ -604,20 +600,21 @@ func (s *SyncService) genTransactions(ctx context.Context, blockNumber uint64) ( transactions []*spec.Transaction receipts []*spec.Receipt ) - txsIt(func(res *spec.TransactionsResponse) bool { + + loop: + for res := range txsIt { switch v := res.TransactionMessage.(type) { case *spec.TransactionsResponse_TransactionWithReceipt: txWithReceipt := v.TransactionWithReceipt transactions = append(transactions, txWithReceipt.Transaction) receipts = append(receipts, txWithReceipt.Receipt) - return true case *spec.TransactionsResponse_Fin: - return false + break loop default: s.log.Warnw("Unexpected TransactionMessage from getTransactions", "v", v) - return false + break loop } - }) + } s.log.Debugw("Transactions length", "len", len(transactions)) spexTxs := specTxWithReceipts{ @@ -635,10 +632,9 @@ func (s *SyncService) genTransactions(ctx context.Context, blockNumber uint64) ( } func (s *SyncService) randomPeer() peer.ID { - peers := s.host.Peerstore().Peers() - + store := s.host.Peerstore() // todo do not request same block from all peers - peers = utils.Filter(peers, func(peerID peer.ID) bool { + peers := utils.Filter(store.Peers(), func(peerID peer.ID) bool { return peerID != s.host.ID() }) if len(peers) == 0 { @@ -647,8 +643,8 @@ func (s *SyncService) randomPeer() peer.ID { p := peers[rand.Intn(len(peers))] //nolint:gosec - // s.log.Debugw("Number of peers", "len", len(peers)) - // s.log.Debugw("Random chosen peer's info", "peerInfo", s.host.Peerstore().PeerInfo(p)) + s.log.Debugw("Number of peers", "len", len(peers)) + s.log.Debugw("Random chosen peer's info", "peerInfo", store.PeerInfo(p)) return p } diff --git a/plugin/plugin.go b/plugin/plugin.go new file mode 100644 index 0000000000..8dd9ee13d2 --- /dev/null +++ b/plugin/plugin.go @@ -0,0 +1,43 @@ +package plugin + +import ( + "fmt" + stdplugin "plugin" + + "github.com/NethermindEth/juno/core" + "github.com/NethermindEth/juno/core/felt" +) + +//go:generate mockgen -destination=../mocks/mock_plugin.go -package=mocks github.com/NethermindEth/juno/plugin JunoPlugin +type JunoPlugin interface { + Init() error + Shutdown() error + NewBlock(block *core.Block, stateUpdate *core.StateUpdate, newClasses map[felt.Felt]core.Class) error + // The state is reverted by applying a write operation with the reverseStateDiff's StorageDiffs, Nonces, and ReplacedClasses, + // and a delete option with its DeclaredV0Classes, DeclaredV1Classes, and ReplacedClasses. + RevertBlock(from, to *BlockAndStateUpdate, reverseStateDiff *core.StateDiff) error +} + +type BlockAndStateUpdate struct { + Block *core.Block + StateUpdate *core.StateUpdate +} + +func Load(pluginPath string) (JunoPlugin, error) { + plug, err := stdplugin.Open(pluginPath) + if err != nil { + return nil, fmt.Errorf("error loading plugin .so file: %w", err) + } + + symPlugin, err := plug.Lookup("JunoPluginInstance") + if err != nil { + return nil, fmt.Errorf("error looking up PluginInstance: %w", err) + } + + pluginInstance, ok := symPlugin.(JunoPlugin) + if !ok { + return nil, fmt.Errorf("the plugin does not staisfy the required interface") + } + + return pluginInstance, pluginInstance.Init() +} diff --git a/plugin/plugin_test.go b/plugin/plugin_test.go new file mode 100644 index 0000000000..3933835ae7 --- /dev/null +++ b/plugin/plugin_test.go @@ -0,0 +1,79 @@ +package plugin_test + +import ( + "context" + "testing" + "time" + + "github.com/NethermindEth/juno/blockchain" + "github.com/NethermindEth/juno/clients/feeder" + "github.com/NethermindEth/juno/db/pebble" + "github.com/NethermindEth/juno/mocks" + junoplugin "github.com/NethermindEth/juno/plugin" + adaptfeeder "github.com/NethermindEth/juno/starknetdata/feeder" + "github.com/NethermindEth/juno/sync" + "github.com/NethermindEth/juno/utils" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" +) + +func TestPlugin(t *testing.T) { + timeout := time.Second + mockCtrl := gomock.NewController(t) + t.Cleanup(mockCtrl.Finish) + + plugin := mocks.NewMockJunoPlugin(mockCtrl) + + mainClient := feeder.NewTestClient(t, &utils.Mainnet) + mainGw := adaptfeeder.New(mainClient) + + integClient := feeder.NewTestClient(t, &utils.Integration) + integGw := adaptfeeder.New(integClient) + + testDB := pebble.NewMemTest(t) + + // sync to integration for 2 blocks + for i := range 2 { + su, block, err := integGw.StateUpdateWithBlock(context.Background(), uint64(i)) + require.NoError(t, err) + plugin.EXPECT().NewBlock(block, su, gomock.Any()) + } + bc := blockchain.New(testDB, &utils.Integration) + synchronizer := sync.New(bc, integGw, utils.NewNopZapLogger(), 0, false).WithPlugin(plugin) + + ctx, cancel := context.WithTimeout(context.Background(), timeout) + require.NoError(t, synchronizer.Run(ctx)) + cancel() + + t.Run("resync to mainnet with the same db", func(t *testing.T) { + bc := blockchain.New(testDB, &utils.Mainnet) + + // Ensure current head is Integration head + head, err := bc.HeadsHeader() + require.NoError(t, err) + require.Equal(t, utils.HexToFelt(t, "0x34e815552e42c5eb5233b99de2d3d7fd396e575df2719bf98e7ed2794494f86"), head.Hash) + + // Reorg 2 blocks, then sync 3 blocks + su1, block1, err := integGw.StateUpdateWithBlock(context.Background(), uint64(1)) + require.NoError(t, err) + su0, block0, err := integGw.StateUpdateWithBlock(context.Background(), uint64(0)) + require.NoError(t, err) + plugin.EXPECT().RevertBlock(&junoplugin.BlockAndStateUpdate{block1, su1}, &junoplugin.BlockAndStateUpdate{block0, su0}, gomock.Any()) + plugin.EXPECT().RevertBlock(&junoplugin.BlockAndStateUpdate{block0, su0}, nil, gomock.Any()) + for i := range 3 { + su, block, err := mainGw.StateUpdateWithBlock(context.Background(), uint64(i)) + require.NoError(t, err) + plugin.EXPECT().NewBlock(block, su, gomock.Any()) + } + + synchronizer = sync.New(bc, mainGw, utils.NewNopZapLogger(), 0, false).WithPlugin(plugin) + ctx, cancel = context.WithTimeout(context.Background(), timeout) + require.NoError(t, synchronizer.Run(ctx)) + cancel() + + // After syncing (and reorging) the current head should be at mainnet + head, err = bc.HeadsHeader() + require.NoError(t, err) + require.Equal(t, utils.HexToFelt(t, "0x4e1f77f39545afe866ac151ac908bd1a347a2a8a7d58bef1276db4f06fdf2f6"), head.Hash) + }) +} diff --git a/plugin/service.go b/plugin/service.go new file mode 100644 index 0000000000..907feefa9e --- /dev/null +++ b/plugin/service.go @@ -0,0 +1,19 @@ +package plugin + +import "context" + +// Service provides an abstraction for signalling the plugin to shut down. +type Service struct { + plugin JunoPlugin +} + +func NewService(plugin JunoPlugin) *Service { + return &Service{ + plugin: plugin, + } +} + +func (p *Service) Run(ctx context.Context) error { + <-ctx.Done() + return p.plugin.Shutdown() +} diff --git a/plugin/service_test.go b/plugin/service_test.go new file mode 100644 index 0000000000..84e1e6ae9f --- /dev/null +++ b/plugin/service_test.go @@ -0,0 +1,47 @@ +package plugin_test + +import ( + "context" + "errors" + "testing" + + "github.com/NethermindEth/juno/mocks" + "github.com/NethermindEth/juno/plugin" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" +) + +func TestService(t *testing.T) { + t.Run("shutdown ok", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + p := mocks.NewMockJunoPlugin(ctrl) + p.EXPECT().Shutdown().Return(nil) + service := plugin.NewService(p) + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + // after ^ this ctx already cancelled + + err := service.Run(ctx) + require.NoError(t, err) + }) + t.Run("shutdown with error", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + shutdownErr := errors.New("error during shutdown") + + p := mocks.NewMockJunoPlugin(ctrl) + p.EXPECT().Shutdown().Return(shutdownErr) + service := plugin.NewService(p) + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + // after ^ this ctx already cancelled + + err := service.Run(ctx) + require.Equal(t, shutdownErr, err) + }) +} diff --git a/rpc/block.go b/rpc/block.go index 44114e9470..2902978078 100644 --- a/rpc/block.go +++ b/rpc/block.go @@ -193,17 +193,6 @@ func (h *Handler) BlockWithTxHashes(id BlockID) (*BlockWithTxHashes, *jsonrpc.Er }, nil } -func (h *Handler) BlockWithTxHashesV0_6(id BlockID) (*BlockWithTxHashes, *jsonrpc.Error) { - resp, err := h.BlockWithTxHashes(id) - if err != nil { - return nil, err - } - - resp.L1DAMode = nil - resp.L1DataGasPrice = nil - return resp, nil -} - // BlockTransactionCount returns the number of transactions in a block // identified by the given BlockID. // @@ -240,7 +229,7 @@ func (h *Handler) BlockWithReceipts(id BlockID) (*BlockWithReceipts, *jsonrpc.Er txsWithReceipts[index] = TransactionWithReceipt{ Transaction: AdaptTransaction(txn), // block_hash, block_number are optional in BlockWithReceipts response - Receipt: AdaptReceipt(r, txn, finalityStatus, nil, 0, false), + Receipt: AdaptReceipt(r, txn, finalityStatus, nil, 0), } } @@ -278,17 +267,6 @@ func (h *Handler) BlockWithTxs(id BlockID) (*BlockWithTxs, *jsonrpc.Error) { }, nil } -func (h *Handler) BlockWithTxsV0_6(id BlockID) (*BlockWithTxs, *jsonrpc.Error) { - resp, err := h.BlockWithTxs(id) - if err != nil { - return nil, err - } - - resp.L1DAMode = nil - resp.L1DataGasPrice = nil - return resp, nil -} - func (h *Handler) blockStatus(id BlockID, block *core.Block) (BlockStatus, *jsonrpc.Error) { l1H, jsonErr := h.l1Head() if jsonErr != nil { diff --git a/rpc/block_test.go b/rpc/block_test.go index c0ebb4f723..a6fa1d28ac 100644 --- a/rpc/block_test.go +++ b/rpc/block_test.go @@ -501,7 +501,7 @@ func TestBlockWithTxHashesV013(t *testing.T) { mockReader.EXPECT().BlockByNumber(gomock.Any()).Return(coreBlock, nil) mockReader.EXPECT().L1Head().Return(&core.L1Head{}, nil) - got, rpcErr := handler.BlockWithTxsV0_6(rpc.BlockID{Number: blockNumber}) + got, rpcErr := handler.BlockWithTxs(rpc.BlockID{Number: blockNumber}) require.Nil(t, rpcErr) got.Transactions = got.Transactions[:1] @@ -512,10 +512,15 @@ func TestBlockWithTxHashesV013(t *testing.T) { NewRoot: coreBlock.GlobalStateRoot, Number: &coreBlock.Number, ParentHash: coreBlock.ParentHash, + L1DAMode: utils.Ptr(rpc.Blob), L1GasPrice: &rpc.ResourcePrice{ InFri: utils.HexToFelt(t, "0x17882b6aa74"), InWei: utils.HexToFelt(t, "0x3b9aca10"), }, + L1DataGasPrice: &rpc.ResourcePrice{ + InFri: utils.HexToFelt(t, "0x2cc6d7f596e1"), + InWei: utils.HexToFelt(t, "0x716a8f6dd"), + }, SequencerAddress: coreBlock.SequencerAddress, Timestamp: coreBlock.Timestamp, }, @@ -604,7 +609,7 @@ func TestBlockWithReceipts(t *testing.T) { txsWithReceipt = append(txsWithReceipt, rpc.TransactionWithReceipt{ Transaction: adaptedTx, - Receipt: rpc.AdaptReceipt(receipt, tx, rpc.TxnAcceptedOnL2, nil, 0, true), + Receipt: rpc.AdaptReceipt(receipt, tx, rpc.TxnAcceptedOnL2, nil, 0), }) } @@ -648,7 +653,7 @@ func TestBlockWithReceipts(t *testing.T) { transactions = append(transactions, rpc.TransactionWithReceipt{ Transaction: adaptedTx, - Receipt: rpc.AdaptReceipt(receipt, tx, rpc.TxnAcceptedOnL1, nil, 0, true), + Receipt: rpc.AdaptReceipt(receipt, tx, rpc.TxnAcceptedOnL1, nil, 0), }) } diff --git a/rpc/class.go b/rpc/class.go index b2beee24a2..c51a942500 100644 --- a/rpc/class.go +++ b/rpc/class.go @@ -9,6 +9,7 @@ import ( "github.com/NethermindEth/juno/core/felt" "github.com/NethermindEth/juno/jsonrpc" "github.com/NethermindEth/juno/starknet" + "github.com/NethermindEth/juno/starknet/compiler" "github.com/NethermindEth/juno/utils" ) @@ -49,7 +50,7 @@ func adaptDeclaredClass(declaredClass json.RawMessage) (core.Class, error) { switch { case feederClass.V1 != nil: - compiledClass, cErr := starknet.Compile(feederClass.V1) + compiledClass, cErr := compiler.Compile(feederClass.V1) if cErr != nil { return nil, cErr } diff --git a/rpc/estimate_fee.go b/rpc/estimate_fee.go index c89599abac..3af789c4f3 100644 --- a/rpc/estimate_fee.go +++ b/rpc/estimate_fee.go @@ -1,9 +1,9 @@ package rpc import ( - "encoding/json" "errors" "fmt" + "net/http" "github.com/NethermindEth/juno/core/felt" "github.com/NethermindEth/juno/jsonrpc" @@ -35,27 +35,6 @@ type FeeEstimate struct { DataGasPrice *felt.Felt `json:"data_gas_price"` OverallFee *felt.Felt `json:"overall_fee"` Unit *FeeUnit `json:"unit,omitempty"` - // pre 13.1 response - v0_6Response bool -} - -func (f FeeEstimate) MarshalJSON() ([]byte, error) { - if f.v0_6Response { - return json.Marshal(struct { - GasConsumed *felt.Felt `json:"gas_consumed"` - GasPrice *felt.Felt `json:"gas_price"` - OverallFee *felt.Felt `json:"overall_fee"` - Unit *FeeUnit `json:"unit,omitempty"` - }{ - GasConsumed: f.GasConsumed, - GasPrice: f.GasPrice, - OverallFee: f.OverallFee, - Unit: f.Unit, - }) - } else { - type alias FeeEstimate // avoid infinite recursion - return json.Marshal(alias(f)) - } } /**************************************************** @@ -64,52 +43,29 @@ func (f FeeEstimate) MarshalJSON() ([]byte, error) { func (h *Handler) EstimateFee(broadcastedTxns []BroadcastedTransaction, simulationFlags []SimulationFlag, id BlockID, -) ([]FeeEstimate, *jsonrpc.Error) { - result, err := h.simulateTransactions(id, broadcastedTxns, append(simulationFlags, SkipFeeChargeFlag), false, true) +) ([]FeeEstimate, http.Header, *jsonrpc.Error) { + result, httpHeader, err := h.simulateTransactions(id, broadcastedTxns, append(simulationFlags, SkipFeeChargeFlag), true) if err != nil { - return nil, err + return nil, httpHeader, err } return utils.Map(result, func(tx SimulatedTransaction) FeeEstimate { return tx.FeeEstimation - }), nil + }), httpHeader, nil } -func (h *Handler) EstimateFeeV0_6(broadcastedTxns []BroadcastedTransaction, - simulationFlags []SimulationFlag, id BlockID, -) ([]FeeEstimate, *jsonrpc.Error) { - result, err := h.simulateTransactions(id, broadcastedTxns, append(simulationFlags, SkipFeeChargeFlag), true, true) - if err != nil { - return nil, err - } - - return utils.Map(result, func(tx SimulatedTransaction) FeeEstimate { - return tx.FeeEstimation - }), nil -} - -func (h *Handler) EstimateMessageFee(msg MsgFromL1, id BlockID) (*FeeEstimate, *jsonrpc.Error) { //nolint:gocritic +func (h *Handler) EstimateMessageFee(msg MsgFromL1, id BlockID) (*FeeEstimate, http.Header, *jsonrpc.Error) { //nolint:gocritic return h.estimateMessageFee(msg, id, h.EstimateFee) } -func (h *Handler) EstimateMessageFeeV0_6(msg MsgFromL1, id BlockID) (*FeeEstimate, *jsonrpc.Error) { //nolint:gocritic - feeEstimate, rpcErr := h.estimateMessageFee(msg, id, h.EstimateFeeV0_6) - if rpcErr != nil { - return nil, rpcErr - } - - feeEstimate.v0_6Response = true - feeEstimate.DataGasPrice = nil - feeEstimate.DataGasConsumed = nil - - return feeEstimate, nil -} - type estimateFeeHandler func(broadcastedTxns []BroadcastedTransaction, simulationFlags []SimulationFlag, id BlockID, -) ([]FeeEstimate, *jsonrpc.Error) +) ([]FeeEstimate, http.Header, *jsonrpc.Error) -func (h *Handler) estimateMessageFee(msg MsgFromL1, id BlockID, f estimateFeeHandler) (*FeeEstimate, *jsonrpc.Error) { //nolint:gocritic +//nolint:gocritic +func (h *Handler) estimateMessageFee(msg MsgFromL1, id BlockID, f estimateFeeHandler) (*FeeEstimate, + http.Header, *jsonrpc.Error, +) { calldata := make([]*felt.Felt, 0, len(msg.Payload)+1) // The order of the calldata parameters matters. msg.From must be prepended. calldata = append(calldata, new(felt.Felt).SetBytes(msg.From.Bytes())) @@ -129,15 +85,15 @@ func (h *Handler) estimateMessageFee(msg MsgFromL1, id BlockID, f estimateFeeHan // Must be greater than zero to successfully execute transaction. PaidFeeOnL1: new(felt.Felt).SetUint64(1), } - estimates, rpcErr := f([]BroadcastedTransaction{tx}, nil, id) + estimates, httpHeader, rpcErr := f([]BroadcastedTransaction{tx}, nil, id) if rpcErr != nil { if rpcErr.Code == ErrTransactionExecutionError.Code { data := rpcErr.Data.(TransactionExecutionErrorData) - return nil, makeContractError(errors.New(data.ExecutionError)) + return nil, httpHeader, makeContractError(errors.New(data.ExecutionError)) } - return nil, rpcErr + return nil, httpHeader, rpcErr } - return &estimates[0], nil + return &estimates[0], httpHeader, nil } type ContractErrorData struct { diff --git a/rpc/estimate_fee_test.go b/rpc/estimate_fee_test.go index 0520a806f2..fdc3699a8e 100644 --- a/rpc/estimate_fee_test.go +++ b/rpc/estimate_fee_test.go @@ -3,98 +3,19 @@ package rpc_test import ( "encoding/json" "errors" - "fmt" "testing" "github.com/NethermindEth/juno/core" "github.com/NethermindEth/juno/core/felt" - "github.com/NethermindEth/juno/db" "github.com/NethermindEth/juno/mocks" "github.com/NethermindEth/juno/rpc" "github.com/NethermindEth/juno/utils" "github.com/NethermindEth/juno/vm" - "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) -func TestEstimateMessageFeeV0_6(t *testing.T) { - mockCtrl := gomock.NewController(t) - t.Cleanup(mockCtrl.Finish) - - n := utils.Ptr(utils.Mainnet) - mockReader := mocks.NewMockReader(mockCtrl) - mockReader.EXPECT().Network().Return(n).AnyTimes() - mockVM := mocks.NewMockVM(mockCtrl) - - handler := rpc.New(mockReader, nil, mockVM, "", utils.NewNopZapLogger()) - msg := rpc.MsgFromL1{ - From: common.HexToAddress("0xDEADBEEF"), - To: *new(felt.Felt).SetUint64(1337), - Payload: []felt.Felt{*new(felt.Felt).SetUint64(1), *new(felt.Felt).SetUint64(2)}, - Selector: *new(felt.Felt).SetUint64(44), - } - - t.Run("block not found", func(t *testing.T) { - mockReader.EXPECT().HeadState().Return(nil, nil, db.ErrKeyNotFound) - _, err := handler.EstimateMessageFeeV0_6(msg, rpc.BlockID{Latest: true}) - require.Equal(t, rpc.ErrBlockNotFound, err) - }) - - latestHeader := &core.Header{ - Number: 9, - Timestamp: 456, - GasPrice: new(felt.Felt).SetUint64(42), - } - mockState := mocks.NewMockStateHistoryReader(mockCtrl) - - mockReader.EXPECT().HeadState().Return(mockState, nopCloser, nil) - mockReader.EXPECT().HeadsHeader().Return(latestHeader, nil) - - expectedGasConsumed := new(felt.Felt).SetUint64(37) - mockVM.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), &vm.BlockInfo{ - Header: latestHeader, - }, gomock.Any(), &utils.Mainnet, gomock.Any(), false, true, false).DoAndReturn( - func(txns []core.Transaction, declaredClasses []core.Class, paidFeesOnL1 []*felt.Felt, blockInfo *vm.BlockInfo, - state core.StateReader, network *utils.Network, skipChargeFee, skipValidate, errOnRevert, useBlobData bool, - ) ([]*felt.Felt, []*felt.Felt, []vm.TransactionTrace, error) { - require.Len(t, txns, 1) - assert.NotNil(t, txns[0].(*core.L1HandlerTransaction)) - - assert.Empty(t, declaredClasses) - assert.Len(t, paidFeesOnL1, 1) - - actualFee := new(felt.Felt).Mul(expectedGasConsumed, blockInfo.Header.GasPrice) - return []*felt.Felt{actualFee}, []*felt.Felt{&felt.Zero}, []vm.TransactionTrace{{ - StateDiff: &vm.StateDiff{ - StorageDiffs: []vm.StorageDiff{}, - Nonces: []vm.Nonce{}, - DeployedContracts: []vm.DeployedContract{}, - DeprecatedDeclaredClasses: []*felt.Felt{}, - DeclaredClasses: []vm.DeclaredClass{}, - ReplacedClasses: []vm.ReplacedClass{}, - }, - }}, nil - }, - ) - - estimateFee, err := handler.EstimateMessageFeeV0_6(msg, rpc.BlockID{Latest: true}) - require.Nil(t, err) - expectedJSON := fmt.Sprintf( - `{"gas_consumed":%q,"gas_price":%q,"overall_fee":%q,"unit":"WEI"}`, - expectedGasConsumed, - latestHeader.GasPrice, - new(felt.Felt).Mul(expectedGasConsumed, latestHeader.GasPrice), - ) - - // we check json response here because some fields are private and we can't set them and assert.Equal fails - // also in 0.6 response some fields should not be presented - estimateFeeJSON, jsonErr := json.Marshal(estimateFee) - require.NoError(t, jsonErr) - require.Equal(t, expectedJSON, string(estimateFeeJSON)) -} - func TestEstimateFee(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -113,33 +34,36 @@ func TestEstimateFee(t *testing.T) { blockInfo := vm.BlockInfo{Header: &core.Header{}} t.Run("ok with zero values", func(t *testing.T) { - mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &blockInfo, mockState, n, true, false, true, true). - Return([]*felt.Felt{}, []*felt.Felt{}, []vm.TransactionTrace{}, nil) + mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &blockInfo, mockState, n, true, false, true). + Return([]*felt.Felt{}, []core.GasConsumed{}, []vm.TransactionTrace{}, uint64(123), nil) - _, err := handler.EstimateFee([]rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{}, rpc.BlockID{Latest: true}) + _, httpHeader, err := handler.EstimateFee([]rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{}, rpc.BlockID{Latest: true}) require.Nil(t, err) + assert.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), "123") }) t.Run("ok with zero values, skip validate", func(t *testing.T) { - mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &blockInfo, mockState, n, true, true, true, true). - Return([]*felt.Felt{}, []*felt.Felt{}, []vm.TransactionTrace{}, nil) + mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &blockInfo, mockState, n, true, true, true). + Return([]*felt.Felt{}, []core.GasConsumed{}, []vm.TransactionTrace{}, uint64(123), nil) - _, err := handler.EstimateFee([]rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipValidateFlag}, rpc.BlockID{Latest: true}) + _, httpHeader, err := handler.EstimateFee([]rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipValidateFlag}, rpc.BlockID{Latest: true}) require.Nil(t, err) + assert.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), "123") }) t.Run("transaction execution error", func(t *testing.T) { - mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &blockInfo, mockState, n, true, true, true, true). - Return(nil, nil, nil, vm.TransactionExecutionError{ + mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &blockInfo, mockState, n, true, true, true). + Return(nil, nil, nil, uint64(0), vm.TransactionExecutionError{ Index: 44, Cause: errors.New("oops"), }) - _, err := handler.EstimateFee([]rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipValidateFlag}, rpc.BlockID{Latest: true}) + _, httpHeader, err := handler.EstimateFee([]rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipValidateFlag}, rpc.BlockID{Latest: true}) require.Equal(t, rpc.ErrTransactionExecutionError.CloneWithData(rpc.TransactionExecutionErrorData{ TransactionIndex: 44, ExecutionError: "oops", }), err) + require.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), "0") }) } diff --git a/rpc/events_test.go b/rpc/events_test.go index 736e888c19..8eb54a3f4e 100644 --- a/rpc/events_test.go +++ b/rpc/events_test.go @@ -19,9 +19,9 @@ import ( adaptfeeder "github.com/NethermindEth/juno/starknetdata/feeder" "github.com/NethermindEth/juno/sync" "github.com/NethermindEth/juno/utils" + "github.com/coder/websocket" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "nhooyr.io/websocket" ) func TestEvents(t *testing.T) { diff --git a/rpc/handlers.go b/rpc/handlers.go index cfaf1f37a1..5bddfe3de3 100644 --- a/rpc/handlers.go +++ b/rpc/handlers.go @@ -68,8 +68,7 @@ const ( ) type traceCacheKey struct { - blockHash felt.Felt - v0_6Response bool + blockHash felt.Felt } type Handler struct { @@ -164,14 +163,14 @@ func (h *Handler) Version() (string, *jsonrpc.Error) { } func (h *Handler) SpecVersion() (string, *jsonrpc.Error) { - return "0.7.1", nil + return "0.8.0", nil } -func (h *Handler) SpecVersionV0_6() (string, *jsonrpc.Error) { - return "0.6.0", nil +func (h *Handler) SpecVersionV0_7() (string, *jsonrpc.Error) { + return "0.7.1", nil } -func (h *Handler) Methods() ([]jsonrpc.Method, string) { //nolint: funlen +func (h *Handler) Methods() ([]jsonrpc.Method, string) { //nolint: funlen, dupl return []jsonrpc.Method{ { Name: "starknet_chainId", @@ -326,10 +325,10 @@ func (h *Handler) Methods() ([]jsonrpc.Method, string) { //nolint: funlen Params: []jsonrpc.Parameter{{Name: "block_id"}}, Handler: h.BlockWithReceipts, }, - }, "/v0_7" + }, "/v0_8" } -func (h *Handler) MethodsV0_6() ([]jsonrpc.Method, string) { //nolint: funlen +func (h *Handler) MethodsV0_7() ([]jsonrpc.Method, string) { //nolint: funlen, dupl return []jsonrpc.Method{ { Name: "starknet_chainId", @@ -346,12 +345,12 @@ func (h *Handler) MethodsV0_6() ([]jsonrpc.Method, string) { //nolint: funlen { Name: "starknet_getBlockWithTxHashes", Params: []jsonrpc.Parameter{{Name: "block_id"}}, - Handler: h.BlockWithTxHashesV0_6, + Handler: h.BlockWithTxHashes, }, { Name: "starknet_getBlockWithTxs", Params: []jsonrpc.Parameter{{Name: "block_id"}}, - Handler: h.BlockWithTxsV0_6, + Handler: h.BlockWithTxs, }, { Name: "starknet_getTransactionByHash", @@ -361,7 +360,7 @@ func (h *Handler) MethodsV0_6() ([]jsonrpc.Method, string) { //nolint: funlen { Name: "starknet_getTransactionReceipt", Params: []jsonrpc.Parameter{{Name: "transaction_hash"}}, - Handler: h.TransactionReceiptByHashV0_6, + Handler: h.TransactionReceiptByHash, }, { Name: "starknet_getBlockTransactionCount", @@ -439,36 +438,36 @@ func (h *Handler) MethodsV0_6() ([]jsonrpc.Method, string) { //nolint: funlen { Name: "starknet_call", Params: []jsonrpc.Parameter{{Name: "request"}, {Name: "block_id"}}, - Handler: h.CallV0_6, + Handler: h.Call, }, { Name: "starknet_estimateFee", Params: []jsonrpc.Parameter{{Name: "request"}, {Name: "simulation_flags"}, {Name: "block_id"}}, - Handler: h.EstimateFeeV0_6, + Handler: h.EstimateFee, }, { Name: "starknet_estimateMessageFee", Params: []jsonrpc.Parameter{{Name: "message"}, {Name: "block_id"}}, - Handler: h.EstimateMessageFeeV0_6, + Handler: h.EstimateMessageFee, }, { Name: "starknet_traceTransaction", Params: []jsonrpc.Parameter{{Name: "transaction_hash"}}, - Handler: h.TraceTransactionV0_6, + Handler: h.TraceTransaction, }, { Name: "starknet_simulateTransactions", Params: []jsonrpc.Parameter{{Name: "block_id"}, {Name: "transactions"}, {Name: "simulation_flags"}}, - Handler: h.SimulateTransactionsV0_6, + Handler: h.SimulateTransactions, }, { Name: "starknet_traceBlockTransactions", Params: []jsonrpc.Parameter{{Name: "block_id"}}, - Handler: h.TraceBlockTransactionsV0_6, + Handler: h.TraceBlockTransactions, }, { Name: "starknet_specVersion", - Handler: h.SpecVersionV0_6, + Handler: h.SpecVersionV0_7, }, { Name: "juno_subscribeNewHeads", @@ -479,5 +478,10 @@ func (h *Handler) MethodsV0_6() ([]jsonrpc.Method, string) { //nolint: funlen Params: []jsonrpc.Parameter{{Name: "id"}}, Handler: h.Unsubscribe, }, - }, "/v0_6" + { + Name: "starknet_getBlockWithReceipts", + Params: []jsonrpc.Parameter{{Name: "block_id"}}, + Handler: h.BlockWithReceipts, + }, + }, "/v0_7" } diff --git a/rpc/handlers_test.go b/rpc/handlers_test.go index 48374d20d8..af5e9ae7a6 100644 --- a/rpc/handlers_test.go +++ b/rpc/handlers_test.go @@ -30,11 +30,11 @@ func TestSpecVersion(t *testing.T) { handler := rpc.New(nil, nil, nil, "", nil) version, rpcErr := handler.SpecVersion() require.Nil(t, rpcErr) - require.Equal(t, "0.7.1", version) + require.Equal(t, "0.8.0", version) - legacyVersion, rpcErr := handler.SpecVersionV0_6() + legacyVersion, rpcErr := handler.SpecVersionV0_7() require.Nil(t, rpcErr) - require.Equal(t, "0.6.0", legacyVersion) + require.Equal(t, "0.7.1", legacyVersion) } func TestThrottledVMError(t *testing.T) { @@ -60,8 +60,9 @@ func TestThrottledVMError(t *testing.T) { t.Run("simulate", func(t *testing.T) { mockReader.EXPECT().HeadState().Return(mockState, nopCloser, nil) mockReader.EXPECT().HeadsHeader().Return(&core.Header{}, nil) - _, rpcErr := handler.SimulateTransactions(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipFeeChargeFlag}) + _, httpHeader, rpcErr := handler.SimulateTransactions(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipFeeChargeFlag}) assert.Equal(t, throttledErr, rpcErr.Data) + assert.NotEmpty(t, httpHeader.Get(rpc.ExecutionStepsHeader)) }) t.Run("trace", func(t *testing.T) { @@ -95,7 +96,8 @@ func TestThrottledVMError(t *testing.T) { headState := mocks.NewMockStateHistoryReader(mockCtrl) headState.EXPECT().Class(declareTx.ClassHash).Return(declaredClass, nil) mockReader.EXPECT().PendingState().Return(headState, nopCloser, nil) - _, rpcErr := handler.TraceBlockTransactions(context.Background(), rpc.BlockID{Hash: blockHash}) + _, httpHeader, rpcErr := handler.TraceBlockTransactions(context.Background(), rpc.BlockID{Hash: blockHash}) assert.Equal(t, throttledErr, rpcErr.Data) + assert.NotEmpty(t, httpHeader.Get(rpc.ExecutionStepsHeader)) }) } diff --git a/rpc/helpers.go b/rpc/helpers.go index 2c65f437b7..dae08c5ff4 100644 --- a/rpc/helpers.go +++ b/rpc/helpers.go @@ -87,9 +87,11 @@ func (h *Handler) blockHeaderByID(id *BlockID) (*core.Header, *jsonrpc.Error) { return header, nil } -func adaptExecutionResources(resources *core.ExecutionResources, v0_6Response bool) *ExecutionResources { +func adaptExecutionResources(resources *core.ExecutionResources) *ExecutionResources { if resources == nil { - return &ExecutionResources{} + return &ExecutionResources{ + DataAvailability: &DataAvailability{}, + } } res := &ExecutionResources{ @@ -105,8 +107,9 @@ func adaptExecutionResources(resources *core.ExecutionResources, v0_6Response bo Poseidon: resources.BuiltinInstanceCounter.Poseidon, SegmentArena: resources.BuiltinInstanceCounter.SegmentArena, }, + DataAvailability: &DataAvailability{}, } - if !v0_6Response && resources.DataAvailability != nil { + if resources.DataAvailability != nil { res.DataAvailability = &DataAvailability{ L1Gas: resources.DataAvailability.L1Gas, L1DataGas: resources.DataAvailability.L1DataGas, diff --git a/rpc/simulation.go b/rpc/simulation.go index fb58b230b4..3dda777ed9 100644 --- a/rpc/simulation.go +++ b/rpc/simulation.go @@ -3,7 +3,9 @@ package rpc import ( "errors" "fmt" + "net/http" "slices" + "strconv" "github.com/NethermindEth/juno/core" "github.com/NethermindEth/juno/core/felt" @@ -19,6 +21,8 @@ const ( SkipFeeChargeFlag ) +const ExecutionStepsHeader string = "X-Cairo-Steps" + func (s *SimulationFlag) UnmarshalJSON(bytes []byte) (err error) { switch flag := string(bytes); flag { case `"SKIP_VALIDATE"`: @@ -48,34 +52,29 @@ type TracedBlockTransaction struct { func (h *Handler) SimulateTransactions(id BlockID, transactions []BroadcastedTransaction, simulationFlags []SimulationFlag, -) ([]SimulatedTransaction, *jsonrpc.Error) { - return h.simulateTransactions(id, transactions, simulationFlags, false, false) -} - -// pre 13.1 -func (h *Handler) SimulateTransactionsV0_6(id BlockID, transactions []BroadcastedTransaction, - simulationFlags []SimulationFlag, -) ([]SimulatedTransaction, *jsonrpc.Error) { - // todo double check errOnRevert = false - return h.simulateTransactions(id, transactions, simulationFlags, true, false) +) ([]SimulatedTransaction, http.Header, *jsonrpc.Error) { + return h.simulateTransactions(id, transactions, simulationFlags, false) } //nolint:funlen,gocyclo func (h *Handler) simulateTransactions(id BlockID, transactions []BroadcastedTransaction, - simulationFlags []SimulationFlag, v0_6Response, errOnRevert bool, -) ([]SimulatedTransaction, *jsonrpc.Error) { + simulationFlags []SimulationFlag, errOnRevert bool, +) ([]SimulatedTransaction, http.Header, *jsonrpc.Error) { skipFeeCharge := slices.Contains(simulationFlags, SkipFeeChargeFlag) skipValidate := slices.Contains(simulationFlags, SkipValidateFlag) + httpHeader := http.Header{} + httpHeader.Set(ExecutionStepsHeader, "0") + state, closer, rpcErr := h.stateByBlockID(&id) if rpcErr != nil { - return nil, rpcErr + return nil, httpHeader, rpcErr } defer h.callAndLogErr(closer, "Failed to close state in starknet_estimateFee") header, rpcErr := h.blockHeaderByID(&id) if rpcErr != nil { - return nil, rpcErr + return nil, httpHeader, rpcErr } txns := make([]core.Transaction, 0, len(transactions)) @@ -85,7 +84,7 @@ func (h *Handler) simulateTransactions(id BlockID, transactions []BroadcastedTra for idx := range transactions { txn, declaredClass, paidFeeOnL1, aErr := adaptBroadcastedTransaction(&transactions[idx], h.bcReader.Network()) if aErr != nil { - return nil, jsonrpc.Err(jsonrpc.InvalidParams, aErr.Error()) + return nil, httpHeader, jsonrpc.Err(jsonrpc.InvalidParams, aErr.Error()) } if paidFeeOnL1 != nil { @@ -100,24 +99,26 @@ func (h *Handler) simulateTransactions(id BlockID, transactions []BroadcastedTra blockHashToBeRevealed, err := h.getRevealedBlockHash(header.Number) if err != nil { - return nil, ErrInternal.CloneWithData(err) + return nil, httpHeader, ErrInternal.CloneWithData(err) } blockInfo := vm.BlockInfo{ Header: header, BlockHashToBeRevealed: blockHashToBeRevealed, } - useBlobData := !v0_6Response - overallFees, dataGasConsumed, traces, err := h.vm.Execute(txns, classes, paidFeesOnL1, &blockInfo, - state, h.bcReader.Network(), skipFeeCharge, skipValidate, errOnRevert, useBlobData) + overallFees, daGas, traces, numSteps, err := h.vm.Execute(txns, classes, paidFeesOnL1, &blockInfo, + state, h.bcReader.Network(), skipFeeCharge, skipValidate, errOnRevert) + + httpHeader.Set(ExecutionStepsHeader, strconv.FormatUint(numSteps, 10)) + if err != nil { if errors.Is(err, utils.ErrResourceBusy) { - return nil, ErrInternal.CloneWithData(throttledVMErr) + return nil, httpHeader, ErrInternal.CloneWithData(throttledVMErr) } var txnExecutionError vm.TransactionExecutionError if errors.As(err, &txnExecutionError) { - return nil, makeTransactionExecutionError(&txnExecutionError) + return nil, httpHeader, makeTransactionExecutionError(&txnExecutionError) } - return nil, ErrUnexpectedError.CloneWithData(err.Error()) + return nil, httpHeader, ErrUnexpectedError.CloneWithData(err.Error()) } result := make([]SimulatedTransaction, 0, len(overallFees)) @@ -142,30 +143,27 @@ func (h *Handler) simulateTransactions(id BlockID, transactions []BroadcastedTra } var gasConsumed *felt.Felt - if !v0_6Response { - dataGasFee := new(felt.Felt).Mul(dataGasConsumed[i], dataGasPrice) - gasConsumed = new(felt.Felt).Sub(overallFee, dataGasFee) - } else { - gasConsumed = overallFee.Clone() - } + daGasL1DataGas := new(felt.Felt).SetUint64(daGas[i].L1DataGas) + dataGasFee := new(felt.Felt).Mul(daGasL1DataGas, dataGasPrice) + gasConsumed = new(felt.Felt).Sub(overallFee, dataGasFee) gasConsumed = gasConsumed.Div(gasConsumed, gasPrice) // division by zero felt is zero felt estimate := FeeEstimate{ GasConsumed: gasConsumed, GasPrice: gasPrice, - DataGasConsumed: dataGasConsumed[i], + DataGasConsumed: daGasL1DataGas, DataGasPrice: dataGasPrice, OverallFee: overallFee, Unit: utils.Ptr(feeUnit), - v0_6Response: v0_6Response, } - if !v0_6Response { - trace := traces[i] - executionResources := trace.TotalExecutionResources() - executionResources.DataAvailability = vm.NewDataAvailability(gasConsumed, dataGasConsumed[i], header.L1DAMode) - traces[i].ExecutionResources = executionResources + trace := traces[i] + executionResources := trace.TotalExecutionResources() + executionResources.DataAvailability = &vm.DataAvailability{ + L1Gas: daGas[i].L1Gas, + L1DataGas: daGas[i].L1DataGas, } + traces[i].ExecutionResources = executionResources result = append(result, SimulatedTransaction{ TransactionTrace: &traces[i], @@ -173,7 +171,7 @@ func (h *Handler) simulateTransactions(id BlockID, transactions []BroadcastedTra }) } - return result, nil + return result, httpHeader, nil } type TransactionExecutionErrorData struct { diff --git a/rpc/simulation_test.go b/rpc/simulation_test.go index 8a35aee4e0..8798bdfa09 100644 --- a/rpc/simulation_test.go +++ b/rpc/simulation_test.go @@ -10,12 +10,13 @@ import ( "github.com/NethermindEth/juno/rpc" "github.com/NethermindEth/juno/utils" "github.com/NethermindEth/juno/vm" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) //nolint:dupl -func TestSimulateTransactionsV0_6(t *testing.T) { +func TestSimulateTransactions(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -34,55 +35,45 @@ func TestSimulateTransactionsV0_6(t *testing.T) { mockReader.EXPECT().HeadsHeader().Return(headsHeader, nil).AnyTimes() t.Run("ok with zero values, skip fee", func(t *testing.T) { + stepsUsed := uint64(123) mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &vm.BlockInfo{ Header: headsHeader, - }, mockState, n, true, false, false, false). - Return([]*felt.Felt{}, []*felt.Felt{}, []vm.TransactionTrace{}, nil) + }, mockState, n, true, false, false). + Return([]*felt.Felt{}, []core.GasConsumed{}, []vm.TransactionTrace{}, stepsUsed, nil) - _, err := handler.SimulateTransactionsV0_6(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipFeeChargeFlag}) + _, httpHeader, err := handler.SimulateTransactions(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipFeeChargeFlag}) require.Nil(t, err) + assert.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), "123") }) t.Run("ok with zero values, skip validate", func(t *testing.T) { + stepsUsed := uint64(123) mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &vm.BlockInfo{ Header: headsHeader, - }, mockState, n, false, true, false, false). - Return([]*felt.Felt{}, []*felt.Felt{}, []vm.TransactionTrace{}, nil) + }, mockState, n, false, true, false). + Return([]*felt.Felt{}, []core.GasConsumed{}, []vm.TransactionTrace{}, stepsUsed, nil) - _, err := handler.SimulateTransactionsV0_6(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipValidateFlag}) + _, httpHeader, err := handler.SimulateTransactions(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipValidateFlag}) require.Nil(t, err) + assert.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), "123") }) t.Run("transaction execution error", func(t *testing.T) { - t.Run("v0_6", func(t *testing.T) { //nolint:dupl + t.Run("v0_7, v0_8", func(t *testing.T) { //nolint:dupl mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &vm.BlockInfo{ Header: headsHeader, - }, mockState, n, false, true, false, false). - Return(nil, nil, nil, vm.TransactionExecutionError{ + }, mockState, n, false, true, false). + Return(nil, nil, nil, uint64(0), vm.TransactionExecutionError{ Index: 44, Cause: errors.New("oops"), }) - _, err := handler.SimulateTransactionsV0_6(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipValidateFlag}) - require.Equal(t, rpc.ErrTransactionExecutionError.CloneWithData(rpc.TransactionExecutionErrorData{ - TransactionIndex: 44, - ExecutionError: "oops", - }), err) - }) - t.Run("v0_7", func(t *testing.T) { //nolint:dupl - mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &vm.BlockInfo{ - Header: headsHeader, - }, mockState, n, false, true, false, true). - Return(nil, nil, nil, vm.TransactionExecutionError{ - Index: 44, - Cause: errors.New("oops"), - }) - - _, err := handler.SimulateTransactions(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipValidateFlag}) + _, httpHeader, err := handler.SimulateTransactions(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipValidateFlag}) require.Equal(t, rpc.ErrTransactionExecutionError.CloneWithData(rpc.TransactionExecutionErrorData{ TransactionIndex: 44, ExecutionError: "oops", }), err) + require.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), "0") }) }) } diff --git a/rpc/trace.go b/rpc/trace.go index 809a8481de..17aa11c68b 100644 --- a/rpc/trace.go +++ b/rpc/trace.go @@ -3,7 +3,9 @@ package rpc import ( "context" "errors" + "net/http" "slices" + "strconv" "github.com/Masterminds/semver/v3" "github.com/NethermindEth/juno/blockchain" @@ -129,18 +131,17 @@ func adaptFeederExecutionResources(resources *starknet.ExecutionResources) *vm.E // // It follows the specification defined here: // https://github.com/starkware-libs/starknet-specs/blob/1ae810e0137cc5d175ace4554892a4f43052be56/api/starknet_trace_api_openrpc.json#L11 -func (h *Handler) TraceTransaction(ctx context.Context, hash felt.Felt) (*vm.TransactionTrace, *jsonrpc.Error) { - return h.traceTransaction(ctx, &hash, false) +func (h *Handler) TraceTransaction(ctx context.Context, hash felt.Felt) (*vm.TransactionTrace, http.Header, *jsonrpc.Error) { + return h.traceTransaction(ctx, &hash) } -func (h *Handler) TraceTransactionV0_6(ctx context.Context, hash felt.Felt) (*vm.TransactionTrace, *jsonrpc.Error) { - return h.traceTransaction(ctx, &hash, true) -} - -func (h *Handler) traceTransaction(ctx context.Context, hash *felt.Felt, v0_6Response bool) (*vm.TransactionTrace, *jsonrpc.Error) { +func (h *Handler) traceTransaction(ctx context.Context, hash *felt.Felt) (*vm.TransactionTrace, http.Header, *jsonrpc.Error) { _, blockHash, _, err := h.bcReader.Receipt(hash) + httpHeader := http.Header{} + httpHeader.Set(ExecutionStepsHeader, "0") + if err != nil { - return nil, ErrTxnHashNotFound + return nil, httpHeader, ErrTxnHashNotFound } var block *core.Block @@ -150,14 +151,14 @@ func (h *Handler) traceTransaction(ctx context.Context, hash *felt.Felt, v0_6Res pending, err = h.bcReader.Pending() if err != nil { // for traceTransaction handlers there is no block not found error - return nil, ErrTxnHashNotFound + return nil, httpHeader, ErrTxnHashNotFound } block = pending.Block } else { block, err = h.bcReader.BlockByHash(blockHash) if err != nil { // for traceTransaction handlers there is no block not found error - return nil, ErrTxnHashNotFound + return nil, httpHeader, ErrTxnHashNotFound } } @@ -165,57 +166,81 @@ func (h *Handler) traceTransaction(ctx context.Context, hash *felt.Felt, v0_6Res return tx.Hash().Equal(hash) }) if txIndex == -1 { - return nil, ErrTxnHashNotFound + return nil, httpHeader, ErrTxnHashNotFound } - traceResults, traceBlockErr := h.traceBlockTransactions(ctx, block, v0_6Response) + traceResults, header, traceBlockErr := h.traceBlockTransactions(ctx, block) if traceBlockErr != nil { - return nil, traceBlockErr + return nil, header, traceBlockErr } - return traceResults[txIndex].TraceRoot, nil + return traceResults[txIndex].TraceRoot, header, nil } -func (h *Handler) TraceBlockTransactions(ctx context.Context, id BlockID) ([]TracedBlockTransaction, *jsonrpc.Error) { +func (h *Handler) TraceBlockTransactions(ctx context.Context, id BlockID) ([]TracedBlockTransaction, http.Header, *jsonrpc.Error) { block, rpcErr := h.blockByID(&id) if rpcErr != nil { - return nil, rpcErr + httpHeader := http.Header{} + httpHeader.Set(ExecutionStepsHeader, "0") + return nil, httpHeader, rpcErr } - return h.traceBlockTransactions(ctx, block, false) + return h.traceBlockTransactions(ctx, block) } -func (h *Handler) TraceBlockTransactionsV0_6(ctx context.Context, id BlockID) ([]TracedBlockTransaction, *jsonrpc.Error) { - block, rpcErr := h.blockByID(&id) - if rpcErr != nil { - return nil, rpcErr - } +//nolint:funlen,gocyclo +func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block) ([]TracedBlockTransaction, http.Header, *jsonrpc.Error) { + httpHeader := http.Header{} + httpHeader.Set(ExecutionStepsHeader, "0") - return h.traceBlockTransactions(ctx, block, true) -} - -func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block, v0_6Response bool, //nolint: gocyclo, funlen -) ([]TracedBlockTransaction, *jsonrpc.Error) { isPending := block.Hash == nil if !isPending { if blockVer, err := core.ParseBlockVersion(block.ProtocolVersion); err != nil { - return nil, ErrUnexpectedError.CloneWithData(err.Error()) - } else if blockVer.Compare(traceFallbackVersion) != 1 && block.ProtocolVersion != excludedVersion { + return nil, httpHeader, ErrUnexpectedError.CloneWithData(err.Error()) + } else if blockVer.LessThanEqual(traceFallbackVersion) && block.ProtocolVersion != excludedVersion { // version <= 0.13.1 and not 0.13.1.1 fetch blocks from feeder gateway - return h.fetchTraces(ctx, block.Hash) + result, err := h.fetchTraces(ctx, block.Hash) + if err != nil { + return nil, httpHeader, err + } + + txDataAvailability := make(map[felt.Felt]vm.DataAvailability, len(block.Receipts)) + for _, receipt := range block.Receipts { + if receipt.ExecutionResources == nil { + continue + } + if receiptDA := receipt.ExecutionResources.DataAvailability; receiptDA != nil { + da := vm.DataAvailability{ + L1Gas: receiptDA.L1Gas, + L1DataGas: receiptDA.L1DataGas, + } + txDataAvailability[*receipt.TransactionHash] = da + } + } + + // add execution resources on root level + for index, trace := range result { + executionResources := trace.TraceRoot.TotalExecutionResources() + // fgw doesn't provide this data in traces endpoint + // some receipts don't have data availability data in this case we don't + da := txDataAvailability[*trace.TransactionHash] + executionResources.DataAvailability = &da + result[index].TraceRoot.ExecutionResources = executionResources + } + + return result, httpHeader, err } if trace, hit := h.blockTraceCache.Get(traceCacheKey{ - blockHash: *block.Hash, - v0_6Response: v0_6Response, + blockHash: *block.Hash, }); hit { - return trace, nil + return trace, httpHeader, nil } } state, closer, err := h.bcReader.StateAtBlockHash(block.ParentHash) if err != nil { - return nil, ErrBlockNotFound + return nil, httpHeader, ErrBlockNotFound } defer h.callAndLogErr(closer, "Failed to close state in traceBlockTransactions") @@ -229,7 +254,7 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block, headState, headStateCloser, err = h.bcReader.HeadState() } if err != nil { - return nil, jsonrpc.Err(jsonrpc.InternalError, err.Error()) + return nil, httpHeader, jsonrpc.Err(jsonrpc.InternalError, err.Error()) } defer h.callAndLogErr(headStateCloser, "Failed to close head state in traceBlockTransactions") @@ -241,7 +266,7 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block, case *core.DeclareTransaction: class, stateErr := headState.Class(tx.ClassHash) if stateErr != nil { - return nil, jsonrpc.Err(jsonrpc.InternalError, stateErr.Error()) + return nil, httpHeader, jsonrpc.Err(jsonrpc.InternalError, stateErr.Error()) } classes = append(classes, class.Class) case *core.L1HandlerTransaction: @@ -252,7 +277,7 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block, blockHashToBeRevealed, err := h.getRevealedBlockHash(block.Number) if err != nil { - return nil, ErrInternal.CloneWithData(err) + return nil, httpHeader, ErrInternal.CloneWithData(err) } network := h.bcReader.Network() header := block.Header @@ -261,49 +286,28 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block, BlockHashToBeRevealed: blockHashToBeRevealed, } - useBlobData := !v0_6Response - overallFees, dataGasConsumed, traces, err := h.vm.Execute(block.Transactions, classes, paidFeesOnL1, &blockInfo, state, network, false, - false, false, useBlobData) + _, daGas, traces, numSteps, err := h.vm.Execute(block.Transactions, classes, paidFeesOnL1, + &blockInfo, state, network, false, false, false) + + httpHeader.Set(ExecutionStepsHeader, strconv.FormatUint(numSteps, 10)) + if err != nil { if errors.Is(err, utils.ErrResourceBusy) { - return nil, ErrInternal.CloneWithData(throttledVMErr) + return nil, httpHeader, ErrInternal.CloneWithData(throttledVMErr) } // Since we are tracing an existing block, we know that there should be no errors during execution. If we encounter any, // report them as unexpected errors - return nil, ErrUnexpectedError.CloneWithData(err.Error()) + return nil, httpHeader, ErrUnexpectedError.CloneWithData(err.Error()) } result := make([]TracedBlockTransaction, 0, len(traces)) for index, trace := range traces { - if !v0_6Response { - feeUnit := feeUnit(block.Transactions[index]) - - gasPrice := header.GasPrice - if feeUnit == FRI { - if gasPrice = header.GasPriceSTRK; gasPrice == nil { - gasPrice = &felt.Zero - } - } - - dataGasPrice := &felt.Zero - if header.L1DataGasPrice != nil { - switch feeUnit { - case FRI: - dataGasPrice = header.L1DataGasPrice.PriceInFri - case WEI: - dataGasPrice = header.L1DataGasPrice.PriceInWei - } - } - - dataGasFee := new(felt.Felt).Mul(dataGasConsumed[index], dataGasPrice) - gasConsumed := new(felt.Felt).Sub(overallFees[index], dataGasFee) - gasConsumed = gasConsumed.Div(gasConsumed, gasPrice) // division by zero felt is zero felt - - executionResources := trace.TotalExecutionResources() - executionResources.DataAvailability = vm.NewDataAvailability(gasConsumed, dataGasConsumed[index], - header.L1DAMode) - traces[index].ExecutionResources = executionResources + executionResources := trace.TotalExecutionResources() + executionResources.DataAvailability = &vm.DataAvailability{ + L1Gas: daGas[index].L1Gas, + L1DataGas: daGas[index].L1DataGas, } + traces[index].ExecutionResources = executionResources result = append(result, TracedBlockTransaction{ TraceRoot: &traces[index], TransactionHash: block.Transactions[index].Hash(), @@ -312,12 +316,11 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block, if !isPending { h.blockTraceCache.Add(traceCacheKey{ - blockHash: *block.Hash, - v0_6Response: v0_6Response, + blockHash: *block.Hash, }, result) } - return result, nil + return result, httpHeader, nil } func (h *Handler) fetchTraces(ctx context.Context, blockHash *felt.Felt) ([]TracedBlockTransaction, *jsonrpc.Error) { @@ -347,14 +350,6 @@ func (h *Handler) fetchTraces(ctx context.Context, blockHash *felt.Felt) ([]Trac // https://github.com/starkware-libs/starknet-specs/blob/e0b76ed0d8d8eba405e182371f9edac8b2bcbc5a/api/starknet_api_openrpc.json#L401-L445 func (h *Handler) Call(funcCall FunctionCall, id BlockID) ([]*felt.Felt, *jsonrpc.Error) { //nolint:gocritic - return h.call(funcCall, id, true) -} - -func (h *Handler) CallV0_6(call FunctionCall, id BlockID) ([]*felt.Felt, *jsonrpc.Error) { //nolint:gocritic - return h.call(call, id, false) -} - -func (h *Handler) call(funcCall FunctionCall, id BlockID, useBlobData bool) ([]*felt.Felt, *jsonrpc.Error) { //nolint:gocritic state, closer, rpcErr := h.stateByBlockID(&id) if rpcErr != nil { return nil, rpcErr @@ -384,7 +379,7 @@ func (h *Handler) call(funcCall FunctionCall, id BlockID, useBlobData bool) ([]* }, &vm.BlockInfo{ Header: header, BlockHashToBeRevealed: blockHashToBeRevealed, - }, state, h.bcReader.Network(), h.callMaxSteps, useBlobData) + }, state, h.bcReader.Network(), h.callMaxSteps) if err != nil { if errors.Is(err, utils.ErrResourceBusy) { return nil, ErrInternal.CloneWithData(throttledVMErr) diff --git a/rpc/trace_test.go b/rpc/trace_test.go index 3721788a68..f1050e5deb 100644 --- a/rpc/trace_test.go +++ b/rpc/trace_test.go @@ -44,12 +44,12 @@ func TestTraceFallback(t *testing.T) { "old block": { hash: "0x3ae41b0f023e53151b0c8ab8b9caafb7005d5f41c9ab260276d5bdc49726279", blockNumber: 0, - want: `[{"trace_root":{"type":"DEPLOY","constructor_invocation":{"contract_address":"0x7b196a359045d4d0c10f73bdf244a9e1205a615dbb754b8df40173364288534","calldata":["0x187d50a5cf3ebd6d4d6fa8e29e4cad0a237759c6416304a25c4ea792ed4bba4","0x42f5af30d6693674296ad87301935d0c159036c3b24af4042ff0270913bf6c6"],"caller_address":"0x0","result":[],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":29}}},"transaction_hash":"0x3fa1bff0c86f34b2eb32c26d12208b6bdb4a5f6a434ac1d4f0e2d1db71bd711"},{"trace_root":{"type":"DEPLOY","constructor_invocation":{"contract_address":"0x64ed79a8ebe97485d3357bbfdf5f6bea0d9db3b5f1feb6e80d564a179122dc6","calldata":["0x5cedec15acd969b0fba39fec9e7d9bd4d0b33f100969ad3a4543039a6f696d4","0xce9801d27b02543f4d88b60aa456860f94ee9f612fc56464abfbdeedc1ab72"],"caller_address":"0x0","result":[],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":29}}},"transaction_hash":"0x154c02cc3165cceadaa32e7238a67061b3a1eac414138c4ebe1408f37fd93eb"},{"trace_root":{"type":"INVOKE","execute_invocation":{"contract_address":"0x64ed79a8ebe97485d3357bbfdf5f6bea0d9db3b5f1feb6e80d564a179122dc6","calldata":["0x17d9c35a8b9a0d4512fa05eafec01c2758a7a5b7ec7b47408a24a4b33124d9b","0x2","0x7f800b5bf79637f8f83f47a8fc4d368b43695c781b22a899f11b5f2faba874a","0x3a7a40d383612b0ad167aec8d90fb07e576e017d07948f63ac318b52511ae93"],"caller_address":"0x0","result":[],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":165,"memory_holes":22,"pedersen_builtin_applications":2,"range_check_builtin_applications":7}}},"transaction_hash":"0x7893675c16da857b7c4229cda449e08a4fe13b07ca817e79d1db02e8a046047"},{"trace_root":{"type":"INVOKE","execute_invocation":{"contract_address":"0x64ed79a8ebe97485d3357bbfdf5f6bea0d9db3b5f1feb6e80d564a179122dc6","calldata":["0x17d9c35a8b9a0d4512fa05eafec01c2758a7a5b7ec7b47408a24a4b33124d9b","0x2","0x7f800b5bf79637f8f83f47a8fc4d368b43695c781b22a899f11b5f2faba874a","0xf140b304e9266c72f1054116dd06d9c1c8e981db7bf34e3c6da99640e9a7c8"],"caller_address":"0x0","result":[],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":165,"memory_holes":22,"pedersen_builtin_applications":2,"range_check_builtin_applications":7}}},"transaction_hash":"0x4a277d67e3f42c4a343854081d1e2e9e425f1323255e4486d2badb37a1d8630"}]`, + want: `[{"trace_root":{"type":"DEPLOY","constructor_invocation":{"contract_address":"0x7b196a359045d4d0c10f73bdf244a9e1205a615dbb754b8df40173364288534","calldata":["0x187d50a5cf3ebd6d4d6fa8e29e4cad0a237759c6416304a25c4ea792ed4bba4","0x42f5af30d6693674296ad87301935d0c159036c3b24af4042ff0270913bf6c6"],"caller_address":"0x0","result":[],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":29}},"execution_resources":{"steps":29,"data_availability":{"l1_gas":1,"l1_data_gas":2}}},"transaction_hash":"0x3fa1bff0c86f34b2eb32c26d12208b6bdb4a5f6a434ac1d4f0e2d1db71bd711"},{"trace_root":{"type":"DEPLOY","constructor_invocation":{"contract_address":"0x64ed79a8ebe97485d3357bbfdf5f6bea0d9db3b5f1feb6e80d564a179122dc6","calldata":["0x5cedec15acd969b0fba39fec9e7d9bd4d0b33f100969ad3a4543039a6f696d4","0xce9801d27b02543f4d88b60aa456860f94ee9f612fc56464abfbdeedc1ab72"],"caller_address":"0x0","result":[],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":29}},"execution_resources":{"steps":29,"data_availability":{"l1_gas":2,"l1_data_gas":3}}},"transaction_hash":"0x154c02cc3165cceadaa32e7238a67061b3a1eac414138c4ebe1408f37fd93eb"},{"trace_root":{"type":"INVOKE","execute_invocation":{"contract_address":"0x64ed79a8ebe97485d3357bbfdf5f6bea0d9db3b5f1feb6e80d564a179122dc6","calldata":["0x17d9c35a8b9a0d4512fa05eafec01c2758a7a5b7ec7b47408a24a4b33124d9b","0x2","0x7f800b5bf79637f8f83f47a8fc4d368b43695c781b22a899f11b5f2faba874a","0x3a7a40d383612b0ad167aec8d90fb07e576e017d07948f63ac318b52511ae93"],"caller_address":"0x0","result":[],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":165,"memory_holes":22,"pedersen_builtin_applications":2,"range_check_builtin_applications":7}},"execution_resources":{"steps":165,"memory_holes":22,"pedersen_builtin_applications":2,"range_check_builtin_applications":7,"data_availability":{"l1_gas":3,"l1_data_gas":4}}},"transaction_hash":"0x7893675c16da857b7c4229cda449e08a4fe13b07ca817e79d1db02e8a046047"},{"trace_root":{"type":"INVOKE","execute_invocation":{"contract_address":"0x64ed79a8ebe97485d3357bbfdf5f6bea0d9db3b5f1feb6e80d564a179122dc6","calldata":["0x17d9c35a8b9a0d4512fa05eafec01c2758a7a5b7ec7b47408a24a4b33124d9b","0x2","0x7f800b5bf79637f8f83f47a8fc4d368b43695c781b22a899f11b5f2faba874a","0xf140b304e9266c72f1054116dd06d9c1c8e981db7bf34e3c6da99640e9a7c8"],"caller_address":"0x0","result":[],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":165,"memory_holes":22,"pedersen_builtin_applications":2,"range_check_builtin_applications":7}},"execution_resources":{"steps":165,"memory_holes":22,"pedersen_builtin_applications":2,"range_check_builtin_applications":7,"data_availability":{"l1_gas":4,"l1_data_gas":5}}},"transaction_hash":"0x4a277d67e3f42c4a343854081d1e2e9e425f1323255e4486d2badb37a1d8630"}]`, }, "newer block": { hash: "0xe3828bd9154ab385e2cbb95b3b650365fb3c6a4321660d98ce8b0a9194f9a3", blockNumber: 300000, - want: `[{"trace_root":{"type":"INVOKE","validate_invocation":{"contract_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","entry_point_selector":"0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775","calldata":["0x1","0x332299dc083f3778122e5b7762bc9d399da18fefe93769aee67bb49f51c8d2","0x2d7cf5d5a324a320f9f37804b1615a533fde487400b41af80f13f7ac5581325","0x0","0x4","0x4","0xaf35ee8ed700ff132c5d1d298a73becda25ccdf9","0x2","0x6cd852fe1b2bbd8587bb0aaeb09813436c57c8ce21e75651e317273a1f22228","0x58feb991988e53fffcba71f6df23c803fb062f1b3bab126d2c9ce574255b36e"],"caller_address":"0x0","class_hash":"0x646a72e2aab2fca75d713fbe4a58f2d12cbd64105621b89dc9ce7045b5bf02b","entry_point_type":"EXTERNAL","call_type":"CALL","result":[],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":89,"range_check_builtin_applications":2,"ecdsa_builtin_applications":1}},"execute_invocation":{"contract_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","entry_point_selector":"0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad","calldata":["0x1","0x332299dc083f3778122e5b7762bc9d399da18fefe93769aee67bb49f51c8d2","0x2d7cf5d5a324a320f9f37804b1615a533fde487400b41af80f13f7ac5581325","0x0","0x4","0x4","0xaf35ee8ed700ff132c5d1d298a73becda25ccdf9","0x2","0x6cd852fe1b2bbd8587bb0aaeb09813436c57c8ce21e75651e317273a1f22228","0x58feb991988e53fffcba71f6df23c803fb062f1b3bab126d2c9ce574255b36e"],"caller_address":"0x0","class_hash":"0x646a72e2aab2fca75d713fbe4a58f2d12cbd64105621b89dc9ce7045b5bf02b","entry_point_type":"EXTERNAL","call_type":"CALL","result":[],"calls":[{"contract_address":"0x332299dc083f3778122e5b7762bc9d399da18fefe93769aee67bb49f51c8d2","entry_point_selector":"0x2d7cf5d5a324a320f9f37804b1615a533fde487400b41af80f13f7ac5581325","calldata":["0xaf35ee8ed700ff132c5d1d298a73becda25ccdf9","0x2","0x6cd852fe1b2bbd8587bb0aaeb09813436c57c8ce21e75651e317273a1f22228","0x58feb991988e53fffcba71f6df23c803fb062f1b3bab126d2c9ce574255b36e"],"caller_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","class_hash":"0x165e7db96ab97a63c621229617a6d49633737238673477a54720e4c952f2c7e","entry_point_type":"EXTERNAL","call_type":"CALL","result":[],"calls":[],"events":[],"messages":[{"order":0,"to_address":"0xAf35eE8eD700ff132C5d1d298A73BECdA25ccDF9","payload":["0x6cd852fe1b2bbd8587bb0aaeb09813436c57c8ce21e75651e317273a1f22228","0x58feb991988e53fffcba71f6df23c803fb062f1b3bab126d2c9ce574255b36e"]}],"execution_resources":{"steps":233,"memory_holes":1,"range_check_builtin_applications":5}}],"events":[],"messages":[],"execution_resources":{"steps":374,"memory_holes":4,"range_check_builtin_applications":7}},"fee_transfer_invocation":{"contract_address":"0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7","entry_point_selector":"0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e","calldata":["0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8","0x127089df3a1984","0x0"],"caller_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","class_hash":"0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3","entry_point_type":"EXTERNAL","call_type":"CALL","result":["0x1"],"calls":[{"contract_address":"0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7","entry_point_selector":"0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e","calldata":["0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8","0x127089df3a1984","0x0"],"caller_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","class_hash":"0x28d7d394810ad8c52741ad8f7564717fd02c10ced68657a81d0b6710ce22079","entry_point_type":"EXTERNAL","call_type":"DELEGATE","result":["0x1"],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":488,"memory_holes":40,"pedersen_builtin_applications":4,"range_check_builtin_applications":21}}],"events":[],"messages":[],"execution_resources":{"steps":548,"memory_holes":40,"pedersen_builtin_applications":4,"range_check_builtin_applications":21}}},"transaction_hash":"0x2a648ab1aa6847eb38507fc842e050f256562bf87b26083c332f3f21318c2c3"},{"trace_root":{"type":"INVOKE","validate_invocation":{"contract_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","entry_point_selector":"0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775","calldata":["0x1","0x5f9211b05c9609d54a8bf5f9cfa4e2cd5a3cab3b5d79682c585575495a15dd1","0x317eb442b72a9fae758d4fb26830ed0d9f31c8e7da4dbff4e8c59ea6a158e7f","0x0","0x4","0x4","0x447379c077035ef4f442411d0407ce9aa66c558f0060137f6455f4f230eabeb","0x2","0x6811b7755a7dd0ec1fb6f51a883e3f255368e2dfd497b5f6480c00cf9cd5a2e","0x23b9e26720dd7aaf98c7cea56499f48f75dc1d4123f7e2d6c23bfc4d5f4a336"],"caller_address":"0x0","class_hash":"0x646a72e2aab2fca75d713fbe4a58f2d12cbd64105621b89dc9ce7045b5bf02b","entry_point_type":"EXTERNAL","call_type":"CALL","result":[],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":89,"range_check_builtin_applications":2,"ecdsa_builtin_applications":1}},"execute_invocation":{"contract_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","entry_point_selector":"0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad","calldata":["0x1","0x5f9211b05c9609d54a8bf5f9cfa4e2cd5a3cab3b5d79682c585575495a15dd1","0x317eb442b72a9fae758d4fb26830ed0d9f31c8e7da4dbff4e8c59ea6a158e7f","0x0","0x4","0x4","0x447379c077035ef4f442411d0407ce9aa66c558f0060137f6455f4f230eabeb","0x2","0x6811b7755a7dd0ec1fb6f51a883e3f255368e2dfd497b5f6480c00cf9cd5a2e","0x23b9e26720dd7aaf98c7cea56499f48f75dc1d4123f7e2d6c23bfc4d5f4a336"],"caller_address":"0x0","class_hash":"0x646a72e2aab2fca75d713fbe4a58f2d12cbd64105621b89dc9ce7045b5bf02b","entry_point_type":"EXTERNAL","call_type":"CALL","result":[],"calls":[{"contract_address":"0x5f9211b05c9609d54a8bf5f9cfa4e2cd5a3cab3b5d79682c585575495a15dd1","entry_point_selector":"0x317eb442b72a9fae758d4fb26830ed0d9f31c8e7da4dbff4e8c59ea6a158e7f","calldata":["0x447379c077035ef4f442411d0407ce9aa66c558f0060137f6455f4f230eabeb","0x2","0x6811b7755a7dd0ec1fb6f51a883e3f255368e2dfd497b5f6480c00cf9cd5a2e","0x23b9e26720dd7aaf98c7cea56499f48f75dc1d4123f7e2d6c23bfc4d5f4a336"],"caller_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","class_hash":"0x13abfd2f333f9c69f690f1569140cdae25f6f66e3f371c9cbb998b65f664a85","entry_point_type":"EXTERNAL","call_type":"CALL","result":[],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":166,"memory_holes":22,"pedersen_builtin_applications":2,"range_check_builtin_applications":7}}],"events":[],"messages":[],"execution_resources":{"steps":307,"memory_holes":25,"pedersen_builtin_applications":2,"range_check_builtin_applications":9}},"fee_transfer_invocation":{"contract_address":"0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7","entry_point_selector":"0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e","calldata":["0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8","0x3b2d25cd7bccc","0x0"],"caller_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","class_hash":"0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3","entry_point_type":"EXTERNAL","call_type":"CALL","result":["0x1"],"calls":[{"contract_address":"0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7","entry_point_selector":"0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e","calldata":["0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8","0x3b2d25cd7bccc","0x0"],"caller_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","class_hash":"0x28d7d394810ad8c52741ad8f7564717fd02c10ced68657a81d0b6710ce22079","entry_point_type":"EXTERNAL","call_type":"DELEGATE","result":["0x1"],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":488,"memory_holes":40,"pedersen_builtin_applications":4,"range_check_builtin_applications":21}}],"events":[],"messages":[],"execution_resources":{"steps":548,"memory_holes":40,"pedersen_builtin_applications":4,"range_check_builtin_applications":21}}},"transaction_hash":"0xbc984e8e1fe594dd518a3a51db4f338437a5d2fbdda772d4426b532a67ffff"}]`, + want: `[{"trace_root":{"type":"INVOKE","validate_invocation":{"contract_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","entry_point_selector":"0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775","calldata":["0x1","0x332299dc083f3778122e5b7762bc9d399da18fefe93769aee67bb49f51c8d2","0x2d7cf5d5a324a320f9f37804b1615a533fde487400b41af80f13f7ac5581325","0x0","0x4","0x4","0xaf35ee8ed700ff132c5d1d298a73becda25ccdf9","0x2","0x6cd852fe1b2bbd8587bb0aaeb09813436c57c8ce21e75651e317273a1f22228","0x58feb991988e53fffcba71f6df23c803fb062f1b3bab126d2c9ce574255b36e"],"caller_address":"0x0","class_hash":"0x646a72e2aab2fca75d713fbe4a58f2d12cbd64105621b89dc9ce7045b5bf02b","entry_point_type":"EXTERNAL","call_type":"CALL","result":[],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":89,"range_check_builtin_applications":2,"ecdsa_builtin_applications":1}},"execute_invocation":{"contract_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","entry_point_selector":"0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad","calldata":["0x1","0x332299dc083f3778122e5b7762bc9d399da18fefe93769aee67bb49f51c8d2","0x2d7cf5d5a324a320f9f37804b1615a533fde487400b41af80f13f7ac5581325","0x0","0x4","0x4","0xaf35ee8ed700ff132c5d1d298a73becda25ccdf9","0x2","0x6cd852fe1b2bbd8587bb0aaeb09813436c57c8ce21e75651e317273a1f22228","0x58feb991988e53fffcba71f6df23c803fb062f1b3bab126d2c9ce574255b36e"],"caller_address":"0x0","class_hash":"0x646a72e2aab2fca75d713fbe4a58f2d12cbd64105621b89dc9ce7045b5bf02b","entry_point_type":"EXTERNAL","call_type":"CALL","result":[],"calls":[{"contract_address":"0x332299dc083f3778122e5b7762bc9d399da18fefe93769aee67bb49f51c8d2","entry_point_selector":"0x2d7cf5d5a324a320f9f37804b1615a533fde487400b41af80f13f7ac5581325","calldata":["0xaf35ee8ed700ff132c5d1d298a73becda25ccdf9","0x2","0x6cd852fe1b2bbd8587bb0aaeb09813436c57c8ce21e75651e317273a1f22228","0x58feb991988e53fffcba71f6df23c803fb062f1b3bab126d2c9ce574255b36e"],"caller_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","class_hash":"0x165e7db96ab97a63c621229617a6d49633737238673477a54720e4c952f2c7e","entry_point_type":"EXTERNAL","call_type":"CALL","result":[],"calls":[],"events":[],"messages":[{"order":0,"to_address":"0xAf35eE8eD700ff132C5d1d298A73BECdA25ccDF9","payload":["0x6cd852fe1b2bbd8587bb0aaeb09813436c57c8ce21e75651e317273a1f22228","0x58feb991988e53fffcba71f6df23c803fb062f1b3bab126d2c9ce574255b36e"]}],"execution_resources":{"steps":233,"memory_holes":1,"range_check_builtin_applications":5}}],"events":[],"messages":[],"execution_resources":{"steps":374,"memory_holes":4,"range_check_builtin_applications":7}},"fee_transfer_invocation":{"contract_address":"0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7","entry_point_selector":"0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e","calldata":["0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8","0x127089df3a1984","0x0"],"caller_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","class_hash":"0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3","entry_point_type":"EXTERNAL","call_type":"CALL","result":["0x1"],"calls":[{"contract_address":"0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7","entry_point_selector":"0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e","calldata":["0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8","0x127089df3a1984","0x0"],"caller_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","class_hash":"0x28d7d394810ad8c52741ad8f7564717fd02c10ced68657a81d0b6710ce22079","entry_point_type":"EXTERNAL","call_type":"DELEGATE","result":["0x1"],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":488,"memory_holes":40,"pedersen_builtin_applications":4,"range_check_builtin_applications":21}}],"events":[],"messages":[],"execution_resources":{"steps":548,"memory_holes":40,"pedersen_builtin_applications":4,"range_check_builtin_applications":21}},"execution_resources":{"steps":1011,"memory_holes":44,"pedersen_builtin_applications":4,"range_check_builtin_applications":30,"ecdsa_builtin_applications":1,"data_availability":{"l1_gas":1,"l1_data_gas":2}}},"transaction_hash":"0x2a648ab1aa6847eb38507fc842e050f256562bf87b26083c332f3f21318c2c3"},{"trace_root":{"type":"INVOKE","validate_invocation":{"contract_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","entry_point_selector":"0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775","calldata":["0x1","0x5f9211b05c9609d54a8bf5f9cfa4e2cd5a3cab3b5d79682c585575495a15dd1","0x317eb442b72a9fae758d4fb26830ed0d9f31c8e7da4dbff4e8c59ea6a158e7f","0x0","0x4","0x4","0x447379c077035ef4f442411d0407ce9aa66c558f0060137f6455f4f230eabeb","0x2","0x6811b7755a7dd0ec1fb6f51a883e3f255368e2dfd497b5f6480c00cf9cd5a2e","0x23b9e26720dd7aaf98c7cea56499f48f75dc1d4123f7e2d6c23bfc4d5f4a336"],"caller_address":"0x0","class_hash":"0x646a72e2aab2fca75d713fbe4a58f2d12cbd64105621b89dc9ce7045b5bf02b","entry_point_type":"EXTERNAL","call_type":"CALL","result":[],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":89,"range_check_builtin_applications":2,"ecdsa_builtin_applications":1}},"execute_invocation":{"contract_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","entry_point_selector":"0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad","calldata":["0x1","0x5f9211b05c9609d54a8bf5f9cfa4e2cd5a3cab3b5d79682c585575495a15dd1","0x317eb442b72a9fae758d4fb26830ed0d9f31c8e7da4dbff4e8c59ea6a158e7f","0x0","0x4","0x4","0x447379c077035ef4f442411d0407ce9aa66c558f0060137f6455f4f230eabeb","0x2","0x6811b7755a7dd0ec1fb6f51a883e3f255368e2dfd497b5f6480c00cf9cd5a2e","0x23b9e26720dd7aaf98c7cea56499f48f75dc1d4123f7e2d6c23bfc4d5f4a336"],"caller_address":"0x0","class_hash":"0x646a72e2aab2fca75d713fbe4a58f2d12cbd64105621b89dc9ce7045b5bf02b","entry_point_type":"EXTERNAL","call_type":"CALL","result":[],"calls":[{"contract_address":"0x5f9211b05c9609d54a8bf5f9cfa4e2cd5a3cab3b5d79682c585575495a15dd1","entry_point_selector":"0x317eb442b72a9fae758d4fb26830ed0d9f31c8e7da4dbff4e8c59ea6a158e7f","calldata":["0x447379c077035ef4f442411d0407ce9aa66c558f0060137f6455f4f230eabeb","0x2","0x6811b7755a7dd0ec1fb6f51a883e3f255368e2dfd497b5f6480c00cf9cd5a2e","0x23b9e26720dd7aaf98c7cea56499f48f75dc1d4123f7e2d6c23bfc4d5f4a336"],"caller_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","class_hash":"0x13abfd2f333f9c69f690f1569140cdae25f6f66e3f371c9cbb998b65f664a85","entry_point_type":"EXTERNAL","call_type":"CALL","result":[],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":166,"memory_holes":22,"pedersen_builtin_applications":2,"range_check_builtin_applications":7}}],"events":[],"messages":[],"execution_resources":{"steps":307,"memory_holes":25,"pedersen_builtin_applications":2,"range_check_builtin_applications":9}},"fee_transfer_invocation":{"contract_address":"0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7","entry_point_selector":"0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e","calldata":["0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8","0x3b2d25cd7bccc","0x0"],"caller_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","class_hash":"0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3","entry_point_type":"EXTERNAL","call_type":"CALL","result":["0x1"],"calls":[{"contract_address":"0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7","entry_point_selector":"0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e","calldata":["0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8","0x3b2d25cd7bccc","0x0"],"caller_address":"0x58b7ee817bd2978c7657d05d3131e83e301ed1aa79d5ad16f01925fd52d1da7","class_hash":"0x28d7d394810ad8c52741ad8f7564717fd02c10ced68657a81d0b6710ce22079","entry_point_type":"EXTERNAL","call_type":"DELEGATE","result":["0x1"],"calls":[],"events":[],"messages":[],"execution_resources":{"steps":488,"memory_holes":40,"pedersen_builtin_applications":4,"range_check_builtin_applications":21}}],"events":[],"messages":[],"execution_resources":{"steps":548,"memory_holes":40,"pedersen_builtin_applications":4,"range_check_builtin_applications":21}},"execution_resources":{"steps":944,"memory_holes":65,"pedersen_builtin_applications":6,"range_check_builtin_applications":32,"ecdsa_builtin_applications":1,"data_availability":{"l1_gas":2,"l1_data_gas":3}}},"transaction_hash":"0xbc984e8e1fe594dd518a3a51db4f338437a5d2fbdda772d4426b532a67ffff"}]`, }, } @@ -59,12 +59,14 @@ func TestTraceFallback(t *testing.T) { return mockReader.BlockByNumber(test.blockNumber) }).Times(2) handler := rpc.New(mockReader, nil, nil, "", nil) - _, jErr := handler.TraceBlockTransactions(context.Background(), rpc.BlockID{Number: test.blockNumber}) + _, httpHeader, jErr := handler.TraceBlockTransactions(context.Background(), rpc.BlockID{Number: test.blockNumber}) require.Equal(t, rpc.ErrInternal.Code, jErr.Code) + assert.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), "0") handler = handler.WithFeeder(client) - trace, jErr := handler.TraceBlockTransactions(context.Background(), rpc.BlockID{Number: test.blockNumber}) + trace, httpHeader, jErr := handler.TraceBlockTransactions(context.Background(), rpc.BlockID{Number: test.blockNumber}) require.Nil(t, jErr) + assert.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), "0") jsonStr, err := json.Marshal(trace) require.NoError(t, err) assert.JSONEq(t, test.want, string(jsonStr)) @@ -86,9 +88,10 @@ func TestTraceTransaction(t *testing.T) { // Receipt() returns error related to db mockReader.EXPECT().Receipt(hash).Return(nil, nil, uint64(0), db.ErrKeyNotFound) - trace, err := handler.TraceTransaction(context.Background(), *hash) + trace, httpHeader, err := handler.TraceTransaction(context.Background(), *hash) assert.Nil(t, trace) assert.Equal(t, rpc.ErrTxnHashNotFound, err) + assert.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), "0") }) t.Run("ok", func(t *testing.T) { hash := utils.HexToFelt(t, "0x37b244ea7dc6b3f9735fba02d183ef0d6807a572dd91a63cc1b14b923c1ac0") @@ -155,13 +158,17 @@ func TestTraceTransaction(t *testing.T) { }`, executionResources) vmTrace := new(vm.TransactionTrace) require.NoError(t, json.Unmarshal(json.RawMessage(vmTraceJSON), vmTrace)) - consumedGas := []*felt.Felt{new(felt.Felt).SetUint64(1)} + consumedGas := []core.GasConsumed{{L1Gas: 1, L1DataGas: 0}} overallFee := []*felt.Felt{new(felt.Felt).SetUint64(1)} + stepsUsed := uint64(123) + stepsUsedStr := "123" mockVM.EXPECT().Execute([]core.Transaction{tx}, []core.Class{declaredClass.Class}, []*felt.Felt{}, - &vm.BlockInfo{Header: header}, gomock.Any(), &utils.Mainnet, false, false, false, true).Return(overallFee, consumedGas, []vm.TransactionTrace{*vmTrace}, nil) + &vm.BlockInfo{Header: header}, gomock.Any(), &utils.Mainnet, false, false, + false).Return(overallFee, consumedGas, []vm.TransactionTrace{*vmTrace}, stepsUsed, nil) - trace, err := handler.TraceTransaction(context.Background(), *hash) + trace, httpHeader, err := handler.TraceTransaction(context.Background(), *hash) require.Nil(t, err) + assert.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), stepsUsedStr) vmTrace.ExecutionResources = &vm.ExecutionResources{ ComputationResources: vm.ComputationResources{ @@ -242,14 +249,17 @@ func TestTraceTransaction(t *testing.T) { }`, executionResources) vmTrace := new(vm.TransactionTrace) require.NoError(t, json.Unmarshal(json.RawMessage(vmTraceJSON), vmTrace)) - consumedGas := []*felt.Felt{new(felt.Felt).SetUint64(1)} + consumedGas := []core.GasConsumed{{L1Gas: 1, L1DataGas: 0}} overallFee := []*felt.Felt{new(felt.Felt).SetUint64(1)} + stepsUsed := uint64(123) + stepsUsedStr := "123" mockVM.EXPECT().Execute([]core.Transaction{tx}, []core.Class{declaredClass.Class}, []*felt.Felt{}, - &vm.BlockInfo{Header: header}, gomock.Any(), &utils.Mainnet, false, false, false, true). - Return(overallFee, consumedGas, []vm.TransactionTrace{*vmTrace}, nil) + &vm.BlockInfo{Header: header}, gomock.Any(), &utils.Mainnet, false, false, false). + Return(overallFee, consumedGas, []vm.TransactionTrace{*vmTrace}, stepsUsed, nil) - trace, err := handler.TraceTransaction(context.Background(), *hash) + trace, httpHeader, err := handler.TraceTransaction(context.Background(), *hash) require.Nil(t, err) + assert.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), stepsUsedStr) vmTrace.ExecutionResources = &vm.ExecutionResources{ // other of fields are zero @@ -261,136 +271,7 @@ func TestTraceTransaction(t *testing.T) { }) } -func TestTraceTransactionV0_6(t *testing.T) { - mockCtrl := gomock.NewController(t) - t.Cleanup(mockCtrl.Finish) - - mockReader := mocks.NewMockReader(mockCtrl) - mockReader.EXPECT().Network().Return(&utils.Mainnet).AnyTimes() - mockVM := mocks.NewMockVM(mockCtrl) - handler := rpc.New(mockReader, nil, mockVM, "", utils.NewNopZapLogger()) - - t.Run("not found", func(t *testing.T) { - hash := utils.HexToFelt(t, "0xBBBB") - // Receipt() returns error related to db - mockReader.EXPECT().Receipt(hash).Return(nil, nil, uint64(0), db.ErrKeyNotFound) - - trace, err := handler.TraceTransactionV0_6(context.Background(), *hash) - assert.Nil(t, trace) - assert.Equal(t, rpc.ErrTxnHashNotFound, err) - }) - t.Run("ok", func(t *testing.T) { - hash := utils.HexToFelt(t, "0x37b244ea7dc6b3f9735fba02d183ef0d6807a572dd91a63cc1b14b923c1ac0") - tx := &core.DeclareTransaction{ - TransactionHash: hash, - ClassHash: utils.HexToFelt(t, "0x000000000"), - } - - header := &core.Header{ - Hash: utils.HexToFelt(t, "0xCAFEBABE"), - ParentHash: utils.HexToFelt(t, "0x0"), - SequencerAddress: utils.HexToFelt(t, "0X111"), - ProtocolVersion: "99.12.3", - } - block := &core.Block{ - Header: header, - Transactions: []core.Transaction{tx}, - } - declaredClass := &core.DeclaredClass{ - At: 3002, - Class: &core.Cairo1Class{}, - } - - mockReader.EXPECT().Receipt(hash).Return(nil, header.Hash, header.Number, nil) - mockReader.EXPECT().BlockByHash(header.Hash).Return(block, nil) - - mockReader.EXPECT().StateAtBlockHash(header.ParentHash).Return(nil, nopCloser, nil) - headState := mocks.NewMockStateHistoryReader(mockCtrl) - headState.EXPECT().Class(tx.ClassHash).Return(declaredClass, nil) - mockReader.EXPECT().HeadState().Return(headState, nopCloser, nil) - - vmTraceJSON := json.RawMessage(`{ - "validate_invocation": {"contract_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", "calldata": ["0x2", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", "0x0", "0x3", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1171593aa5bdadda4d6b0efde6cc94ee7649c3163d5efeb19da6c16d63a2a63", "0x3", "0x10", "0x13", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x1e8480", "0x0", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x420eeb770f7a4", "0x0", "0x40139799e37e4", "0x0", "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x0", "0x0", "0x1", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x64"], "caller_address": "0x0", "class_hash": "0x25ec026985a3bf9d0cc1fe17326b245dfdc3ff89b8fde106542a3ea56c5a918", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": [], "calls": [{"contract_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", "calldata": ["0x2", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", "0x0", "0x3", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1171593aa5bdadda4d6b0efde6cc94ee7649c3163d5efeb19da6c16d63a2a63", "0x3", "0x10", "0x13", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x1e8480", "0x0", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x420eeb770f7a4", "0x0", "0x40139799e37e4", "0x0", "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x0", "0x0", "0x1", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x64"], "caller_address": "0x0", "class_hash": "0x33434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": [], "calls": [], "events": [], "messages": []}], "events": [], "messages": []}, - "execute_invocation": {"contract_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", "calldata": ["0x2", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", "0x0", "0x3", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1171593aa5bdadda4d6b0efde6cc94ee7649c3163d5efeb19da6c16d63a2a63", "0x3", "0x10", "0x13", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x1e8480", "0x0", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x420eeb770f7a4", "0x0", "0x40139799e37e4", "0x0", "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x0", "0x0", "0x1", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x64"], "caller_address": "0x0", "class_hash": "0x25ec026985a3bf9d0cc1fe17326b245dfdc3ff89b8fde106542a3ea56c5a918", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1", "0x1"], "calls": [{"contract_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", "calldata": ["0x2", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", "0x0", "0x3", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1171593aa5bdadda4d6b0efde6cc94ee7649c3163d5efeb19da6c16d63a2a63", "0x3", "0x10", "0x13", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x1e8480", "0x0", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x420eeb770f7a4", "0x0", "0x40139799e37e4", "0x0", "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x0", "0x0", "0x1", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x64"], "caller_address": "0x0", "class_hash": "0x33434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1", "0x1"], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0"], "caller_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "class_hash": "0x52c7ba99c77fc38dd3346beea6c0753c3471f2e3135af5bb837d6c9523fff62", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0"], "caller_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [], "events": [{"keys": ["0x134692b230b9e1ffa39098904722134159652b09c5bc41d88d6698779d228ff"], "data": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0"]}], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "entry_point_selector": "0x1171593aa5bdadda4d6b0efde6cc94ee7649c3163d5efeb19da6c16d63a2a63", "calldata": ["0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x1e8480", "0x0", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x420eeb770f7a4", "0x0", "0x40139799e37e4", "0x0", "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x0", "0x0", "0x1", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x64"], "caller_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "class_hash": "0x5ee939756c1a60b029c594da00e637bf5923bf04a86ff163e877e899c0840eb", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "entry_point_selector": "0x1171593aa5bdadda4d6b0efde6cc94ee7649c3163d5efeb19da6c16d63a2a63", "calldata": ["0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x1e8480", "0x0", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x420eeb770f7a4", "0x0", "0x40139799e37e4", "0x0", "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x0", "0x0", "0x1", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x64"], "caller_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "class_hash": "0x38627c278c0b3cb3c84ddee2c783fb22c3c3a3f0e667ea2b82be0ea2253bce4", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x41b033f4a31df8067c24d1e9b550a2ce75fd4a29e1147af9752174f0e6cb20", "calldata": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x52c7ba99c77fc38dd3346beea6c0753c3471f2e3135af5bb837d6c9523fff62", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x41b033f4a31df8067c24d1e9b550a2ce75fd4a29e1147af9752174f0e6cb20", "calldata": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [], "events": [{"keys": ["0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"], "data": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0"]}], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x1ed6790cdca923073adc728080b06c159d9784cc9bf8fb26181acfdbe4256e6", "entry_point_selector": "0x260bb04cf90403013190e77d7e75f3d40d3d307180364da33c63ff53061d4e8", "calldata": [], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x5ee939756c1a60b029c594da00e637bf5923bf04a86ff163e877e899c0840eb", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x0", "0x0", "0x5"], "calls": [{"contract_address": "0x1ed6790cdca923073adc728080b06c159d9784cc9bf8fb26181acfdbe4256e6", "entry_point_selector": "0x260bb04cf90403013190e77d7e75f3d40d3d307180364da33c63ff53061d4e8", "calldata": [], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x46668cd07d83af5d7158e7cd62c710f1a7573501bcd4f4092c6a4e1ecd2bf61", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x0", "0x0", "0x5"], "calls": [], "events": [], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x2e4263afad30923c891518314c3c95dbe830a16874e8abc5777a9a20b54c76e", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x52c7ba99c77fc38dd3346beea6c0753c3471f2e3135af5bb837d6c9523fff62", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1e8480", "0x0"], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x2e4263afad30923c891518314c3c95dbe830a16874e8abc5777a9a20b54c76e", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1e8480", "0x0"], "calls": [], "events": [], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "entry_point_selector": "0x15543c3708653cda9d418b4ccd3be11368e40636c10c44b18cfe756b6d88b29", "calldata": ["0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x1e8480", "0x0", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x0", "0x0", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f"], "caller_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "class_hash": "0x2ceb6369dba6af865bca639f9f1342dfb1ae4e5d0d0723de98028b812e7cdd2", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": [], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", "calldata": ["0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x1e8480", "0x0"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x52c7ba99c77fc38dd3346beea6c0753c3471f2e3135af5bb837d6c9523fff62", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", "calldata": ["0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x1e8480", "0x0"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [], "events": [{"keys": ["0x134692b230b9e1ffa39098904722134159652b09c5bc41d88d6698779d228ff"], "data": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x1e8480", "0x0"]}], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "entry_point_selector": "0x2c0f7bf2d6cf5304c29171bf493feb222fef84bdaf17805a6574b0c2e8bcc87", "calldata": ["0x1e8480", "0x0", "0x0", "0x0", "0x2", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x648f780a"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x514718bb56ed2a8607554c7d393c2ffd73cbab971c120b00a2ce27cc58dd1c1", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x2", "0x1e8480", "0x0", "0x417c36e4fc16d", "0x0"], "calls": [{"contract_address": "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "entry_point_selector": "0x3c388f7eb137a89061c6f0b6e78bae453202258b0b3c419f8dd9814a547d406", "calldata": [], "caller_address": "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "class_hash": "0x231adde42526bad434ca2eb983efdd64472638702f87f97e6e3c084f264e06f", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x178b60b3a0bcc4aa98", "0xaf07589b7c", "0x648f7422"], "calls": [], "events": [], "messages": []}, {"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x41b033f4a31df8067c24d1e9b550a2ce75fd4a29e1147af9752174f0e6cb20", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "0x1e8480", "0x0"], "caller_address": "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "class_hash": "0x52c7ba99c77fc38dd3346beea6c0753c3471f2e3135af5bb837d6c9523fff62", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x41b033f4a31df8067c24d1e9b550a2ce75fd4a29e1147af9752174f0e6cb20", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "0x1e8480", "0x0"], "caller_address": "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [], "events": [{"keys": ["0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"], "data": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "0x1e8480", "0x0"]}], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "entry_point_selector": "0x15543c3708653cda9d418b4ccd3be11368e40636c10c44b18cfe756b6d88b29", "calldata": ["0x417c36e4fc16d", "0x0", "0x0", "0x0", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f"], "caller_address": "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "class_hash": "0x231adde42526bad434ca2eb983efdd64472638702f87f97e6e3c084f264e06f", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": [], "calls": [{"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x417c36e4fc16d", "0x0"], "caller_address": "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "class_hash": "0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x417c36e4fc16d", "0x0"], "caller_address": "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [], "events": [{"keys": ["0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"], "data": ["0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x417c36e4fc16d", "0x0"]}], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x2e4263afad30923c891518314c3c95dbe830a16874e8abc5777a9a20b54c76e", "calldata": ["0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325"], "caller_address": "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "class_hash": "0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x178b5c9bdd4e74e92b", "0x0"], "calls": [{"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x2e4263afad30923c891518314c3c95dbe830a16874e8abc5777a9a20b54c76e", "calldata": ["0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325"], "caller_address": "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x178b5c9bdd4e74e92b", "0x0"], "calls": [], "events": [], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x2e4263afad30923c891518314c3c95dbe830a16874e8abc5777a9a20b54c76e", "calldata": ["0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325"], "caller_address": "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "class_hash": "0x52c7ba99c77fc38dd3346beea6c0753c3471f2e3135af5bb837d6c9523fff62", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0xaf07771ffc", "0x0"], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x2e4263afad30923c891518314c3c95dbe830a16874e8abc5777a9a20b54c76e", "calldata": ["0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325"], "caller_address": "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0xaf07771ffc", "0x0"], "calls": [], "events": [], "messages": []}], "events": [], "messages": []}], "events": [{"keys": ["0xe14a408baf7f453312eec68e9b7d728ec5337fbdf671f917ee8c80f3255232"], "data": ["0x178b5c9bdd4e74e92b", "0xaf07771ffc"]}, {"keys": ["0xe316f0d9d2a3affa97de1d99bb2aac0538e2666d0d8545545ead241ef0ccab"], "data": ["0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x0", "0x0", "0x1e8480", "0x0", "0x417c36e4fc16d", "0x0", "0x0", "0x0", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f"]}], "messages": []}], "events": [], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x2e4263afad30923c891518314c3c95dbe830a16874e8abc5777a9a20b54c76e", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x417c36e4fc16d", "0x0"], "calls": [{"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x2e4263afad30923c891518314c3c95dbe830a16874e8abc5777a9a20b54c76e", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x417c36e4fc16d", "0x0"], "calls": [], "events": [], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "calldata": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x417c36e4fc16d", "0x0"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "calldata": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x417c36e4fc16d", "0x0"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [], "events": [{"keys": ["0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"], "data": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x417c36e4fc16d", "0x0"]}], "messages": []}], "events": [], "messages": []}], "events": [{"keys": ["0xe316f0d9d2a3affa97de1d99bb2aac0538e2666d0d8545545ead241ef0ccab"], "data": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x1e8480", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x417c36e4fc16d", "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a"]}], "messages": []}], "events": [], "messages": []}], "events": [{"keys": ["0x5ad857f66a5b55f1301ff1ed7e098ac6d4433148f0b72ebc4a2945ab85ad53"], "data": ["0x2fc5e96de394697c1311606c96ec14840e408493fd42cf0c54b73b39d312b81", "0x2", "0x1", "0x1"]}], "messages": []}], "events": [], "messages": []}, - "fee_transfer_invocation": {"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "calldata": ["0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8", "0x2cb6", "0x0"], "caller_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "class_hash": "0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "calldata": ["0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8", "0x2cb6", "0x0"], "caller_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [], "events": [{"keys": ["0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"], "data": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8", "0x2cb6", "0x0"]}], "messages": []}], "events": [], "messages": []}, - "state_diff": { - "storage_diffs": [], - "nonces": [], - "deployed_contracts": [], - "deprecated_declared_classes": [], - "declared_classes": [], - "replaced_classes": [] - } - }`) - vmTrace := new(vm.TransactionTrace) - require.NoError(t, json.Unmarshal(vmTraceJSON, vmTrace)) - mockVM.EXPECT().Execute([]core.Transaction{tx}, []core.Class{declaredClass.Class}, []*felt.Felt{}, - &vm.BlockInfo{Header: header}, gomock.Any(), &utils.Mainnet, false, false, false, false). - Return(nil, nil, []vm.TransactionTrace{*vmTrace}, nil) - - trace, err := handler.TraceTransactionV0_6(context.Background(), *hash) - require.Nil(t, err) - assert.Equal(t, vmTrace, trace) - }) - t.Run("pending block", func(t *testing.T) { - hash := utils.HexToFelt(t, "0xceb6a374aff2bbb3537cf35f50df8634b2354a21") - tx := &core.DeclareTransaction{ - TransactionHash: hash, - ClassHash: utils.HexToFelt(t, "0x000000000"), - } - - header := &core.Header{ - ParentHash: utils.HexToFelt(t, "0x0"), - SequencerAddress: utils.HexToFelt(t, "0X111"), - ProtocolVersion: "99.12.3", - } - require.Nil(t, header.Hash, "hash must be nil for pending block") - - block := &core.Block{ - Header: header, - Transactions: []core.Transaction{tx}, - } - declaredClass := &core.DeclaredClass{ - At: 3002, - Class: &core.Cairo1Class{}, - } - - mockReader.EXPECT().Receipt(hash).Return(nil, header.Hash, header.Number, nil) - mockReader.EXPECT().Pending().Return(blockchain.Pending{ - Block: block, - }, nil) - - mockReader.EXPECT().StateAtBlockHash(header.ParentHash).Return(nil, nopCloser, nil) - headState := mocks.NewMockStateHistoryReader(mockCtrl) - headState.EXPECT().Class(tx.ClassHash).Return(declaredClass, nil) - mockReader.EXPECT().PendingState().Return(headState, nopCloser, nil) - - vmTraceJSON := json.RawMessage(`{ - "validate_invocation": {"contract_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", "calldata": ["0x2", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", "0x0", "0x3", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1171593aa5bdadda4d6b0efde6cc94ee7649c3163d5efeb19da6c16d63a2a63", "0x3", "0x10", "0x13", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x1e8480", "0x0", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x420eeb770f7a4", "0x0", "0x40139799e37e4", "0x0", "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x0", "0x0", "0x1", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x64"], "caller_address": "0x0", "class_hash": "0x25ec026985a3bf9d0cc1fe17326b245dfdc3ff89b8fde106542a3ea56c5a918", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": [], "calls": [{"contract_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", "calldata": ["0x2", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", "0x0", "0x3", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1171593aa5bdadda4d6b0efde6cc94ee7649c3163d5efeb19da6c16d63a2a63", "0x3", "0x10", "0x13", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x1e8480", "0x0", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x420eeb770f7a4", "0x0", "0x40139799e37e4", "0x0", "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x0", "0x0", "0x1", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x64"], "caller_address": "0x0", "class_hash": "0x33434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": [], "calls": [], "events": [], "messages": []}], "events": [], "messages": []}, - "execute_invocation": {"contract_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", "calldata": ["0x2", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", "0x0", "0x3", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1171593aa5bdadda4d6b0efde6cc94ee7649c3163d5efeb19da6c16d63a2a63", "0x3", "0x10", "0x13", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x1e8480", "0x0", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x420eeb770f7a4", "0x0", "0x40139799e37e4", "0x0", "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x0", "0x0", "0x1", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x64"], "caller_address": "0x0", "class_hash": "0x25ec026985a3bf9d0cc1fe17326b245dfdc3ff89b8fde106542a3ea56c5a918", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1", "0x1"], "calls": [{"contract_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", "calldata": ["0x2", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", "0x0", "0x3", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1171593aa5bdadda4d6b0efde6cc94ee7649c3163d5efeb19da6c16d63a2a63", "0x3", "0x10", "0x13", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x1e8480", "0x0", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x420eeb770f7a4", "0x0", "0x40139799e37e4", "0x0", "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x0", "0x0", "0x1", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x64"], "caller_address": "0x0", "class_hash": "0x33434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1", "0x1"], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0"], "caller_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "class_hash": "0x52c7ba99c77fc38dd3346beea6c0753c3471f2e3135af5bb837d6c9523fff62", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0"], "caller_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [], "events": [{"keys": ["0x134692b230b9e1ffa39098904722134159652b09c5bc41d88d6698779d228ff"], "data": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0"]}], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "entry_point_selector": "0x1171593aa5bdadda4d6b0efde6cc94ee7649c3163d5efeb19da6c16d63a2a63", "calldata": ["0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x1e8480", "0x0", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x420eeb770f7a4", "0x0", "0x40139799e37e4", "0x0", "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x0", "0x0", "0x1", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x64"], "caller_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "class_hash": "0x5ee939756c1a60b029c594da00e637bf5923bf04a86ff163e877e899c0840eb", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "entry_point_selector": "0x1171593aa5bdadda4d6b0efde6cc94ee7649c3163d5efeb19da6c16d63a2a63", "calldata": ["0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x1e8480", "0x0", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x420eeb770f7a4", "0x0", "0x40139799e37e4", "0x0", "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x0", "0x0", "0x1", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x64"], "caller_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "class_hash": "0x38627c278c0b3cb3c84ddee2c783fb22c3c3a3f0e667ea2b82be0ea2253bce4", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x41b033f4a31df8067c24d1e9b550a2ce75fd4a29e1147af9752174f0e6cb20", "calldata": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x52c7ba99c77fc38dd3346beea6c0753c3471f2e3135af5bb837d6c9523fff62", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x41b033f4a31df8067c24d1e9b550a2ce75fd4a29e1147af9752174f0e6cb20", "calldata": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [], "events": [{"keys": ["0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"], "data": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x1e8480", "0x0"]}], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x1ed6790cdca923073adc728080b06c159d9784cc9bf8fb26181acfdbe4256e6", "entry_point_selector": "0x260bb04cf90403013190e77d7e75f3d40d3d307180364da33c63ff53061d4e8", "calldata": [], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x5ee939756c1a60b029c594da00e637bf5923bf04a86ff163e877e899c0840eb", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x0", "0x0", "0x5"], "calls": [{"contract_address": "0x1ed6790cdca923073adc728080b06c159d9784cc9bf8fb26181acfdbe4256e6", "entry_point_selector": "0x260bb04cf90403013190e77d7e75f3d40d3d307180364da33c63ff53061d4e8", "calldata": [], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x46668cd07d83af5d7158e7cd62c710f1a7573501bcd4f4092c6a4e1ecd2bf61", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x0", "0x0", "0x5"], "calls": [], "events": [], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x2e4263afad30923c891518314c3c95dbe830a16874e8abc5777a9a20b54c76e", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x52c7ba99c77fc38dd3346beea6c0753c3471f2e3135af5bb837d6c9523fff62", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1e8480", "0x0"], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x2e4263afad30923c891518314c3c95dbe830a16874e8abc5777a9a20b54c76e", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1e8480", "0x0"], "calls": [], "events": [], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "entry_point_selector": "0x15543c3708653cda9d418b4ccd3be11368e40636c10c44b18cfe756b6d88b29", "calldata": ["0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x1e8480", "0x0", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x0", "0x0", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f"], "caller_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "class_hash": "0x2ceb6369dba6af865bca639f9f1342dfb1ae4e5d0d0723de98028b812e7cdd2", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": [], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", "calldata": ["0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x1e8480", "0x0"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x52c7ba99c77fc38dd3346beea6c0753c3471f2e3135af5bb837d6c9523fff62", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c", "calldata": ["0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x1e8480", "0x0"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [], "events": [{"keys": ["0x134692b230b9e1ffa39098904722134159652b09c5bc41d88d6698779d228ff"], "data": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x1e8480", "0x0"]}], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "entry_point_selector": "0x2c0f7bf2d6cf5304c29171bf493feb222fef84bdaf17805a6574b0c2e8bcc87", "calldata": ["0x1e8480", "0x0", "0x0", "0x0", "0x2", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x648f780a"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x514718bb56ed2a8607554c7d393c2ffd73cbab971c120b00a2ce27cc58dd1c1", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x2", "0x1e8480", "0x0", "0x417c36e4fc16d", "0x0"], "calls": [{"contract_address": "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "entry_point_selector": "0x3c388f7eb137a89061c6f0b6e78bae453202258b0b3c419f8dd9814a547d406", "calldata": [], "caller_address": "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "class_hash": "0x231adde42526bad434ca2eb983efdd64472638702f87f97e6e3c084f264e06f", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x178b60b3a0bcc4aa98", "0xaf07589b7c", "0x648f7422"], "calls": [], "events": [], "messages": []}, {"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x41b033f4a31df8067c24d1e9b550a2ce75fd4a29e1147af9752174f0e6cb20", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "0x1e8480", "0x0"], "caller_address": "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "class_hash": "0x52c7ba99c77fc38dd3346beea6c0753c3471f2e3135af5bb837d6c9523fff62", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x41b033f4a31df8067c24d1e9b550a2ce75fd4a29e1147af9752174f0e6cb20", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "0x1e8480", "0x0"], "caller_address": "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [], "events": [{"keys": ["0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"], "data": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "0x1e8480", "0x0"]}], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "entry_point_selector": "0x15543c3708653cda9d418b4ccd3be11368e40636c10c44b18cfe756b6d88b29", "calldata": ["0x417c36e4fc16d", "0x0", "0x0", "0x0", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f"], "caller_address": "0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "class_hash": "0x231adde42526bad434ca2eb983efdd64472638702f87f97e6e3c084f264e06f", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": [], "calls": [{"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x417c36e4fc16d", "0x0"], "caller_address": "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "class_hash": "0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x417c36e4fc16d", "0x0"], "caller_address": "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [], "events": [{"keys": ["0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"], "data": ["0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0x417c36e4fc16d", "0x0"]}], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x2e4263afad30923c891518314c3c95dbe830a16874e8abc5777a9a20b54c76e", "calldata": ["0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325"], "caller_address": "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "class_hash": "0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x178b5c9bdd4e74e92b", "0x0"], "calls": [{"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x2e4263afad30923c891518314c3c95dbe830a16874e8abc5777a9a20b54c76e", "calldata": ["0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325"], "caller_address": "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x178b5c9bdd4e74e92b", "0x0"], "calls": [], "events": [], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x2e4263afad30923c891518314c3c95dbe830a16874e8abc5777a9a20b54c76e", "calldata": ["0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325"], "caller_address": "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "class_hash": "0x52c7ba99c77fc38dd3346beea6c0753c3471f2e3135af5bb837d6c9523fff62", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0xaf07771ffc", "0x0"], "calls": [{"contract_address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "entry_point_selector": "0x2e4263afad30923c891518314c3c95dbe830a16874e8abc5777a9a20b54c76e", "calldata": ["0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325"], "caller_address": "0x23c72abdf49dffc85ae3ede714f2168ad384cc67d08524732acea90df325", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0xaf07771ffc", "0x0"], "calls": [], "events": [], "messages": []}], "events": [], "messages": []}], "events": [{"keys": ["0xe14a408baf7f453312eec68e9b7d728ec5337fbdf671f917ee8c80f3255232"], "data": ["0x178b5c9bdd4e74e92b", "0xaf07771ffc"]}, {"keys": ["0xe316f0d9d2a3affa97de1d99bb2aac0538e2666d0d8545545ead241ef0ccab"], "data": ["0x7a6f98c03379b9513ca84cca1373ff452a7462a3b61598f0af5bb27ad7f76d1", "0x0", "0x0", "0x1e8480", "0x0", "0x417c36e4fc16d", "0x0", "0x0", "0x0", "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f"]}], "messages": []}], "events": [], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x2e4263afad30923c891518314c3c95dbe830a16874e8abc5777a9a20b54c76e", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x417c36e4fc16d", "0x0"], "calls": [{"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x2e4263afad30923c891518314c3c95dbe830a16874e8abc5777a9a20b54c76e", "calldata": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x417c36e4fc16d", "0x0"], "calls": [], "events": [], "messages": []}], "events": [], "messages": []}, {"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "calldata": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x417c36e4fc16d", "0x0"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "calldata": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x417c36e4fc16d", "0x0"], "caller_address": "0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [], "events": [{"keys": ["0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"], "data": ["0x4270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f", "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x417c36e4fc16d", "0x0"]}], "messages": []}], "events": [], "messages": []}], "events": [{"keys": ["0xe316f0d9d2a3affa97de1d99bb2aac0538e2666d0d8545545ead241ef0ccab"], "data": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x1e8480", "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x417c36e4fc16d", "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a"]}], "messages": []}], "events": [], "messages": []}], "events": [{"keys": ["0x5ad857f66a5b55f1301ff1ed7e098ac6d4433148f0b72ebc4a2945ab85ad53"], "data": ["0x2fc5e96de394697c1311606c96ec14840e408493fd42cf0c54b73b39d312b81", "0x2", "0x1", "0x1"]}], "messages": []}], "events": [], "messages": []}, - "fee_transfer_invocation": {"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "calldata": ["0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8", "0x2cb6", "0x0"], "caller_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "class_hash": "0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "calldata": ["0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8", "0x2cb6", "0x0"], "caller_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [], "events": [{"keys": ["0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"], "data": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8", "0x2cb6", "0x0"]}], "messages": []}], "events": [], "messages": []}, - "state_diff": { - "storage_diffs": [], - "nonces": [], - "deployed_contracts": [], - "deprecated_declared_classes": [], - "declared_classes": [], - "replaced_classes": [] - } - }`) - vmTrace := new(vm.TransactionTrace) - require.NoError(t, json.Unmarshal(vmTraceJSON, vmTrace)) - mockVM.EXPECT().Execute([]core.Transaction{tx}, []core.Class{declaredClass.Class}, []*felt.Felt{}, - &vm.BlockInfo{Header: header}, gomock.Any(), &utils.Mainnet, false, false, false, false). - Return(nil, nil, []vm.TransactionTrace{*vmTrace}, nil) - - trace, err := handler.TraceTransactionV0_6(context.Background(), *hash) - require.Nil(t, err) - assert.Equal(t, vmTrace, trace) - }) -} - -func TestTraceBlockTransactionsV0_6(t *testing.T) { +func TestTraceBlockTransactions(t *testing.T) { errTests := map[string]rpc.BlockID{ "latest": {Latest: true}, "pending": {Pending: true}, @@ -405,8 +286,9 @@ func TestTraceBlockTransactionsV0_6(t *testing.T) { chain := blockchain.New(pebble.NewMemTest(t), n) handler := rpc.New(chain, nil, nil, "", log) - update, rpcErr := handler.TraceBlockTransactions(context.Background(), id) + update, httpHeader, rpcErr := handler.TraceBlockTransactions(context.Background(), id) assert.Nil(t, update) + assert.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), "0") assert.Equal(t, rpc.ErrBlockNotFound, rpcErr) }) } @@ -456,9 +338,9 @@ func TestTraceBlockTransactionsV0_6(t *testing.T) { paidL1Fees := []*felt.Felt{(&felt.Felt{}).SetUint64(1)} vmTraceJSON := json.RawMessage(`{ - "validate_invocation": {}, - "execute_invocation": {}, - "fee_transfer_invocation": {}, + "validate_invocation": {"execution_resources":{}}, + "execute_invocation": {"execution_resources":{}}, + "fee_transfer_invocation": {"execution_resources":{}}, "state_diff": { "storage_diffs": [], "nonces": [], @@ -469,17 +351,25 @@ func TestTraceBlockTransactionsV0_6(t *testing.T) { } }`) vmTrace := vm.TransactionTrace{} + stepsUsed := uint64(123) + stepsUsedStr := "123" require.NoError(t, json.Unmarshal(vmTraceJSON, &vmTrace)) mockVM.EXPECT().Execute(block.Transactions, []core.Class{declaredClass.Class}, paidL1Fees, &vm.BlockInfo{Header: header}, - gomock.Any(), n, false, false, false, false). - Return(nil, nil, []vm.TransactionTrace{vmTrace, vmTrace}, nil) + gomock.Any(), n, false, false, false). + Return(nil, []core.GasConsumed{{}, {}}, []vm.TransactionTrace{vmTrace, vmTrace}, stepsUsed, nil) - result, err := handler.TraceBlockTransactionsV0_6(context.Background(), rpc.BlockID{Hash: blockHash}) + result, httpHeader, err := handler.TraceBlockTransactions(context.Background(), rpc.BlockID{Hash: blockHash}) require.Nil(t, err) + assert.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), stepsUsedStr) assert.Equal(t, &vm.TransactionTrace{ - ValidateInvocation: &vm.FunctionInvocation{}, - ExecuteInvocation: &vm.ExecuteInvocation{}, - FeeTransferInvocation: &vm.FunctionInvocation{}, + ValidateInvocation: &vm.FunctionInvocation{ExecutionResources: &vm.ExecutionResources{}}, + ExecuteInvocation: &vm.ExecuteInvocation{FunctionInvocation: &vm.FunctionInvocation{ + ExecutionResources: &vm.ExecutionResources{}, + }}, + FeeTransferInvocation: &vm.FunctionInvocation{ExecutionResources: &vm.ExecutionResources{}}, + ExecutionResources: &vm.ExecutionResources{ + DataAvailability: &vm.DataAvailability{}, + }, StateDiff: &vm.StateDiff{ StorageDiffs: []vm.StorageDiff{}, Nonces: []vm.Nonce{}, @@ -523,9 +413,10 @@ func TestTraceBlockTransactionsV0_6(t *testing.T) { mockReader.EXPECT().HeadState().Return(headState, nopCloser, nil) vmTraceJSON := json.RawMessage(`{ - "validate_invocation":{"entry_point_selector":"0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895","calldata":["0x25ec026985a3bf9d0cc1fe17326b245dfdc3ff89b8fde106542a3ea56c5a918","0x322258135d04971e96b747a5551061aa046ad5d8be11a35c67029d96b23f98","0x33434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2","0x79dc0da7c54b95f10aa182ad0a46400db63156920adb65eca2654c0945a463","0x2","0x322258135d04971e96b747a5551061aa046ad5d8be11a35c67029d96b23f98","0x0"],"caller_address":"0x0","class_hash":"0x25ec026985a3bf9d0cc1fe17326b245dfdc3ff89b8fde106542a3ea56c5a918","entry_point_type":"EXTERNAL","call_type":"CALL","result":[],"calls":[{"entry_point_selector":"0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895","calldata":["0x25ec026985a3bf9d0cc1fe17326b245dfdc3ff89b8fde106542a3ea56c5a918","0x322258135d04971e96b747a5551061aa046ad5d8be11a35c67029d96b23f98","0x33434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2","0x79dc0da7c54b95f10aa182ad0a46400db63156920adb65eca2654c0945a463","0x2","0x322258135d04971e96b747a5551061aa046ad5d8be11a35c67029d96b23f98","0x0"],"caller_address":"0x0","class_hash":"0x33434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2","entry_point_type":"EXTERNAL","call_type":"DELEGATE","result":[],"calls":[],"events":[],"messages":[]}],"events":[],"messages":[]}, - "execute_invocation":{"entry_point_selector":"0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194","calldata":["0x33434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2","0x79dc0da7c54b95f10aa182ad0a46400db63156920adb65eca2654c0945a463","0x2","0x322258135d04971e96b747a5551061aa046ad5d8be11a35c67029d96b23f98","0x0"],"caller_address":"0x0","class_hash":"0x25ec026985a3bf9d0cc1fe17326b245dfdc3ff89b8fde106542a3ea56c5a918","entry_point_type":"CONSTRUCTOR","call_type":"CALL","result":[],"calls":[{"entry_point_selector":"0x79dc0da7c54b95f10aa182ad0a46400db63156920adb65eca2654c0945a463","calldata":["0x322258135d04971e96b747a5551061aa046ad5d8be11a35c67029d96b23f98","0x0"],"caller_address":"0x0","class_hash":"0x33434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2","entry_point_type":"EXTERNAL","call_type":"DELEGATE","result":[],"calls":[],"events":[{"keys":["0x10c19bef19acd19b2c9f4caa40fd47c9fbe1d9f91324d44dcd36be2dae96784"],"data":["0xdac9bcffb3d967f19a7fe21002c98c984d5a9458a88e6fc5d1c478a97ed412","0x322258135d04971e96b747a5551061aa046ad5d8be11a35c67029d96b23f98","0x0"]}],"messages":[]}],"events":[],"messages":[]}, - "fee_transfer_invocation":{"entry_point_selector":"0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e","calldata":["0x5dcd266a80b8a5f29f04d779c6b166b80150c24f2180a75e82427242dab20a9","0x15be","0x0"],"caller_address":"0xdac9bcffb3d967f19a7fe21002c98c984d5a9458a88e6fc5d1c478a97ed412","class_hash":"0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3","entry_point_type":"EXTERNAL","call_type":"CALL","result":["0x1"],"calls":[{"entry_point_selector":"0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e","calldata":["0x5dcd266a80b8a5f29f04d779c6b166b80150c24f2180a75e82427242dab20a9","0x15be","0x0"],"caller_address":"0xdac9bcffb3d967f19a7fe21002c98c984d5a9458a88e6fc5d1c478a97ed412","class_hash":"0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0","entry_point_type":"EXTERNAL","call_type":"DELEGATE","result":["0x1"],"calls":[],"events":[{"keys":["0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"],"data":["0xdac9bcffb3d967f19a7fe21002c98c984d5a9458a88e6fc5d1c478a97ed412","0x5dcd266a80b8a5f29f04d779c6b166b80150c24f2180a75e82427242dab20a9","0x15be","0x0"]}],"messages":[]}],"events":[],"messages":[]}, + "validate_invocation":{"entry_point_selector":"0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895","calldata":["0x25ec026985a3bf9d0cc1fe17326b245dfdc3ff89b8fde106542a3ea56c5a918","0x322258135d04971e96b747a5551061aa046ad5d8be11a35c67029d96b23f98","0x33434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2","0x79dc0da7c54b95f10aa182ad0a46400db63156920adb65eca2654c0945a463","0x2","0x322258135d04971e96b747a5551061aa046ad5d8be11a35c67029d96b23f98","0x0"],"caller_address":"0x0","class_hash":"0x25ec026985a3bf9d0cc1fe17326b245dfdc3ff89b8fde106542a3ea56c5a918","entry_point_type":"EXTERNAL","call_type":"CALL","result":[],"calls":[{"entry_point_selector":"0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895","calldata":["0x25ec026985a3bf9d0cc1fe17326b245dfdc3ff89b8fde106542a3ea56c5a918","0x322258135d04971e96b747a5551061aa046ad5d8be11a35c67029d96b23f98","0x33434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2","0x79dc0da7c54b95f10aa182ad0a46400db63156920adb65eca2654c0945a463","0x2","0x322258135d04971e96b747a5551061aa046ad5d8be11a35c67029d96b23f98","0x0"],"caller_address":"0x0","class_hash":"0x33434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2","entry_point_type":"EXTERNAL","call_type":"DELEGATE","result":[],"calls":[],"events":[],"messages":[]}],"events":[],"messages":[], "execution_resources":{}}, + "execute_invocation":{"entry_point_selector":"0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194","calldata":["0x33434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2","0x79dc0da7c54b95f10aa182ad0a46400db63156920adb65eca2654c0945a463","0x2","0x322258135d04971e96b747a5551061aa046ad5d8be11a35c67029d96b23f98","0x0"],"caller_address":"0x0","class_hash":"0x25ec026985a3bf9d0cc1fe17326b245dfdc3ff89b8fde106542a3ea56c5a918","entry_point_type":"CONSTRUCTOR","call_type":"CALL","result":[],"calls":[{"entry_point_selector":"0x79dc0da7c54b95f10aa182ad0a46400db63156920adb65eca2654c0945a463","calldata":["0x322258135d04971e96b747a5551061aa046ad5d8be11a35c67029d96b23f98","0x0"],"caller_address":"0x0","class_hash":"0x33434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2","entry_point_type":"EXTERNAL","call_type":"DELEGATE","result":[],"calls":[],"events":[{"keys":["0x10c19bef19acd19b2c9f4caa40fd47c9fbe1d9f91324d44dcd36be2dae96784"],"data":["0xdac9bcffb3d967f19a7fe21002c98c984d5a9458a88e6fc5d1c478a97ed412","0x322258135d04971e96b747a5551061aa046ad5d8be11a35c67029d96b23f98","0x0"]}],"messages":[]}],"events":[],"messages":[], "execution_resources": {}}, + "fee_transfer_invocation":{"entry_point_selector":"0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e","calldata":["0x5dcd266a80b8a5f29f04d779c6b166b80150c24f2180a75e82427242dab20a9","0x15be","0x0"],"caller_address":"0xdac9bcffb3d967f19a7fe21002c98c984d5a9458a88e6fc5d1c478a97ed412","class_hash":"0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3","entry_point_type":"EXTERNAL","call_type":"CALL","result":["0x1"],"calls":[{"entry_point_selector":"0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e","calldata":["0x5dcd266a80b8a5f29f04d779c6b166b80150c24f2180a75e82427242dab20a9","0x15be","0x0"],"caller_address":"0xdac9bcffb3d967f19a7fe21002c98c984d5a9458a88e6fc5d1c478a97ed412","class_hash":"0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0","entry_point_type":"EXTERNAL","call_type":"DELEGATE","result":["0x1"],"calls":[],"events":[{"keys":["0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"],"data":["0xdac9bcffb3d967f19a7fe21002c98c984d5a9458a88e6fc5d1c478a97ed412","0x5dcd266a80b8a5f29f04d779c6b166b80150c24f2180a75e82427242dab20a9","0x15be","0x0"]}],"messages":[]}],"events":[],"messages":[], "execution_resources": {}}, + "execution_resources": {"data_availability": {}}, "state_diff": { "storage_diffs": [], "nonces": [], @@ -537,9 +428,11 @@ func TestTraceBlockTransactionsV0_6(t *testing.T) { }`) vmTrace := vm.TransactionTrace{} require.NoError(t, json.Unmarshal(vmTraceJSON, &vmTrace)) + stepsUsed := uint64(123) + stepsUsedStr := "123" mockVM.EXPECT().Execute([]core.Transaction{tx}, []core.Class{declaredClass.Class}, []*felt.Felt{}, &vm.BlockInfo{Header: header}, - gomock.Any(), n, false, false, false, false). - Return(nil, nil, []vm.TransactionTrace{vmTrace}, nil) + gomock.Any(), n, false, false, false). + Return(nil, []core.GasConsumed{{}, {}}, []vm.TransactionTrace{vmTrace}, stepsUsed, nil) expectedResult := []rpc.TracedBlockTransaction{ { @@ -547,8 +440,9 @@ func TestTraceBlockTransactionsV0_6(t *testing.T) { TraceRoot: &vmTrace, }, } - result, err := handler.TraceBlockTransactionsV0_6(context.Background(), rpc.BlockID{Hash: blockHash}) + result, httpHeader, err := handler.TraceBlockTransactions(context.Background(), rpc.BlockID{Hash: blockHash}) require.Nil(t, err) + assert.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), stepsUsedStr) assert.Equal(t, expectedResult, result) }) } @@ -626,7 +520,7 @@ func TestCall(t *testing.T) { ClassHash: classHash, Selector: selector, Calldata: calldata, - }, &vm.BlockInfo{Header: headsHeader}, gomock.Any(), &utils.Mainnet, uint64(1337), true).Return(expectedRes, nil) + }, &vm.BlockInfo{Header: headsHeader}, gomock.Any(), &utils.Mainnet, uint64(1337)).Return(expectedRes, nil) res, rpcErr := handler.Call(rpc.FunctionCall{ ContractAddress: *contractAddr, diff --git a/rpc/transaction.go b/rpc/transaction.go index d040bf866a..b270e7e861 100644 --- a/rpc/transaction.go +++ b/rpc/transaction.go @@ -471,7 +471,7 @@ func (h *Handler) TransactionByBlockIDAndIndex(id BlockID, txIndex int) (*Transa // // It follows the specification defined here: // https://github.com/starkware-libs/starknet-specs/blob/master/api/starknet_api_openrpc.json#L222 -func (h *Handler) TransactionReceiptByHash(hash felt.Felt) (*TransactionReceipt, *jsonrpc.Error) { //nolint:dupl +func (h *Handler) TransactionReceiptByHash(hash felt.Felt) (*TransactionReceipt, *jsonrpc.Error) { txn, err := h.bcReader.TransactionByHash(&hash) if err != nil { return nil, ErrTxnHashNotFound @@ -495,38 +495,7 @@ func (h *Handler) TransactionReceiptByHash(hash felt.Felt) (*TransactionReceipt, } } - return AdaptReceipt(receipt, txn, status, blockHash, blockNumber, false), nil -} - -// TransactionReceiptByHash returns the receipt of a transaction identified by the given hash. -// -// It follows the specification defined here: -// https://github.com/starkware-libs/starknet-specs/blob/master/api/starknet_api_openrpc.json#L222 -func (h *Handler) TransactionReceiptByHashV0_6(hash felt.Felt) (*TransactionReceipt, *jsonrpc.Error) { //nolint:dupl - txn, err := h.bcReader.TransactionByHash(&hash) - if err != nil { - return nil, ErrTxnHashNotFound - } - - receipt, blockHash, blockNumber, err := h.bcReader.Receipt(&hash) - if err != nil { - return nil, ErrTxnHashNotFound - } - - status := TxnAcceptedOnL2 - - if blockHash != nil { - l1H, jsonErr := h.l1Head() - if jsonErr != nil { - return nil, jsonErr - } - - if isL1Verified(blockNumber, l1H) { - status = TxnAcceptedOnL1 - } - } - - return AdaptReceipt(receipt, txn, status, blockHash, blockNumber, true), nil + return AdaptReceipt(receipt, txn, status, blockHash, blockNumber), nil } // AddTransaction relays a transaction to the gateway. @@ -613,28 +582,13 @@ func (h *Handler) TransactionStatus(ctx context.Context, hash felt.Felt) (*Trans return nil, jsonrpc.Err(jsonrpc.InternalError, err.Error()) } - var status TransactionStatus - switch txStatus.FinalityStatus { - case starknet.AcceptedOnL1: - status.Finality = TxnStatusAcceptedOnL1 - case starknet.AcceptedOnL2: - status.Finality = TxnStatusAcceptedOnL2 - case starknet.Received: - status.Finality = TxnStatusReceived - default: + status, err := adaptTransactionStatus(txStatus) + if err != nil { + h.log.Errorw("Failed to adapt transaction status", "err", err) return nil, ErrTxnHashNotFound } - switch txStatus.ExecutionStatus { - case starknet.Succeeded: - status.Execution = TxnSuccess - case starknet.Reverted: - status.Execution = TxnFailure - case starknet.Rejected: - status.Finality = TxnStatusRejected - default: // Omit the field on error. It's optional in the spec. - } - return &status, nil + return status, nil } return nil, txErr } @@ -721,9 +675,8 @@ func AdaptTransaction(t core.Transaction) *Transaction { } // todo(Kirill): try to replace core.Transaction with rpc.Transaction type -func AdaptReceipt(receipt *core.TransactionReceipt, txn core.Transaction, - finalityStatus TxnFinalityStatus, blockHash *felt.Felt, blockNumber uint64, - v0_6Response bool, +func AdaptReceipt(receipt *core.TransactionReceipt, txn core.Transaction, finalityStatus TxnFinalityStatus, + blockHash *felt.Felt, blockNumber uint64, ) *TransactionReceipt { messages := make([]*MsgToL1, len(receipt.L2ToL1Message)) for idx, msg := range receipt.L2ToL1Message { @@ -782,11 +735,38 @@ func AdaptReceipt(receipt *core.TransactionReceipt, txn core.Transaction, Events: events, ContractAddress: contractAddress, RevertReason: receipt.RevertReason, - ExecutionResources: adaptExecutionResources(receipt.ExecutionResources, v0_6Response), + ExecutionResources: adaptExecutionResources(receipt.ExecutionResources), MessageHash: messageHash, } } +func adaptTransactionStatus(txStatus *starknet.TransactionStatus) (*TransactionStatus, error) { + var status TransactionStatus + + switch finalityStatus := txStatus.FinalityStatus; finalityStatus { + case starknet.AcceptedOnL1: + status.Finality = TxnStatusAcceptedOnL1 + case starknet.AcceptedOnL2: + status.Finality = TxnStatusAcceptedOnL2 + case starknet.Received: + status.Finality = TxnStatusReceived + default: + return nil, fmt.Errorf("unknown finality status: %v", finalityStatus) + } + + switch txStatus.ExecutionStatus { + case starknet.Succeeded: + status.Execution = TxnSuccess + case starknet.Reverted: + status.Execution = TxnFailure + case starknet.Rejected: + status.Finality = TxnStatusRejected + default: // Omit the field on error. It's optional in the spec. + } + + return &status, nil +} + // https://github.com/starkware-libs/starknet-specs/blob/a789ccc3432c57777beceaa53a34a7ae2f25fda0/api/starknet_api_openrpc.json#L1605 func adaptInvokeTransaction(t *core.InvokeTransaction) *Transaction { tx := &Transaction{ diff --git a/rpc/transaction_test.go b/rpc/transaction_test.go index 53a1292bb8..8de3400ee9 100644 --- a/rpc/transaction_test.go +++ b/rpc/transaction_test.go @@ -489,7 +489,7 @@ func TestTransactionByBlockIdAndIndex(t *testing.T) { } //nolint:dupl -func TestTransactionReceiptByHashV0_6(t *testing.T) { +func TestTransactionReceiptByHash(t *testing.T) { mockCtrl := gomock.NewController(t) t.Cleanup(mockCtrl.Finish) @@ -501,7 +501,7 @@ func TestTransactionReceiptByHashV0_6(t *testing.T) { txHash := new(felt.Felt).SetBytes([]byte("random hash")) mockReader.EXPECT().TransactionByHash(txHash).Return(nil, errors.New("tx not found")) - tx, rpcErr := handler.TransactionReceiptByHashV0_6(*txHash) + tx, rpcErr := handler.TransactionReceiptByHash(*txHash) assert.Nil(t, tx) assert.Equal(t, rpc.ErrTxnHashNotFound, rpcErr) }) @@ -518,9 +518,8 @@ func TestTransactionReceiptByHashV0_6(t *testing.T) { expectedMap := make(map[string]any) require.NoError(t, json.Unmarshal([]byte(expected), &expectedMap)) - receipt, err := handler.TransactionReceiptByHashV0_6(*h) + receipt, err := handler.TransactionReceiptByHash(*h) require.Nil(t, err) - receiptJSON, jsonErr := json.Marshal(receipt) require.NoError(t, jsonErr) @@ -546,7 +545,13 @@ func TestTransactionReceiptByHashV0_6(t *testing.T) { "messages_sent": [], "events": [], "contract_address": "0x20cfa74ee3564b4cd5435cdace0f9c4d43b939620e4a0bb5076105df0a626c6", - "execution_resources":{"steps":29} + "execution_resources": { + "data_availability": { + "l1_data_gas": 0, + "l1_gas": 0 + }, + "steps": 29 + } }`, }, "without contract addr": { @@ -570,7 +575,13 @@ func TestTransactionReceiptByHashV0_6(t *testing.T) { } ], "events": [], - "execution_resources":{"steps":31} + "execution_resources": { + "data_availability": { + "l1_data_gas": 0, + "l1_gas": 0 + }, + "steps": 31 + } }`, }, } @@ -604,7 +615,13 @@ func TestTransactionReceiptByHashV0_6(t *testing.T) { } ], "events": [], - "execution_resources":{"steps":31} + "execution_resources": { + "data_availability": { + "l1_data_gas": 0, + "l1_gas": 0 + }, + "steps": 31 + } }` txHash := block0.Transactions[i].Hash() @@ -635,7 +652,13 @@ func TestTransactionReceiptByHashV0_6(t *testing.T) { } ], "events": [], - "execution_resources":{"steps":31} + "execution_resources": { + "data_availability": { + "l1_data_gas": 0, + "l1_gas": 0 + }, + "steps": 31 + } }` txHash := block0.Transactions[i].Hash() @@ -661,7 +684,13 @@ func TestTransactionReceiptByHashV0_6(t *testing.T) { "messages_sent": [], "events": [], "revert_reason": "Error in the called contract (0x00b1461de04c6a1aa3375bdf9b7723a8779c082ffe21311d683a0b15c078b5dc):\nError at pc=0:25:\nGot an exception while executing a hint.\nCairo traceback (most recent call last):\nUnknown location (pc=0:731)\nUnknown location (pc=0:677)\nUnknown location (pc=0:291)\nUnknown location (pc=0:314)\n\nError in the called contract (0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7):\nError at pc=0:104:\nGot an exception while executing a hint.\nCairo traceback (most recent call last):\nUnknown location (pc=0:1678)\nUnknown location (pc=0:1664)\n\nError in the called contract (0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7):\nError at pc=0:6:\nGot an exception while executing a hint: Assertion failed, 0 % 0x800000000000011000000000000000000000000000000000000000000000001 is equal to 0\nCairo traceback (most recent call last):\nUnknown location (pc=0:1238)\nUnknown location (pc=0:1215)\nUnknown location (pc=0:836)\n", - "execution_resources":{"steps":0} + "execution_resources": { + "data_availability": { + "l1_data_gas": 0, + "l1_gas": 0 + }, + "steps": 0 + } }` integClient := feeder.NewTestClient(t, &utils.Integration) @@ -719,7 +748,11 @@ func TestTransactionReceiptByHashV0_6(t *testing.T) { "execution_resources": { "steps": 615, "range_check_builtin_applications": 19, - "memory_holes": 4 + "memory_holes": 4, + "data_availability": { + "l1_data_gas": 0, + "l1_gas": 0 + } }, "actual_fee": { "amount": "0x16d8b4ad4000", @@ -744,256 +777,55 @@ func TestTransactionReceiptByHashV0_6(t *testing.T) { checkTxReceipt(t, txnHash, expected) }) -} - -//nolint:dupl -func TestTransactionReceiptByHash(t *testing.T) { - mockCtrl := gomock.NewController(t) - t.Cleanup(mockCtrl.Finish) - - n := utils.Ptr(utils.Mainnet) - mockReader := mocks.NewMockReader(mockCtrl) - handler := rpc.New(mockReader, nil, nil, "", nil) - - t.Run("transaction not found", func(t *testing.T) { - txHash := new(felt.Felt).SetBytes([]byte("random hash")) - mockReader.EXPECT().TransactionByHash(txHash).Return(nil, errors.New("tx not found")) - - tx, rpcErr := handler.TransactionReceiptByHash(*txHash) - assert.Nil(t, tx) - assert.Equal(t, rpc.ErrTxnHashNotFound, rpcErr) - }) - - client := feeder.NewTestClient(t, n) - mainnetGw := adaptfeeder.New(client) - - block0, err := mainnetGw.BlockByNumber(context.Background(), 0) - require.NoError(t, err) - - checkTxReceipt := func(t *testing.T, h *felt.Felt, expected string) { - t.Helper() - - expectedMap := make(map[string]any) - require.NoError(t, json.Unmarshal([]byte(expected), &expectedMap)) - - receipt, err := handler.TransactionReceiptByHash(*h) - require.Nil(t, err) - receiptJSON, jsonErr := json.Marshal(receipt) - require.NoError(t, jsonErr) - - receiptMap := make(map[string]any) - require.NoError(t, json.Unmarshal(receiptJSON, &receiptMap)) - assert.Equal(t, expectedMap, receiptMap) - } - - tests := map[string]struct { - index int - expected string - }{ - "with contract addr": { - index: 0, - expected: `{ - "type": "DEPLOY", - "transaction_hash": "0xe0a2e45a80bb827967e096bcf58874f6c01c191e0a0530624cba66a508ae75", - "actual_fee": {"amount": "0x0", "unit": "WEI"}, - "finality_status": "ACCEPTED_ON_L2", - "execution_status": "SUCCEEDED", - "block_hash": "0x47c3637b57c2b079b93c61539950c17e868a28f46cdef28f88521067f21e943", - "block_number": 0, - "messages_sent": [], - "events": [], - "contract_address": "0x20cfa74ee3564b4cd5435cdace0f9c4d43b939620e4a0bb5076105df0a626c6", - "execution_resources":{"steps":29} - }`, - }, - "without contract addr": { - index: 2, - expected: `{ - "type": "INVOKE", - "transaction_hash": "0xce54bbc5647e1c1ea4276c01a708523f740db0ff5474c77734f73beec2624", - "actual_fee": {"amount": "0x0", "unit": "WEI"}, - "finality_status": "ACCEPTED_ON_L2", - "execution_status": "SUCCEEDED", - "block_hash": "0x47c3637b57c2b079b93c61539950c17e868a28f46cdef28f88521067f21e943", - "block_number": 0, - "messages_sent": [ - { - "from_address": "0x20cfa74ee3564b4cd5435cdace0f9c4d43b939620e4a0bb5076105df0a626c6", - "to_address": "0xc84dd7fd43a7defb5b7a15c4fbbe11cbba6db1ba", - "payload": [ - "0xc", - "0x22" - ] - } - ], - "events": [], - "execution_resources":{"steps":31} - }`, - }, - } - for name, test := range tests { - t.Run(name, func(t *testing.T) { - txHash := block0.Transactions[test.index].Hash() - mockReader.EXPECT().TransactionByHash(txHash).Return(block0.Transactions[test.index], nil) - mockReader.EXPECT().Receipt(txHash).Return(block0.Receipts[test.index], block0.Hash, block0.Number, nil) - mockReader.EXPECT().L1Head().Return(nil, db.ErrKeyNotFound) - - checkTxReceipt(t, txHash, test.expected) - }) - } - - t.Run("pending receipt", func(t *testing.T) { - i := 2 - expected := `{ - "type": "INVOKE", - "transaction_hash": "0xce54bbc5647e1c1ea4276c01a708523f740db0ff5474c77734f73beec2624", - "actual_fee": {"amount": "0x0", "unit": "WEI"}, - "finality_status": "ACCEPTED_ON_L2", - "execution_status": "SUCCEEDED", - "messages_sent": [ - { - "from_address": "0x20cfa74ee3564b4cd5435cdace0f9c4d43b939620e4a0bb5076105df0a626c6", - "to_address": "0xc84dd7fd43a7defb5b7a15c4fbbe11cbba6db1ba", - "payload": [ - "0xc", - "0x22" - ] - } - ], - "events": [], - "execution_resources":{"steps":31} - }` - - txHash := block0.Transactions[i].Hash() - mockReader.EXPECT().TransactionByHash(txHash).Return(block0.Transactions[i], nil) - mockReader.EXPECT().Receipt(txHash).Return(block0.Receipts[i], nil, uint64(0), nil) - - checkTxReceipt(t, txHash, expected) - }) - - t.Run("accepted on l1 receipt", func(t *testing.T) { - i := 2 - expected := `{ - "type": "INVOKE", - "transaction_hash": "0xce54bbc5647e1c1ea4276c01a708523f740db0ff5474c77734f73beec2624", - "actual_fee": {"amount": "0x0", "unit": "WEI"}, - "finality_status": "ACCEPTED_ON_L1", - "execution_status": "SUCCEEDED", - "block_hash": "0x47c3637b57c2b079b93c61539950c17e868a28f46cdef28f88521067f21e943", - "block_number": 0, - "messages_sent": [ - { - "from_address": "0x20cfa74ee3564b4cd5435cdace0f9c4d43b939620e4a0bb5076105df0a626c6", - "to_address": "0xc84dd7fd43a7defb5b7a15c4fbbe11cbba6db1ba", - "payload": [ - "0xc", - "0x22" - ] - } - ], - "events": [], - "execution_resources":{"steps":31} - }` - - txHash := block0.Transactions[i].Hash() - mockReader.EXPECT().TransactionByHash(txHash).Return(block0.Transactions[i], nil) - mockReader.EXPECT().Receipt(txHash).Return(block0.Receipts[i], block0.Hash, block0.Number, nil) - mockReader.EXPECT().L1Head().Return(&core.L1Head{ - BlockNumber: block0.Number, - BlockHash: block0.Hash, - StateRoot: block0.GlobalStateRoot, - }, nil) - - checkTxReceipt(t, txHash, expected) - }) - t.Run("reverted", func(t *testing.T) { - expected := `{ - "type": "INVOKE", - "transaction_hash": "0x19abec18bbacec23c2eee160c70190a48e4b41dd5ff98ad8f247f9393559998", - "actual_fee": {"amount": "0x247aff6e224", "unit": "WEI"}, - "execution_status": "REVERTED", - "finality_status": "ACCEPTED_ON_L2", - "block_hash": "0x76e0229fd0c36dda2ee7905f7e4c9b3ebb78d98c4bfab550bcb3a03bf859a6", - "block_number": 304740, - "messages_sent": [], - "events": [], - "revert_reason": "Error in the called contract (0x00b1461de04c6a1aa3375bdf9b7723a8779c082ffe21311d683a0b15c078b5dc):\nError at pc=0:25:\nGot an exception while executing a hint.\nCairo traceback (most recent call last):\nUnknown location (pc=0:731)\nUnknown location (pc=0:677)\nUnknown location (pc=0:291)\nUnknown location (pc=0:314)\n\nError in the called contract (0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7):\nError at pc=0:104:\nGot an exception while executing a hint.\nCairo traceback (most recent call last):\nUnknown location (pc=0:1678)\nUnknown location (pc=0:1664)\n\nError in the called contract (0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7):\nError at pc=0:6:\nGot an exception while executing a hint: Assertion failed, 0 % 0x800000000000011000000000000000000000000000000000000000000000001 is equal to 0\nCairo traceback (most recent call last):\nUnknown location (pc=0:1238)\nUnknown location (pc=0:1215)\nUnknown location (pc=0:836)\n", - "execution_resources":{"steps":0} - }` - - integClient := feeder.NewTestClient(t, &utils.Integration) - integGw := adaptfeeder.New(integClient) - - blockWithRevertedTxn, err := integGw.BlockByNumber(context.Background(), 304740) - require.NoError(t, err) - - revertedTxnIdx := 1 - revertedTxnHash := blockWithRevertedTxn.Transactions[revertedTxnIdx].Hash() - - mockReader.EXPECT().TransactionByHash(revertedTxnHash).Return(blockWithRevertedTxn.Transactions[revertedTxnIdx], nil) - mockReader.EXPECT().Receipt(revertedTxnHash).Return(blockWithRevertedTxn.Receipts[revertedTxnIdx], - blockWithRevertedTxn.Hash, blockWithRevertedTxn.Number, nil) - mockReader.EXPECT().L1Head().Return(nil, db.ErrKeyNotFound) - - checkTxReceipt(t, revertedTxnHash, expected) - }) - t.Run("v3 tx", func(t *testing.T) { + t.Run("tx with non empty data_availability", func(t *testing.T) { expected := `{ - "block_hash": "0x50e864db6b81ce69fbeb70e6a7284ee2febbb9a2e707415de7adab83525e9cd", - "block_number": 319132, + "type": "DECLARE", + "transaction_hash": "0x5ac644bbd6ae98d3be2d988439854e33f0961e24f349a63b43e16d172bfe747", + "actual_fee": { + "amount": "0xd07af45c84550", + "unit": "WEI" + }, "execution_status": "SUCCEEDED", "finality_status": "ACCEPTED_ON_L2", - "transaction_hash": "0x49728601e0bb2f48ce506b0cbd9c0e2a9e50d95858aa41463f46386dca489fd", + "block_hash": "0x1ea2a9cfa3df5297d58c0a04d09d276bc68d40fe64701305bbe2ed8f417e869", + "block_number": 35748, "messages_sent": [], "events": [ { - "from_address": "0x4718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", + "from_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "keys": [ "0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9" ], "data": [ - "0x3f6f3bc663aedc5285d6013cc3ffcbc4341d86ab488b8b68d297f8258793c41", + "0x472aa8128e01eb0df145810c9511a92852d62a68ba8198ce5fa414e6337a365", "0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8", - "0x16d8b4ad4000", - "0x0" - ] - }, - { - "from_address": "0x4718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", - "keys": [ - "0xa9fa878c35cd3d0191318f89033ca3e5501a3d90e21e3cc9256bdd5cd17fdd" - ], - "data": [ - "0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8", - "0x18ad8494375bc00", - "0x0", - "0x18aef21f822fc00", + "0xd07af45c84550", "0x0" ] } ], "execution_resources": { - "steps": 615, - "range_check_builtin_applications": 19, - "memory_holes": 4 - }, - "actual_fee": { - "amount": "0x16d8b4ad4000", - "unit": "FRI" - }, - "type": "INVOKE" + "steps": 3950, + "ecdsa_builtin_applications": 1, + "pedersen_builtin_applications": 16, + "poseidon_builtin_applications": 4, + "range_check_builtin_applications": 157, + "data_availability": { + "l1_gas": 0, + "l1_data_gas": 192 + } + } }` - integClient := feeder.NewTestClient(t, &utils.Integration) - integGw := adaptfeeder.New(integClient) + netClient := feeder.NewTestClient(t, utils.Ptr(utils.SepoliaIntegration)) + netGW := adaptfeeder.New(netClient) - block, err := integGw.BlockByNumber(context.Background(), 319132) + block, err := netGW.BlockByNumber(context.Background(), 35748) require.NoError(t, err) index := 0 txnHash := block.Transactions[index].Hash() - mockReader.EXPECT().TransactionByHash(txnHash).Return(block.Transactions[index], nil) mockReader.EXPECT().Receipt(txnHash).Return(block.Receipts[index], block.Hash, block.Number, nil) @@ -1355,6 +1187,7 @@ func TestTransactionStatus(t *testing.T) { } ctx := context.Background() + log := utils.NewNopZapLogger() for _, test := range tests { t.Run(test.network.String(), func(t *testing.T) { @@ -1395,7 +1228,7 @@ func TestTransactionStatus(t *testing.T) { BlockNumber: block.Number + 1, }, nil) - handler := rpc.New(mockReader, nil, nil, "", nil) + handler := rpc.New(mockReader, nil, nil, "", log) want := &rpc.TransactionStatus{ Finality: rpc.TxnStatusAcceptedOnL1, @@ -1425,7 +1258,7 @@ func TestTransactionStatus(t *testing.T) { t.Run(description, func(t *testing.T) { mockReader := mocks.NewMockReader(mockCtrl) mockReader.EXPECT().TransactionByHash(notFoundTest.hash).Return(nil, db.ErrKeyNotFound).Times(2) - handler := rpc.New(mockReader, nil, nil, "", nil) + handler := rpc.New(mockReader, nil, nil, "", log) _, err := handler.TransactionStatus(ctx, *notFoundTest.hash) require.Equal(t, rpc.ErrTxnHashNotFound.Code, err.Code) @@ -1442,7 +1275,7 @@ func TestTransactionStatus(t *testing.T) { t.Run("transaction not found in db and feeder ", func(t *testing.T) { mockReader := mocks.NewMockReader(mockCtrl) mockReader.EXPECT().TransactionByHash(test.notFoundTxHash).Return(nil, db.ErrKeyNotFound) - handler := rpc.New(mockReader, nil, nil, "", nil).WithFeeder(client) + handler := rpc.New(mockReader, nil, nil, "", log).WithFeeder(client) _, err := handler.TransactionStatus(ctx, *test.notFoundTxHash) require.NotNil(t, err) diff --git a/scripts/fuzz_all.sh b/scripts/fuzz_all.sh new file mode 100755 index 0000000000..ece67fb600 --- /dev/null +++ b/scripts/fuzz_all.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -e + +fuzzTime=${1:-10} + +files=$(grep -r --include='**_test.go' --files-with-matches 'func Fuzz' .) + +for file in ${files} +do + funcs=$(grep -o 'func Fuzz\w*' $file | sed 's/func //') + for func in ${funcs} + do + echo "Fuzzing $func in $file" + parentDir=$(dirname $file) + go test $parentDir -run=$func -fuzz=$func -fuzztime=${fuzzTime}s + done +done diff --git a/starknet/compiler.go b/starknet/compiler/compiler.go similarity index 81% rename from starknet/compiler.go rename to starknet/compiler/compiler.go index 5def4da367..90367788c5 100644 --- a/starknet/compiler.go +++ b/starknet/compiler/compiler.go @@ -1,4 +1,4 @@ -package starknet +package compiler /* #include @@ -19,10 +19,12 @@ import ( "encoding/json" "errors" "unsafe" + + "github.com/NethermindEth/juno/starknet" ) -func Compile(sierra *SierraDefinition) (*CompiledClass, error) { - sierraJSON, err := json.Marshal(SierraDefinition{ +func Compile(sierra *starknet.SierraDefinition) (*starknet.CompiledClass, error) { + sierraJSON, err := json.Marshal(starknet.SierraDefinition{ EntryPoints: sierra.EntryPoints, Program: sierra.Program, Version: sierra.Version, @@ -45,7 +47,7 @@ func Compile(sierra *SierraDefinition) (*CompiledClass, error) { casmJSON := C.GoString(result) - var casmClass CompiledClass + var casmClass starknet.CompiledClass if err := json.Unmarshal([]byte(casmJSON), &casmClass); err != nil { return nil, err } diff --git a/starknet/compiler_test.go b/starknet/compiler/compiler_test.go similarity index 86% rename from starknet/compiler_test.go rename to starknet/compiler/compiler_test.go index 68682d08f2..201150a25f 100644 --- a/starknet/compiler_test.go +++ b/starknet/compiler/compiler_test.go @@ -1,4 +1,4 @@ -package starknet_test +package compiler_test import ( "context" @@ -10,6 +10,7 @@ import ( "github.com/NethermindEth/juno/adapters/sn2core" "github.com/NethermindEth/juno/clients/feeder" "github.com/NethermindEth/juno/starknet" + "github.com/NethermindEth/juno/starknet/compiler" "github.com/NethermindEth/juno/utils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -17,7 +18,7 @@ import ( func TestCompile(t *testing.T) { t.Run("zero sierra", func(t *testing.T) { - _, err := starknet.Compile(&starknet.SierraDefinition{}) + _, err := compiler.Compile(&starknet.SierraDefinition{}) require.Error(t, err) }) @@ -33,7 +34,7 @@ func TestCompile(t *testing.T) { expectedCompiled, err := sn2core.AdaptCompiledClass(compiledDef) require.NoError(t, err) - res, err := starknet.Compile(classDef.V1) + res, err := compiler.Compile(classDef.V1) require.NoError(t, err) gotCompiled, err := sn2core.AdaptCompiledClass(res) @@ -45,7 +46,7 @@ func TestCompile(t *testing.T) { // tests https://github.com/NethermindEth/juno/issues/1748 definition := loadTestData[starknet.SierraDefinition](t, "declare_cairo2_definition.json") - _, err := starknet.Compile(&definition) + _, err := compiler.Compile(&definition) require.NoError(t, err) }) } @@ -54,7 +55,7 @@ func TestCompile(t *testing.T) { func loadTestData[T any](t *testing.T, filename string) T { t.Helper() - file := fmt.Sprintf("./testdata/%s", filename) + file := fmt.Sprintf("../testdata/%s", filename) buff, err := os.ReadFile(file) if err != nil { t.Fatalf("Failed to read file %s: %v", file, err) diff --git a/starknet/rust/.gitignore b/starknet/compiler/rust/.gitignore similarity index 100% rename from starknet/rust/.gitignore rename to starknet/compiler/rust/.gitignore diff --git a/starknet/rust/Cargo.toml b/starknet/compiler/rust/Cargo.toml similarity index 64% rename from starknet/rust/Cargo.toml rename to starknet/compiler/rust/Cargo.toml index 5a84b57548..e23bddfb07 100644 --- a/starknet/rust/Cargo.toml +++ b/starknet/compiler/rust/Cargo.toml @@ -6,9 +6,9 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -serde = "1.0.171" -serde_json = { version = "1.0.96", features = ["raw_value"] } -cairo-lang-starknet-classes = "=2.7.0-rc.3" +serde = "1.0.208" +serde_json = { version = "1.0.125", features = ["raw_value"] } +cairo-lang-starknet-classes = "2.7.1" [lib] crate-type = ["staticlib"] diff --git a/starknet/rust/Makefile b/starknet/compiler/rust/Makefile similarity index 100% rename from starknet/rust/Makefile rename to starknet/compiler/rust/Makefile diff --git a/starknet/rust/src/lib.rs b/starknet/compiler/rust/src/lib.rs similarity index 100% rename from starknet/rust/src/lib.rs rename to starknet/compiler/rust/src/lib.rs diff --git a/starknet/transaction.go b/starknet/transaction.go index 3898e95e5b..d73095d071 100644 --- a/starknet/transaction.go +++ b/starknet/transaction.go @@ -16,16 +16,16 @@ const ( Rejected ) -func (es *ExecutionStatus) UnmarshalJSON(data []byte) error { - switch string(data) { - case `"SUCCEEDED"`: +func (es *ExecutionStatus) UnmarshalText(data []byte) error { + switch str := string(data); str { + case "SUCCEEDED": *es = Succeeded - case `"REVERTED"`: + case "REVERTED": *es = Reverted - case `"REJECTED"`: + case "REJECTED": *es = Rejected default: - return errors.New("unknown ExecutionStatus") + return fmt.Errorf("unknown ExecutionStatus %q", str) } return nil } @@ -39,18 +39,18 @@ const ( Received ) -func (fs *FinalityStatus) UnmarshalJSON(data []byte) error { - switch string(data) { - case `"ACCEPTED_ON_L2"`: +func (fs *FinalityStatus) UnmarshalText(data []byte) error { + switch str := string(data); str { + case "ACCEPTED_ON_L2": *fs = AcceptedOnL2 - case `"ACCEPTED_ON_L1"`: + case "ACCEPTED_ON_L1": *fs = AcceptedOnL1 - case `"NOT_RECEIVED"`: + case "NOT_RECEIVED": *fs = NotReceived - case `"RECEIVED"`: + case "RECEIVED": *fs = Received default: - return errors.New("unknown FinalityStatus") + return fmt.Errorf("unknown FinalityStatus %q", str) } return nil } @@ -83,24 +83,24 @@ func (t TransactionType) String() string { } } -func (t TransactionType) MarshalJSON() ([]byte, error) { - return []byte(fmt.Sprintf("%q", t)), nil +func (t TransactionType) MarshalText() ([]byte, error) { + return []byte(t.String()), nil } -func (t *TransactionType) UnmarshalJSON(data []byte) error { - switch string(data) { - case `"DECLARE"`: +func (t *TransactionType) UnmarshalText(data []byte) error { + switch str := string(data); str { + case "DECLARE": *t = TxnDeclare - case `"DEPLOY"`: + case "DEPLOY": *t = TxnDeploy - case `"DEPLOY_ACCOUNT"`: + case "DEPLOY_ACCOUNT": *t = TxnDeployAccount - case `"INVOKE"`, `"INVOKE_FUNCTION"`: + case "INVOKE", "INVOKE_FUNCTION": *t = TxnInvoke - case `"L1_HANDLER"`: + case "L1_HANDLER": *t = TxnL1Handler default: - return errors.New("unknown TransactionType") + return fmt.Errorf("unknown TransactionType %q", str) } return nil } @@ -139,14 +139,6 @@ func (r Resource) MarshalText() ([]byte, error) { } } -func (r Resource) MarshalJSON() ([]byte, error) { - result, err := r.MarshalText() - if err != nil { - return nil, err - } - return []byte(`"` + string(result) + `"`), nil -} - type DataAvailabilityMode uint32 const ( diff --git a/starknet/transaction_test.go b/starknet/transaction_test.go index d5224106ea..e3e5f81096 100644 --- a/starknet/transaction_test.go +++ b/starknet/transaction_test.go @@ -1,6 +1,7 @@ package starknet_test import ( + "encoding/json" "testing" "github.com/NethermindEth/juno/starknet" @@ -10,22 +11,35 @@ import ( func TestUnmarshalExecutionStatus(t *testing.T) { es := new(starknet.ExecutionStatus) - require.NoError(t, es.UnmarshalJSON([]byte(`"SUCCEEDED"`))) - assert.Equal(t, starknet.Succeeded, *es) - require.NoError(t, es.UnmarshalJSON([]byte(`"REVERTED"`))) - assert.Equal(t, starknet.Reverted, *es) - - require.ErrorContains(t, es.UnmarshalJSON([]byte("ABC")), "unknown ExecutionStatus") + cases := map[string]starknet.ExecutionStatus{ + "SUCCEEDED": starknet.Succeeded, + "REVERTED": starknet.Reverted, + "REJECTED": starknet.Rejected, + } + for str, expected := range cases { + quotedStr := `"` + str + `"` + require.NoError(t, json.Unmarshal([]byte(quotedStr), es)) + assert.Equal(t, expected, *es) + } + + require.ErrorContains(t, json.Unmarshal([]byte(`"ABC"`), es), "unknown ExecutionStatus") } func TestUnmarshalFinalityStatus(t *testing.T) { fs := new(starknet.FinalityStatus) - require.NoError(t, fs.UnmarshalJSON([]byte(`"ACCEPTED_ON_L1"`))) - assert.Equal(t, starknet.AcceptedOnL1, *fs) - - require.NoError(t, fs.UnmarshalJSON([]byte(`"ACCEPTED_ON_L2"`))) - assert.Equal(t, starknet.AcceptedOnL2, *fs) - require.ErrorContains(t, fs.UnmarshalJSON([]byte("ABC")), "unknown FinalityStatus") + cases := map[string]starknet.FinalityStatus{ + "ACCEPTED_ON_L2": starknet.AcceptedOnL2, + "ACCEPTED_ON_L1": starknet.AcceptedOnL1, + "NOT_RECEIVED": starknet.NotReceived, + "RECEIVED": starknet.Received, + } + for str, expected := range cases { + quotedStr := `"` + str + `"` + require.NoError(t, json.Unmarshal([]byte(quotedStr), fs)) + assert.Equal(t, expected, *fs) + } + + require.ErrorContains(t, json.Unmarshal([]byte(`"ABC"`), fs), "unknown FinalityStatus") } diff --git a/sync/sync.go b/sync/sync.go index a2e4ac0bf0..1270193d07 100644 --- a/sync/sync.go +++ b/sync/sync.go @@ -12,6 +12,7 @@ import ( "github.com/NethermindEth/juno/core/felt" "github.com/NethermindEth/juno/db" "github.com/NethermindEth/juno/feed" + junoplugin "github.com/NethermindEth/juno/plugin" "github.com/NethermindEth/juno/service" "github.com/NethermindEth/juno/starknetdata" "github.com/NethermindEth/juno/utils" @@ -72,6 +73,7 @@ type Synchronizer struct { pendingPollInterval time.Duration catchUpMode bool + plugin junoplugin.JunoPlugin } func New(bc *blockchain.Blockchain, starkNetData starknetdata.StarknetData, @@ -89,6 +91,12 @@ func New(bc *blockchain.Blockchain, starkNetData starknetdata.StarknetData, return s } +// WithPlugin registers an plugin +func (s *Synchronizer) WithPlugin(plugin junoplugin.JunoPlugin) *Synchronizer { + s.plugin = plugin + return s +} + // WithListener registers an EventListener func (s *Synchronizer) WithListener(listener EventListener) *Synchronizer { s.listener = listener @@ -180,6 +188,49 @@ func (s *Synchronizer) fetchUnknownClasses(ctx context.Context, stateUpdate *cor return newClasses, closer() } +func (s *Synchronizer) handlePluginRevertBlock() { + fromBlock, err := s.blockchain.Head() + if err != nil { + s.log.Warnw("Failed to retrieve the reverted blockchain head block for the plugin", "err", err) + return + } + fromSU, err := s.blockchain.StateUpdateByNumber(fromBlock.Number) + if err != nil { + s.log.Warnw("Failed to retrieve the reverted blockchain head state-update for the plugin", "err", err) + return + } + reverseStateDiff, err := s.blockchain.GetReverseStateDiff() + if err != nil { + s.log.Warnw("Failed to retrieve reverse state diff", "head", fromBlock.Number, "hash", fromBlock.Hash.ShortString(), "err", err) + return + } + + var toBlockAndStateUpdate *junoplugin.BlockAndStateUpdate + if fromBlock.Number != 0 { + toBlock, err := s.blockchain.BlockByHash(fromBlock.ParentHash) + if err != nil { + s.log.Warnw("Failed to retrieve the parent block for the plugin", "err", err) + return + } + toSU, err := s.blockchain.StateUpdateByNumber(toBlock.Number) + if err != nil { + s.log.Warnw("Failed to retrieve the parents state-update for the plugin", "err", err) + return + } + toBlockAndStateUpdate = &junoplugin.BlockAndStateUpdate{ + Block: toBlock, + StateUpdate: toSU, + } + } + err = s.plugin.RevertBlock( + &junoplugin.BlockAndStateUpdate{Block: fromBlock, StateUpdate: fromSU}, + toBlockAndStateUpdate, + reverseStateDiff) + if err != nil { + s.log.Errorw("Plugin RevertBlock failure:", "err", err) + } +} + func (s *Synchronizer) verifierTask(ctx context.Context, block *core.Block, stateUpdate *core.StateUpdate, newClasses map[felt.Felt]core.Class, resetStreams context.CancelFunc, ) stream.Callback { @@ -205,6 +256,9 @@ func (s *Synchronizer) verifierTask(ctx context.Context, block *core.Block, stat // revert the head and restart the sync process, hoping that the reorg is not deep // if the reorg is deeper, we will end up here again and again until we fully revert reorged // blocks + if s.plugin != nil { + s.handlePluginRevertBlock() + } s.revertHead(block) } else { s.log.Warnw("Failed storing Block", "number", block.Number, @@ -231,6 +285,12 @@ func (s *Synchronizer) verifierTask(ctx context.Context, block *core.Block, stat s.newHeads.Send(block.Header) s.log.Infow("Stored Block", "number", block.Number, "hash", block.Hash.ShortString(), "root", block.GlobalStateRoot.ShortString()) + if s.plugin != nil { + err := s.plugin.NewBlock(block, stateUpdate, newClasses) + if err != nil { + s.log.Errorw("Plugin NewBlock failure:", err) + } + } } } } @@ -315,11 +375,8 @@ func (s *Synchronizer) revertHead(forkBlock *core.Block) { if err == nil { localHead = head.Hash } - s.log.Infow("Reorg detected", "localHead", localHead, "forkHead", forkBlock.Hash) - - err = s.blockchain.RevertHead() - if err != nil { + if err := s.blockchain.RevertHead(); err != nil { s.log.Warnw("Failed reverting HEAD", "reverted", localHead, "err", err) } else { s.log.Infow("Reverted HEAD", "reverted", localHead) diff --git a/utils/compression_test.go b/utils/compression_test.go index 647ae1c192..2aacb58c95 100644 --- a/utils/compression_test.go +++ b/utils/compression_test.go @@ -19,3 +19,13 @@ func TestGzip64(t *testing.T) { require.NoError(t, err) assert.Equal(t, bytes, decompBytes) } + +func FuzzGzip64(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + compressed, err := utils.Gzip64Encode(data) + require.NoError(t, err) + decompressed, err := utils.Gzip64Decode(compressed) + require.NoError(t, err) + assert.Equal(t, data, decompressed) + }) +} diff --git a/utils/iter/pull.go b/utils/iter/pull.go deleted file mode 100644 index 28723982e8..0000000000 --- a/utils/iter/pull.go +++ /dev/null @@ -1,34 +0,0 @@ -package iter - -import "context" - -// Pull is our implementation of iter.Pull from stdlib -// original impl - https://cs.opensource.google/go/go/+/refs/tags/go1.22rc2:src/iter/iter.go;l=56 -// Note that seq is going to be called in a separate goroutine (original impl uses private coroutine functions) -func Pull[V any](seq Seq[V]) (next func() (V, bool), stop func()) { - ctx, stop := context.WithCancel(context.Background()) - ch := make(chan V) - - // values producer for ch - go func() { - defer close(ch) - - yield := func(v V) bool { - select { - case ch <- v: - case <-ctx.Done(): - return false - } - - return true - } - seq(yield) - }() - // consumer of ch - next = func() (v V, ok bool) { - v, ok = <-ch - return - } - - return next, stop -} diff --git a/utils/iter/pull_test.go b/utils/iter/pull_test.go deleted file mode 100644 index 8a2fe84698..0000000000 --- a/utils/iter/pull_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package iter - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestPull(t *testing.T) { - t.Run("Iterate over all values", func(t *testing.T) { - it := newIterator(1, 2, 3, 4, 5) - next, _ := Pull(it) - - for i := 1; i <= 5; i++ { - v, ok := next() - assert.True(t, ok) - assert.Equal(t, i, v) - } - - v, ok := next() - assert.Zero(t, v) - assert.False(t, ok) - }) - t.Run("Iterate and stop in the middle", func(t *testing.T) { - it := newIterator(1, 2, 3, 4, 5) - next, stop := Pull(it) - - for i := 1; i <= 3; i++ { - v, ok := next() - assert.True(t, ok) - assert.Equal(t, i, v) - } - stop() - - v, ok := next() - assert.Zero(t, v) - assert.False(t, ok) - }) -} - -func newIterator[T any](values ...T) Seq[T] { - return func(yield func(T) bool) { - for _, v := range values { - if !yield(v) { - break - } - } - } -} diff --git a/utils/iter/seq.go b/utils/iter/seq.go deleted file mode 100644 index 1c5f103a3f..0000000000 --- a/utils/iter/seq.go +++ /dev/null @@ -1,6 +0,0 @@ -package iter - -type ( - Seq[V any] func(yield func(V) bool) - Seq2[K, V any] func(yield func(K, V) bool) -) diff --git a/utils/log.go b/utils/log.go index 1fc9b7d011..a38857facb 100644 --- a/utils/log.go +++ b/utils/log.go @@ -3,6 +3,7 @@ package utils import ( "encoding" "fmt" + "strings" "time" "github.com/cockroachdb/pebble" @@ -102,9 +103,7 @@ type ZapLogger struct { *zap.SugaredLogger } -const ( - traceLevel = zapcore.Level(-2) -) +const traceLevel = zapcore.Level(-2) func (l *ZapLogger) IsTraceEnabled() bool { return l.Desugar().Core().Enabled(traceLevel) @@ -112,7 +111,13 @@ func (l *ZapLogger) IsTraceEnabled() bool { func (l *ZapLogger) Tracew(msg string, keysAndValues ...interface{}) { if l.IsTraceEnabled() { - l.Debugw("[TRACE] "+msg, keysAndValues...) // Hack: we use Debug for traces + // l.WithOptions() clones logger every time there is a Tracew() call + // which may be inefficient, one possible improvement is to create + // special logger just for traces in ZapLogger with AddCallerSkip(1) + // also check this issue https://github.com/uber-go/zap/issues/930 for updates + + // AddCallerSkip(1) is necessary to skip the caller of this function + l.WithOptions(zap.AddCallerSkip(1)).Logw(traceLevel, msg, keysAndValues...) } } @@ -127,9 +132,9 @@ func NewZapLogger(logLevel LogLevel, colour bool) (*ZapLogger, error) { config := zap.NewProductionConfig() config.Sampling = nil config.Encoding = "console" - config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder + config.EncoderConfig.EncodeLevel = capitalColorLevelEncoder if !colour { - config.EncoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder + config.EncoderConfig.EncodeLevel = capitalLevelEncoder } config.EncoderConfig.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString(t.Local().Format("15:04:05.000 02/01/2006 -07:00")) @@ -158,3 +163,37 @@ func NewZapLogger(logLevel LogLevel, colour bool) (*ZapLogger, error) { func (l *ZapLogger) Warningf(msg string, args ...any) { l.Warnf(msg, args) } + +// colour (originally color) type with methods were extracted from go.uber.org/zap/internal/color +// because it's internal it's not possible to import it directly +// +//nolint:misspell +const cyan colour = 36 + +// colour represents a text colour. +type colour uint8 + +// Add adds the colouring to the given string. +func (c colour) Add(s string) string { + return fmt.Sprintf("\x1b[%dm%s\x1b[0m", uint8(c), s) +} + +// capitalColorLevelEncoder adds support for TRACE log level to the default CapitalColorLevelEncoder +func capitalColorLevelEncoder(l zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { + if l == traceLevel { + tracePrefix := strings.ToUpper(TRACE.String()) + enc.AppendString(cyan.Add(tracePrefix)) + } else { + zapcore.CapitalColorLevelEncoder(l, enc) + } +} + +// capitalLevelEncoder adds support for TRACE log level to the default CapitalLevelEncoder +func capitalLevelEncoder(l zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { + if l == traceLevel { + tracePrefix := strings.ToUpper(TRACE.String()) + enc.AppendString(tracePrefix) + } else { + zapcore.CapitalLevelEncoder(l, enc) + } +} diff --git a/utils/maps.go b/utils/maps.go index 5ed01c235e..886929ab93 100644 --- a/utils/maps.go +++ b/utils/maps.go @@ -1,23 +1,5 @@ package utils -func MapValues[K comparable, V any](m map[K]V) []V { - sl := make([]V, 0, len(m)) - for _, v := range m { - sl = append(sl, v) - } - - return sl -} - -func MapKeys[K comparable, V any](m map[K]V) []K { - sl := make([]K, 0, len(m)) - for k := range m { - sl = append(sl, k) - } - - return sl -} - func ToMap[T any, K comparable, V any](sl []T, f func(T) (K, V)) map[K]V { m := make(map[K]V, len(sl)) for _, item := range sl { diff --git a/utils/pipeline/pipeline_test.go b/utils/pipeline/pipeline_test.go index 5b5156d109..91341240f7 100644 --- a/utils/pipeline/pipeline_test.go +++ b/utils/pipeline/pipeline_test.go @@ -52,7 +52,6 @@ func TestPipeline(t *testing.T) { var chs []<-chan string for n := range nums { - n := n strCh := make(chan string) go func() { defer close(strCh) diff --git a/vm/rust/Cargo.toml b/vm/rust/Cargo.toml index 4a8588f68d..2909483444 100644 --- a/vm/rust/Cargo.toml +++ b/vm/rust/Cargo.toml @@ -6,15 +6,15 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -serde = "1.0.171" -serde_json = { version = "1.0.96", features = ["raw_value"] } -blockifier = "=0.8.0-rc.1" -starknet_api = "=0.13.0-rc.0" -cairo-vm = "=1.0.0-rc5" +serde = "1.0.208" +serde_json = { version = "1.0.125", features = ["raw_value"] } +blockifier = "0.8.0-rc.3" +starknet_api = "0.13.0-rc.1" +cairo-vm = "=1.0.1" starknet-types-core = { version = "0.1.5", features = ["hash", "prime-bigint"] } indexmap = "2.1.0" cached = "0.53.1" -once_cell = "1.18.0" +once_cell = "1.19.0" lazy_static = "1.4.0" semver = "1.0.22" anyhow = "1.0.81" diff --git a/vm/rust/src/juno_state_reader.rs b/vm/rust/src/juno_state_reader.rs index e70c83b6f2..ee4ad9734d 100644 --- a/vm/rust/src/juno_state_reader.rs +++ b/vm/rust/src/juno_state_reader.rs @@ -1,5 +1,5 @@ use std::{ - ffi::{c_char, c_uchar, c_void, CStr}, + ffi::{c_char, c_int, c_uchar, c_void, CStr}, slice, sync::Mutex, }; @@ -31,15 +31,18 @@ extern "C" { reader_handle: usize, contract_address: *const c_uchar, storage_location: *const c_uchar, - ) -> *const c_uchar; + buffer: *mut c_uchar, + ) -> c_int; fn JunoStateGetNonceAt( reader_handle: usize, contract_address: *const c_uchar, - ) -> *const c_uchar; + buffer: *mut c_uchar, + ) -> c_int; fn JunoStateGetClassHashAt( reader_handle: usize, contract_address: *const c_uchar, - ) -> *const c_uchar; + buffer: *mut c_uchar, + ) -> c_int; fn JunoStateGetCompiledClass(reader_handle: usize, class_hash: *const c_uchar) -> *const c_char; } @@ -71,19 +74,24 @@ impl StateReader for JunoStateReader { ) -> StateResult { let addr = felt_to_byte_array(contract_address.0.key()); let storage_key = felt_to_byte_array(key.0.key()); - let ptr = - unsafe { JunoStateGetStorageAt(self.handle, addr.as_ptr(), storage_key.as_ptr()) }; - if ptr.is_null() { + let mut buffer: [u8; 32] = [0; 32]; + let wrote = unsafe { + JunoStateGetStorageAt( + self.handle, + addr.as_ptr(), + storage_key.as_ptr(), + buffer.as_mut_ptr(), + ) + }; + if wrote == 0 { Err(StateError::StateReadError(format!( "failed to read location {} at address {}", key.0.key(), contract_address.0.key() ))) } else { - let felt_val = ptr_to_felt(ptr); - unsafe { JunoFree(ptr as *const c_void) }; - - Ok(felt_val) + assert!(wrote == 32, "Juno didn't write 32 bytes"); + Ok(StarkFelt::from_bytes_be(&buffer)) } } @@ -91,16 +99,16 @@ impl StateReader for JunoStateReader { /// Default: 0 for an uninitialized contract address. fn get_nonce_at(&self, contract_address: ContractAddress) -> StateResult { let addr = felt_to_byte_array(contract_address.0.key()); - let ptr = unsafe { JunoStateGetNonceAt(self.handle, addr.as_ptr()) }; - if ptr.is_null() { + let mut buffer: [u8; 32] = [0; 32]; + let wrote = unsafe { JunoStateGetNonceAt(self.handle, addr.as_ptr(), buffer.as_mut_ptr()) }; + if wrote == 0 { Err(StateError::StateReadError(format!( "failed to read nonce of address {}", contract_address.0.key() ))) } else { - let felt_val = ptr_to_felt(ptr); - unsafe { JunoFree(ptr as *const c_void) }; - Ok(Nonce(felt_val)) + assert!(wrote == 32, "Juno didn't write 32 bytes"); + Ok(Nonce(StarkFelt::from_bytes_be(&buffer))) } } @@ -108,17 +116,17 @@ impl StateReader for JunoStateReader { /// Default: 0 (uninitialized class hash) for an uninitialized contract address. fn get_class_hash_at(&self, contract_address: ContractAddress) -> StateResult { let addr = felt_to_byte_array(contract_address.0.key()); - let ptr = unsafe { JunoStateGetClassHashAt(self.handle, addr.as_ptr()) }; - if ptr.is_null() { + let mut buffer: [u8; 32] = [0; 32]; + let wrote = + unsafe { JunoStateGetClassHashAt(self.handle, addr.as_ptr(), buffer.as_mut_ptr()) }; + if wrote == 0 { Err(StateError::StateReadError(format!( "failed to read class hash of address {}", contract_address.0.key() ))) } else { - let felt_val = ptr_to_felt(ptr); - unsafe { JunoFree(ptr as *const c_void) }; - - Ok(ClassHash(felt_val)) + assert!(wrote == 32, "Juno didn't write 32 bytes"); + Ok(ClassHash(StarkFelt::from_bytes_be(&buffer))) } } @@ -207,19 +215,17 @@ pub fn class_info_from_json_str(raw_json: &str) -> Result VersionedConstants { CONSTANTS.get(&"0.13.1".to_string()).unwrap().to_owned() } else if version < StarknetVersion::from_str("0.13.2").unwrap() { CONSTANTS.get(&"0.13.1.1".to_string()).unwrap().to_owned() + } else if version < StarknetVersion::from_str("0.13.2.1").unwrap() { + CONSTANTS.get(&"0.13.2".to_string()).unwrap().to_owned() } else { VersionedConstants::latest_constants().to_owned() } diff --git a/vm/rust/versioned_constants_13_0.json b/vm/rust/versioned_constants_13_0.json index 1531f6fc13..103ea7fca0 100644 --- a/vm/rust/versioned_constants_13_0.json +++ b/vm/rust/versioned_constants_13_0.json @@ -5,6 +5,7 @@ }, "invoke_tx_max_n_steps": 3000000, "max_recursion_depth": 50, + "segment_arena_cells": true, "os_constants": { "nop_entry_point_offset": -1, "entry_point_type_external": 0, diff --git a/vm/rust/versioned_constants_13_1.json b/vm/rust/versioned_constants_13_1.json index 4e28f7b711..279612a501 100644 --- a/vm/rust/versioned_constants_13_1.json +++ b/vm/rust/versioned_constants_13_1.json @@ -24,6 +24,7 @@ ] }, "max_recursion_depth": 50, + "segment_arena_cells": true, "os_constants": { "nop_entry_point_offset": -1, "entry_point_type_external": 0, diff --git a/vm/rust/versioned_constants_13_1_1.json b/vm/rust/versioned_constants_13_1_1.json index 791dac8b9b..a80475fa16 100644 --- a/vm/rust/versioned_constants_13_1_1.json +++ b/vm/rust/versioned_constants_13_1_1.json @@ -24,6 +24,7 @@ ] }, "max_recursion_depth": 50, + "segment_arena_cells": true, "os_constants": { "nop_entry_point_offset": -1, "entry_point_type_external": 0, diff --git a/vm/rust/versioned_constants_13_2.json b/vm/rust/versioned_constants_13_2.json new file mode 100644 index 0000000000..b6a12cee8d --- /dev/null +++ b/vm/rust/versioned_constants_13_2.json @@ -0,0 +1,608 @@ +{ + "tx_event_limits": { + "max_data_length": 300, + "max_keys_length": 50, + "max_n_emitted_events": 1000 + }, + "gateway": { + "max_calldata_length": 5000, + "max_contract_bytecode_size": 81920 + }, + "invoke_tx_max_n_steps": 10000000, + "l2_resource_gas_costs": { + "gas_per_data_felt": [ + 128, + 1000 + ], + "event_key_factor": [ + 2, + 1 + ], + "gas_per_code_byte": [ + 875, + 1000 + ] + }, + "disable_cairo0_redeclaration": true, + "max_recursion_depth": 50, + "segment_arena_cells": false, + "os_constants": { + "block_hash_contract_address": 1, + "call_contract_gas_cost": { + "entry_point_gas_cost": 1, + "step_gas_cost": 10, + "syscall_base_gas_cost": 1 + }, + "constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "default_entry_point_selector": 0, + "deploy_gas_cost": { + "entry_point_gas_cost": 1, + "step_gas_cost": 200, + "syscall_base_gas_cost": 1 + }, + "emit_event_gas_cost": { + "step_gas_cost": 10, + "syscall_base_gas_cost": 1 + }, + "entry_point_gas_cost": { + "entry_point_initial_budget": 1, + "step_gas_cost": 500 + }, + "entry_point_initial_budget": { + "step_gas_cost": 100 + }, + "entry_point_type_constructor": 2, + "entry_point_type_external": 0, + "entry_point_type_l1_handler": 1, + "error_block_number_out_of_range": "Block number out of range", + "error_invalid_input_len": "Invalid input length", + "error_invalid_argument": "Invalid argument", + "error_out_of_gas": "Out of gas", + "execute_entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", + "fee_transfer_gas_cost": { + "entry_point_gas_cost": 1, + "step_gas_cost": 100 + }, + "get_block_hash_gas_cost": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "get_execution_info_gas_cost": { + "step_gas_cost": 10, + "syscall_base_gas_cost": 1 + }, + "initial_gas_cost": { + "step_gas_cost": 100000000 + }, + "keccak_gas_cost": { + "syscall_base_gas_cost": 1 + }, + "keccak_round_cost_gas_cost": 180000, + "l1_gas": "L1_GAS", + "l1_gas_index": 0, + "l1_handler_version": 0, + "l2_gas": "L2_GAS", + "l2_gas_index": 1, + "library_call_gas_cost": { + "call_contract_gas_cost": 1 + }, + "sha256_process_block_gas_cost": { + "step_gas_cost": 1852, + "range_check_gas_cost": 65, + "bitwise_builtin_gas_cost": 1115, + "syscall_base_gas_cost": 1 + }, + "memory_hole_gas_cost": 10, + "nop_entry_point_offset": -1, + "range_check_gas_cost": 70, + "bitwise_builtin_gas_cost": 594, + "replace_class_gas_cost": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "secp256k1_add_gas_cost": { + "range_check_gas_cost": 29, + "step_gas_cost": 406 + }, + "secp256k1_get_point_from_x_gas_cost": { + "memory_hole_gas_cost": 20, + "range_check_gas_cost": 30, + "step_gas_cost": 391 + }, + "secp256k1_get_xy_gas_cost": { + "memory_hole_gas_cost": 40, + "range_check_gas_cost": 11, + "step_gas_cost": 239 + }, + "secp256k1_mul_gas_cost": { + "memory_hole_gas_cost": 2, + "range_check_gas_cost": 7045, + "step_gas_cost": 76501 + }, + "secp256k1_new_gas_cost": { + "memory_hole_gas_cost": 40, + "range_check_gas_cost": 35, + "step_gas_cost": 475 + }, + "secp256r1_add_gas_cost": { + "range_check_gas_cost": 57, + "step_gas_cost": 589 + }, + "secp256r1_get_point_from_x_gas_cost": { + "memory_hole_gas_cost": 20, + "range_check_gas_cost": 44, + "step_gas_cost": 510 + }, + "secp256r1_get_xy_gas_cost": { + "memory_hole_gas_cost": 40, + "range_check_gas_cost": 11, + "step_gas_cost": 241 + }, + "secp256r1_mul_gas_cost": { + "memory_hole_gas_cost": 2, + "range_check_gas_cost": 13961, + "step_gas_cost": 125340 + }, + "secp256r1_new_gas_cost": { + "memory_hole_gas_cost": 40, + "range_check_gas_cost": 49, + "step_gas_cost": 594 + }, + "send_message_to_l1_gas_cost": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "sierra_array_len_bound": 4294967296, + "step_gas_cost": 100, + "storage_read_gas_cost": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "storage_write_gas_cost": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "stored_block_hash_buffer": 10, + "syscall_base_gas_cost": { + "step_gas_cost": 100 + }, + "transaction_gas_cost": { + "entry_point_gas_cost": 2, + "fee_transfer_gas_cost": 1, + "step_gas_cost": 100 + }, + "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", + "validate_declare_entry_point_selector": "0x289da278a8dc833409cabfdad1581e8e7d40e42dcaed693fa4008dcdb4963b3", + "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", + "validate_entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", + "validate_rounding_consts": { + "validate_block_number_rounding": 100, + "validate_timestamp_rounding": 3600 + }, + "validated": "VALID" + }, + "os_resources": { + "execute_syscalls": { + "CallContract": { + "n_steps": 827, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "DelegateCall": { + "n_steps": 713, + "builtin_instance_counter": { + "range_check_builtin": 19 + }, + "n_memory_holes": 0 + }, + "DelegateL1Handler": { + "n_steps": 692, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "Deploy": { + "n_steps": 1097, + "builtin_instance_counter": { + "pedersen_builtin": 7, + "range_check_builtin": 18 + }, + "n_memory_holes": 0 + }, + "EmitEvent": { + "n_steps": 61, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetBlockHash": { + "n_steps": 104, + "builtin_instance_counter": { + "range_check_builtin": 2 + }, + "n_memory_holes": 0 + }, + "GetBlockNumber": { + "n_steps": 40, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetBlockTimestamp": { + "n_steps": 38, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetCallerAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetContractAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetExecutionInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetSequencerAddress": { + "n_steps": 34, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetTxInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetTxSignature": { + "n_steps": 44, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "Keccak": { + "n_steps": 381, + "builtin_instance_counter": { + "bitwise_builtin": 6, + "keccak_builtin": 1, + "range_check_builtin": 56 + }, + "n_memory_holes": 0 + }, + "LibraryCall": { + "n_steps": 818, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "LibraryCallL1Handler": { + "n_steps": 659, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "ReplaceClass": { + "n_steps": 98, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Secp256k1Add": { + "n_steps": 410, + "builtin_instance_counter": { + "range_check_builtin": 29 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetPointFromX": { + "n_steps": 395, + "builtin_instance_counter": { + "range_check_builtin": 30 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetXy": { + "n_steps": 207, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256k1Mul": { + "n_steps": 76505, + "builtin_instance_counter": { + "range_check_builtin": 7045 + }, + "n_memory_holes": 0 + }, + "Secp256k1New": { + "n_steps": 461, + "builtin_instance_counter": { + "range_check_builtin": 35 + }, + "n_memory_holes": 0 + }, + "Secp256r1Add": { + "n_steps": 593, + "builtin_instance_counter": { + "range_check_builtin": 57 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetPointFromX": { + "n_steps": 514, + "builtin_instance_counter": { + "range_check_builtin": 44 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetXy": { + "n_steps": 209, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256r1Mul": { + "n_steps": 125344, + "builtin_instance_counter": { + "range_check_builtin": 13961 + }, + "n_memory_holes": 0 + }, + "Secp256r1New": { + "n_steps": 580, + "builtin_instance_counter": { + "range_check_builtin": 49 + }, + "n_memory_holes": 0 + }, + "SendMessageToL1": { + "n_steps": 141, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Sha256ProcessBlock": { + "n_steps": 1855, + "builtin_instance_counter": { + "range_check_builtin": 65, + "bitwise_builtin": 1115 + }, + "n_memory_holes": 0 + }, + "StorageRead": { + "n_steps": 87, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "StorageWrite": { + "n_steps": 89, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "execute_txs_inner": { + "Declare": { + "deprecated_resources": { + "constant": { + "n_steps": 2973, + "builtin_instance_counter": { + "pedersen_builtin": 16, + "range_check_builtin": 53 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 3079, + "builtin_instance_counter": { + "pedersen_builtin": 4, + "range_check_builtin": 58, + "poseidon_builtin": 10 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + } + }, + "DeployAccount": { + "deprecated_resources": { + "constant": { + "n_steps": 4015, + "builtin_instance_counter": { + "pedersen_builtin": 23, + "range_check_builtin": 72 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 4137, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 77, + "poseidon_builtin": 10 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + } + }, + "InvokeFunction": { + "deprecated_resources": { + "constant": { + "n_steps": 3763, + "builtin_instance_counter": { + "pedersen_builtin": 14, + "range_check_builtin": 69 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 3904, + "builtin_instance_counter": { + "pedersen_builtin": 4, + "range_check_builtin": 74, + "poseidon_builtin": 11 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + }, + "L1Handler": { + "deprecated_resources": { + "constant": { + "n_steps": 1233, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 16 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + } + }, + "compute_os_kzg_commitment_info": { + "n_steps": 113, + "builtin_instance_counter": { + "range_check_builtin": 17 + }, + "n_memory_holes": 0 + } + }, + "validate_max_n_steps": 1000000, + "vm_resource_fee_cost": { + "add_mod_builtin": [ + 4, + 100 + ], + "bitwise_builtin": [ + 16, + 100 + ], + "ec_op_builtin": [ + 256, + 100 + ], + "ecdsa_builtin": [ + 512, + 100 + ], + "keccak_builtin": [ + 512, + 100 + ], + "mul_mod_builtin": [ + 4, + 100 + ], + "n_steps": [ + 25, + 10000 + ], + "output_builtin": [ + 0, + 1 + ], + "pedersen_builtin": [ + 8, + 100 + ], + "poseidon_builtin": [ + 8, + 100 + ], + "range_check_builtin": [ + 4, + 100 + ], + "range_check96_builtin": [ + 4, + 100 + ] + } +} diff --git a/vm/state_reader.go b/vm/state_reader.go index d0d7cf8cba..4ce85663ea 100644 --- a/vm/state_reader.go +++ b/vm/state_reader.go @@ -18,7 +18,7 @@ func JunoFree(ptr unsafe.Pointer) { } //export JunoStateGetStorageAt -func JunoStateGetStorageAt(readerHandle C.uintptr_t, contractAddress, storageLocation unsafe.Pointer) unsafe.Pointer { +func JunoStateGetStorageAt(readerHandle C.uintptr_t, contractAddress, storageLocation, buffer unsafe.Pointer) C.int { context := unwrapContext(readerHandle) contractAddressFelt := makeFeltFromPtr(contractAddress) @@ -27,16 +27,16 @@ func JunoStateGetStorageAt(readerHandle C.uintptr_t, contractAddress, storageLoc if err != nil { if !errors.Is(err, db.ErrKeyNotFound) { context.log.Errorw("JunoStateGetStorageAt failed to read contract storage", "err", err) - return nil + return 0 } val = &felt.Zero } - return makePtrFromFelt(val) + return fillBufferWithFelt(val, buffer) } //export JunoStateGetNonceAt -func JunoStateGetNonceAt(readerHandle C.uintptr_t, contractAddress unsafe.Pointer) unsafe.Pointer { +func JunoStateGetNonceAt(readerHandle C.uintptr_t, contractAddress, buffer unsafe.Pointer) C.int { context := unwrapContext(readerHandle) contractAddressFelt := makeFeltFromPtr(contractAddress) @@ -44,16 +44,16 @@ func JunoStateGetNonceAt(readerHandle C.uintptr_t, contractAddress unsafe.Pointe if err != nil { if !errors.Is(err, db.ErrKeyNotFound) { context.log.Errorw("JunoStateGetNonceAt failed to read contract nonce", "err", err) - return nil + return 0 } val = &felt.Zero } - return makePtrFromFelt(val) + return fillBufferWithFelt(val, buffer) } //export JunoStateGetClassHashAt -func JunoStateGetClassHashAt(readerHandle C.uintptr_t, contractAddress unsafe.Pointer) unsafe.Pointer { +func JunoStateGetClassHashAt(readerHandle C.uintptr_t, contractAddress, buffer unsafe.Pointer) C.int { context := unwrapContext(readerHandle) contractAddressFelt := makeFeltFromPtr(contractAddress) @@ -61,12 +61,12 @@ func JunoStateGetClassHashAt(readerHandle C.uintptr_t, contractAddress unsafe.Po if err != nil { if !errors.Is(err, db.ErrKeyNotFound) { context.log.Errorw("JunoStateGetClassHashAt failed to read contract class", "err", err) - return nil + return 0 } val = &felt.Zero } - return makePtrFromFelt(val) + return fillBufferWithFelt(val, buffer) } //export JunoStateGetCompiledClass @@ -90,3 +90,8 @@ func JunoStateGetCompiledClass(readerHandle C.uintptr_t, classHash unsafe.Pointe return unsafe.Pointer(cstring(compiledClass)) } + +func fillBufferWithFelt(val *felt.Felt, buffer unsafe.Pointer) C.int { + feltBytes := val.Bytes() + return C.int(copy(unsafe.Slice((*byte)(buffer), felt.Bytes), feltBytes[:])) +} diff --git a/vm/trace.go b/vm/trace.go index f17257ff41..82a4c9fb75 100644 --- a/vm/trace.go +++ b/vm/trace.go @@ -5,7 +5,6 @@ import ( "errors" "slices" - "github.com/NethermindEth/juno/core" "github.com/NethermindEth/juno/core/felt" ) @@ -235,6 +234,7 @@ type ComputationResources struct { AddMod uint64 `json:"add_mod_builtin,omitempty"` MulMod uint64 `json:"mul_mod_builtin,omitempty"` RangeCheck96 uint64 `json:"range_check_96_builtin,omitempty"` + Output uint64 `json:"output_builtin,omitempty"` } type DataAvailability struct { @@ -246,16 +246,3 @@ type ExecutionResources struct { ComputationResources DataAvailability *DataAvailability `json:"data_availability,omitempty"` } - -func NewDataAvailability(gasConsumed, dataGasConsumed *felt.Felt, mode core.L1DAMode) *DataAvailability { - da := &DataAvailability{} - - switch mode { - case core.Calldata: - da.L1Gas = gasConsumed.Uint64() - case core.Blob: - da.L1DataGas = dataGasConsumed.Uint64() - } - - return da -} diff --git a/vm/vm.go b/vm/vm.go index a55d3e297c..e3b0bdd90e 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -39,8 +39,8 @@ extern void cairoVMExecute(char* txns_json, char* classes_json, char* paid_fees_ extern char* setVersionedConstants(char* json); extern void freeString(char* str); -#cgo vm_debug LDFLAGS: -L./rust/target/debug -ljuno_starknet_rs -#cgo !vm_debug LDFLAGS: -L./rust/target/release -ljuno_starknet_rs +#cgo vm_debug LDFLAGS: -L./rust/target/debug -ljuno_starknet_rs -lbz2 +#cgo !vm_debug LDFLAGS: -L./rust/target/release -ljuno_starknet_rs -lbz2 */ import "C" @@ -62,10 +62,10 @@ import ( //go:generate mockgen -destination=../mocks/mock_vm.go -package=mocks github.com/NethermindEth/juno/vm VM type VM interface { Call(callInfo *CallInfo, blockInfo *BlockInfo, state core.StateReader, network *utils.Network, - maxSteps uint64, useBlobData bool) ([]*felt.Felt, error) + maxSteps uint64) ([]*felt.Felt, error) Execute(txns []core.Transaction, declaredClasses []core.Class, paidFeesOnL1 []*felt.Felt, blockInfo *BlockInfo, - state core.StateReader, network *utils.Network, skipChargeFee, skipValidate, errOnRevert, useBlobData bool, - ) ([]*felt.Felt, []*felt.Felt, []TransactionTrace, error) + state core.StateReader, network *utils.Network, skipChargeFee, skipValidate, errOnRevert bool, + ) ([]*felt.Felt, []core.GasConsumed, []TransactionTrace, uint64, error) } type vm struct { @@ -92,9 +92,10 @@ type callContext struct { // response from the executed Cairo function response []*felt.Felt // fee amount taken per transaction during VM execution - actualFees []*felt.Felt - traces []json.RawMessage - dataGasConsumed []*felt.Felt + actualFees []*felt.Felt + traces []json.RawMessage + daGas []core.GasConsumed + executionSteps uint64 } func unwrapContext(readerHandle C.uintptr_t) *callContext { @@ -132,20 +133,23 @@ func JunoAppendActualFee(readerHandle C.uintptr_t, ptr unsafe.Pointer) { context.actualFees = append(context.actualFees, makeFeltFromPtr(ptr)) } -//export JunoAppendDataGasConsumed -func JunoAppendDataGasConsumed(readerHandle C.uintptr_t, ptr unsafe.Pointer) { +//export JunoAppendGasConsumed +func JunoAppendGasConsumed(readerHandle C.uintptr_t, ptr, ptr2 unsafe.Pointer) { context := unwrapContext(readerHandle) - context.dataGasConsumed = append(context.dataGasConsumed, makeFeltFromPtr(ptr)) + context.daGas = append(context.daGas, core.GasConsumed{ + L1Gas: makeFeltFromPtr(ptr).Uint64(), + L1DataGas: makeFeltFromPtr(ptr2).Uint64(), + }) } -func makeFeltFromPtr(ptr unsafe.Pointer) *felt.Felt { - return new(felt.Felt).SetBytes(C.GoBytes(ptr, felt.Bytes)) +//export JunoAddExecutionSteps +func JunoAddExecutionSteps(readerHandle C.uintptr_t, execSteps C.ulonglong) { + context := unwrapContext(readerHandle) + context.executionSteps += uint64(execSteps) } -func makePtrFromFelt(val *felt.Felt) unsafe.Pointer { - feltBytes := val.Bytes() - //nolint:gocritic - return C.CBytes(feltBytes[:]) +func makeFeltFromPtr(ptr unsafe.Pointer) *felt.Felt { + return new(felt.Felt).SetBytes(C.GoBytes(ptr, felt.Bytes)) } type CallInfo struct { @@ -196,7 +200,7 @@ func makeCCallInfo(callInfo *CallInfo) (C.CallInfo, runtime.Pinner) { return cCallInfo, pinner } -func makeCBlockInfo(blockInfo *BlockInfo, useBlobData bool) C.BlockInfo { +func makeCBlockInfo(blockInfo *BlockInfo) C.BlockInfo { var cBlockInfo C.BlockInfo cBlockInfo.block_number = C.ulonglong(blockInfo.Header.Number) @@ -209,17 +213,13 @@ func makeCBlockInfo(blockInfo *BlockInfo, useBlobData bool) C.BlockInfo { if blockInfo.Header.L1DAMode == core.Blob { copyFeltIntoCArray(blockInfo.Header.L1DataGasPrice.PriceInWei, &cBlockInfo.data_gas_price_wei[0]) copyFeltIntoCArray(blockInfo.Header.L1DataGasPrice.PriceInFri, &cBlockInfo.data_gas_price_fri[0]) - if useBlobData { - cBlockInfo.use_blob_data = 1 - } else { - cBlockInfo.use_blob_data = 0 - } + cBlockInfo.use_blob_data = 1 } return cBlockInfo } func (v *vm) Call(callInfo *CallInfo, blockInfo *BlockInfo, state core.StateReader, - network *utils.Network, maxSteps uint64, useBlobData bool, + network *utils.Network, maxSteps uint64, ) ([]*felt.Felt, error) { context := &callContext{ state: state, @@ -236,7 +236,7 @@ func (v *vm) Call(callInfo *CallInfo, blockInfo *BlockInfo, state core.StateRead C.setVersionedConstants(C.CString("my_json")) cCallInfo, callInfoPinner := makeCCallInfo(callInfo) - cBlockInfo := makeCBlockInfo(blockInfo, useBlobData) + cBlockInfo := makeCBlockInfo(blockInfo) chainID := C.CString(network.L2ChainID) C.cairoVMCall( &cCallInfo, @@ -259,8 +259,8 @@ func (v *vm) Call(callInfo *CallInfo, blockInfo *BlockInfo, state core.StateRead // Execute executes a given transaction set and returns the gas spent per transaction func (v *vm) Execute(txns []core.Transaction, declaredClasses []core.Class, paidFeesOnL1 []*felt.Felt, blockInfo *BlockInfo, state core.StateReader, network *utils.Network, - skipChargeFee, skipValidate, errOnRevert, useBlobData bool, -) ([]*felt.Felt, []*felt.Felt, []TransactionTrace, error) { + skipChargeFee, skipValidate, errOnRevert bool, +) ([]*felt.Felt, []core.GasConsumed, []TransactionTrace, uint64, error) { context := &callContext{ state: state, log: v.log, @@ -270,12 +270,12 @@ func (v *vm) Execute(txns []core.Transaction, declaredClasses []core.Class, paid txnsJSON, classesJSON, err := marshalTxnsAndDeclaredClasses(txns, declaredClasses) if err != nil { - return nil, nil, nil, err + return nil, nil, nil, 0, err } paidFeesOnL1Bytes, err := json.Marshal(paidFeesOnL1) if err != nil { - return nil, nil, nil, err + return nil, nil, nil, 0, err } paidFeesOnL1CStr := cstring(paidFeesOnL1Bytes) @@ -302,7 +302,7 @@ func (v *vm) Execute(txns []core.Transaction, declaredClasses []core.Class, paid concurrencyModeByte = 1 } - cBlockInfo := makeCBlockInfo(blockInfo, useBlobData) + cBlockInfo := makeCBlockInfo(blockInfo) chainID := C.CString(network.L2ChainID) C.cairoVMExecute(txnsJSONCstr, classesJSONCStr, @@ -324,23 +324,21 @@ func (v *vm) Execute(txns []core.Transaction, declaredClasses []core.Class, paid if context.err != "" { if context.errTxnIndex >= 0 { - return nil, nil, nil, TransactionExecutionError{ + return nil, nil, nil, 0, TransactionExecutionError{ Index: uint64(context.errTxnIndex), Cause: errors.New(context.err), } } - return nil, nil, nil, errors.New(context.err) + return nil, nil, nil, 0, errors.New(context.err) } traces := make([]TransactionTrace, len(context.traces)) for index, traceJSON := range context.traces { if err := json.Unmarshal(traceJSON, &traces[index]); err != nil { - return nil, nil, nil, fmt.Errorf("unmarshal trace: %v", err) + return nil, nil, nil, 0, fmt.Errorf("unmarshal trace: %v", err) } - // } - - return context.actualFees, context.dataGasConsumed, traces, nil + return context.actualFees, context.daGas, traces, context.executionSteps, nil } func marshalTxnsAndDeclaredClasses(txns []core.Transaction, declaredClasses []core.Class) (json.RawMessage, json.RawMessage, error) { //nolint:lll diff --git a/vm/vm_test.go b/vm/vm_test.go index 63c830debb..00832b6063 100644 --- a/vm/vm_test.go +++ b/vm/vm_test.go @@ -54,7 +54,7 @@ func TestV0Call(t *testing.T) { ContractAddress: contractAddr, ClassHash: classHash, Selector: entryPoint, - }, &BlockInfo{Header: &core.Header{}}, testState, &utils.Mainnet, 1_000_000, true) + }, &BlockInfo{Header: &core.Header{}}, testState, &utils.Mainnet, 1_000_000) require.NoError(t, err) assert.Equal(t, []*felt.Felt{&felt.Zero}, ret) @@ -74,7 +74,7 @@ func TestV0Call(t *testing.T) { ContractAddress: contractAddr, ClassHash: classHash, Selector: entryPoint, - }, &BlockInfo{Header: &core.Header{Number: 1}}, testState, &utils.Mainnet, 1_000_000, true) + }, &BlockInfo{Header: &core.Header{Number: 1}}, testState, &utils.Mainnet, 1_000_000) require.NoError(t, err) assert.Equal(t, []*felt.Felt{new(felt.Felt).SetUint64(1337)}, ret) } @@ -122,7 +122,7 @@ func TestV1Call(t *testing.T) { Calldata: []felt.Felt{ *storageLocation, }, - }, &BlockInfo{Header: &core.Header{}}, testState, &utils.Goerli, 1_000_000, true) + }, &BlockInfo{Header: &core.Header{}}, testState, &utils.Goerli, 1_000_000) require.NoError(t, err) assert.Equal(t, []*felt.Felt{&felt.Zero}, ret) @@ -144,7 +144,7 @@ func TestV1Call(t *testing.T) { Calldata: []felt.Felt{ *storageLocation, }, - }, &BlockInfo{Header: &core.Header{Number: 1}}, testState, &utils.Goerli, 1_000_000, true) + }, &BlockInfo{Header: &core.Header{Number: 1}}, testState, &utils.Goerli, 1_000_000) require.NoError(t, err) assert.Equal(t, []*felt.Felt{new(felt.Felt).SetUint64(37)}, ret) } @@ -186,7 +186,7 @@ func TestCall_MaxSteps(t *testing.T) { ContractAddress: contractAddr, ClassHash: classHash, Selector: entryPoint, - }, &BlockInfo{Header: &core.Header{}}, testState, &utils.Mainnet, 0, true) + }, &BlockInfo{Header: &core.Header{}}, testState, &utils.Mainnet, 0) assert.ErrorContains(t, err, "RunResources has no remaining steps") } @@ -203,7 +203,7 @@ func TestExecute(t *testing.T) { state := core.NewState(txn) t.Run("empty transaction list", func(t *testing.T) { - _, _, _, err := New(false, nil).Execute([]core.Transaction{}, []core.Class{}, []*felt.Felt{}, &BlockInfo{ + _, _, _, _, err := New(false, nil).Execute([]core.Transaction{}, []core.Class{}, []*felt.Felt{}, &BlockInfo{ Header: &core.Header{ Timestamp: 1666877926, SequencerAddress: utils.HexToFelt(t, "0x46a89ae102987331d369645031b49c27738ed096f2789c24449966da4c6de6b"), @@ -211,17 +211,17 @@ func TestExecute(t *testing.T) { GasPriceSTRK: &felt.Zero, }, }, state, - &network, false, false, false, false) + &network, false, false, false) require.NoError(t, err) }) t.Run("zero data", func(t *testing.T) { - _, _, _, err := New(false, nil).Execute(nil, nil, []*felt.Felt{}, &BlockInfo{ + _, _, _, _, err := New(false, nil).Execute(nil, nil, []*felt.Felt{}, &BlockInfo{ Header: &core.Header{ SequencerAddress: &felt.Zero, GasPrice: &felt.Zero, GasPriceSTRK: &felt.Zero, }, - }, state, &network, false, false, false, false) + }, state, &network, false, false, false) require.NoError(t, err) }) }