diff --git a/.github/workflows/l2geth_ci.yml b/.github/workflows/l2geth_ci.yml index c7b6c8a831..a6fe47d7b9 100644 --- a/.github/workflows/l2geth_ci.yml +++ b/.github/workflows/l2geth_ci.yml @@ -20,7 +20,7 @@ jobs: - name: Install Go uses: actions/setup-go@v2 with: - go-version: 1.18.x + go-version: 1.20.x - name: Checkout code uses: actions/checkout@v2 - name: Build @@ -33,7 +33,7 @@ jobs: - name: Install Go uses: actions/setup-go@v2 with: - go-version: 1.19.x + go-version: 1.20.x - name: Install rust uses: actions-rs/toolchain@v1 with: @@ -55,7 +55,7 @@ jobs: - name: Install Go uses: actions/setup-go@v2 with: - go-version: 1.18.x + go-version: 1.20.x - name: Checkout code uses: actions/checkout@v2 - name: Lint @@ -69,7 +69,7 @@ jobs: - name: Install Go uses: actions/setup-go@v2 with: - go-version: 1.18.x + go-version: 1.20.x - name: Install goimports run: go install golang.org/x/tools/cmd/goimports@latest - name: Checkout code @@ -89,7 +89,7 @@ jobs: - name: Install Go uses: actions/setup-go@v2 with: - go-version: 1.18.x + go-version: 1.20.x - name: Checkout code uses: actions/checkout@v2 - name: Test diff --git a/.golangci.yml b/.golangci.yml index 22d42292ee..5ed0a9ebfa 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -13,8 +13,8 @@ linters: disable-all: true enable: - deadcode - - goconst - - goimports + # - goconst + # - goimports - gosimple - govet - ineffassign diff --git a/Dockerfile b/Dockerfile index c5fa6f76ee..025b1f6f56 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ ARG VERSION="" ARG BUILDNUM="" # Build libzkp dependency -FROM scrolltech/go-rust-builder:go-1.19-rust-nightly-2022-12-10 as chef +FROM scrolltech/go-rust-builder:go-1.20-rust-nightly-2022-12-10 as chef WORKDIR app FROM chef as planner @@ -21,7 +21,7 @@ RUN cargo build --release RUN find ./ | grep libzktrie.so | xargs -I{} cp {} /app/target/release/ # Build Geth in a stock Go builder container -FROM scrolltech/go-rust-builder:go-1.19-rust-nightly-2022-12-10 as builder +FROM scrolltech/go-rust-builder:go-1.20-rust-nightly-2022-12-10 as builder ADD . /go-ethereum COPY --from=zkp-builder /app/target/release/libzkp.so /usr/local/lib/ diff --git a/Dockerfile.alltools b/Dockerfile.alltools index 1cd9ad9ad4..3529b98b54 100644 --- a/Dockerfile.alltools +++ b/Dockerfile.alltools @@ -4,7 +4,7 @@ ARG VERSION="" ARG BUILDNUM="" # Build Geth in a stock Go builder container -FROM golang:1.19-alpine as builder +FROM golang:1.20-alpine as builder RUN apk add --no-cache gcc musl-dev linux-headers git diff --git a/Dockerfile.mockccc b/Dockerfile.mockccc index dd71826118..729e4ee1ac 100644 --- a/Dockerfile.mockccc +++ b/Dockerfile.mockccc @@ -4,7 +4,7 @@ ARG VERSION="" ARG BUILDNUM="" # Build Geth in a stock Go builder container -FROM scrolltech/go-rust-builder:go-1.19-rust-nightly-2022-12-10 as builder +FROM scrolltech/go-rust-builder:go-1.20-rust-nightly-2022-12-10 as builder ADD . /go-ethereum RUN cd /go-ethereum && env GO111MODULE=on go run build/ci.go install ./cmd/geth diff --git a/Dockerfile.mockccc.alpine b/Dockerfile.mockccc.alpine index ec46f60773..77dde0b6c4 100644 --- a/Dockerfile.mockccc.alpine +++ b/Dockerfile.mockccc.alpine @@ -4,7 +4,7 @@ ARG VERSION="" ARG BUILDNUM="" # Build Geth in a stock Go builder container -FROM golang:1.18-alpine as builder +FROM golang:1.20-alpine as builder RUN apk add --no-cache gcc musl-dev linux-headers git diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 83eefabc2a..f6919557fc 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -79,7 +79,7 @@ type SimulatedBackend struct { func NewSimulatedBackendWithDatabase(database ethdb.Database, alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend { genesis := core.Genesis{Config: params.AllEthashProtocolChanges, GasLimit: gasLimit, Alloc: alloc} genesis.MustCommit(database) - blockchain, _ := core.NewBlockChain(database, nil, genesis.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + blockchain, _ := core.NewBlockChain(database, nil, genesis.Config, ethash.NewFaker(), vm.Config{}, nil, nil) backend := &SimulatedBackend{ database: database, diff --git a/build/checksums.txt b/build/checksums.txt index fa4c83a934..e7b52e6a15 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -15,24 +15,30 @@ c4b2349a8d11350ca038b8c57f3cc58dc0b31284bcbed4f7fca39aeed28b4a51 go1.17.2.linux fa6da0b829a66f5fab7e4e312fd6aa1b2d8f045c7ecee83b3d00f6fe5306759a go1.17.2.windows-amd64.zip 00575c85dc7a129ba892685a456b27a3f3670f71c8bfde1c5ad151f771d55df7 go1.17.2.windows-arm64.zip -658078aaaf7608693f37c4cf1380b2af418ab8b2d23fdb33e7e2d4339328590e golangci-lint-1.46.2-darwin-amd64.tar.gz -81f9b4afd62ec5e612ef8bc3b1d612a88b56ff289874831845cdad394427385f golangci-lint-1.46.2-darwin-arm64.tar.gz -943486e703e62ec55ecd90caeb22bcd39f8cc3962a93eec18c06b7bae12cb46f golangci-lint-1.46.2-freebsd-386.tar.gz -a75dd9ba7e08e8315c411697171db5375c0f6a1ece9e6fbeb9e9a4386822e17d golangci-lint-1.46.2-freebsd-amd64.tar.gz -83eedca1af72e8be055a1235177eb1b33524fbf08bec5730df2e6c3efade2b23 golangci-lint-1.46.2-freebsd-armv6.tar.gz -513d276c490de6f82baa01f9346d8d78b385f2ae97608f42f05d1f0f1314cd54 golangci-lint-1.46.2-freebsd-armv7.tar.gz -461a60016d516c69d406dc3e2d4957b722dbe684b7085dfac4802d0f84409e27 golangci-lint-1.46.2-linux-386.tar.gz -242cd4f2d6ac0556e315192e8555784d13da5d1874e51304711570769c4f2b9b golangci-lint-1.46.2-linux-amd64.tar.gz -ff5448ada2b3982581984d64b0dec614dba0a3ea4cab2d6a343c77927fc89f7e golangci-lint-1.46.2-linux-arm64.tar.gz -177f5210ef04aee282bfbc6ec519d36af5fb7d2b2c8d3f4ea5e59fdba71b0a27 golangci-lint-1.46.2-linux-armv6.tar.gz -10dd512a36ee978a1009edbca3ba3af410f0fda8df4d85f0e4793a24213870cc golangci-lint-1.46.2-linux-armv7.tar.gz -67779fa517c688c9db1090c3c456117d95c6b92979c623fe8cce8fb84251f21e golangci-lint-1.46.2-linux-mips64.tar.gz -c085f0f57bdccbb2c902a41b72ce210a3dfff16ca856789374745ab52004b6ee golangci-lint-1.46.2-linux-mips64le.tar.gz -abecef6421499248e58ed75d2938bc12b4b1f98b057f25060680b77bb51a881e golangci-lint-1.46.2-linux-ppc64le.tar.gz -134843a8f5c5c182c11979ea75f5866945d54757b2a04f3e5e04a0cf4fbf3a39 golangci-lint-1.46.2-linux-riscv64.tar.gz -9fe21a9476567aafe7a2e1a926b9641a39f920d4c0ea8eda9d968bc6136337f9 golangci-lint-1.46.2-linux-s390x.tar.gz -b48a421ec12a43f8fc8f977b9cf7d4a1ea1c4b97f803a238de7d3ce4ab23a84b golangci-lint-1.46.2-windows-386.zip -604acc1378a566abb0eac799362f3a37b7fcb5fa2268aeb2d5d954c829367301 golangci-lint-1.46.2-windows-amd64.zip -927def10db073da9687594072e6a3d9c891f67fa897105a2cfd715e018e7386c golangci-lint-1.46.2-windows-arm64.zip -729b76ed1d8b4e2612e38772b211503cb940e00a137bbaace1aa066f7c943737 golangci-lint-1.46.2-windows-armv6.zip -ea27c86d91e0b245ecbcfbf6cdb4ac0522d4bc6dca56bba02ea1bc77ad2917ac golangci-lint-1.46.2-windows-armv7.zip +632e96e6d5294fbbe7b2c410a49c8fa01c60712a0af85a567de85bcc1623ea21 golangci-lint-1.55.2-darwin-amd64.tar.gz +234463f059249f82045824afdcdd5db5682d0593052f58f6a3039a0a1c3899f6 golangci-lint-1.55.2-darwin-arm64.tar.gz +2bdd105e2d4e003a9058c33a22bb191a1e0f30fa0790acca0d8fbffac1d6247c golangci-lint-1.55.2-freebsd-386.tar.gz +e75056e8b082386676ce23eba455cf893931a792c0d87e1e3743c0aec33c7fb5 golangci-lint-1.55.2-freebsd-amd64.tar.gz +5789b933facaf6136bd23f1d50add67b79bbcf8dfdfc9069a37f729395940a66 golangci-lint-1.55.2-freebsd-armv6.tar.gz +7f21ab1008d05f32c954f99470fc86a83a059e530fe2add1d0b7d8ed4d8992a7 golangci-lint-1.55.2-freebsd-armv7.tar.gz +33ab06139b9219a28251f10821da94423db30285cc2af97494cbb2a281927de9 golangci-lint-1.55.2-illumos-amd64.tar.gz +57ce6f8ce3ad6ee45d7cc3d9a047545a851c2547637834a3fcb086c7b40b1e6b golangci-lint-1.55.2-linux-386.tar.gz +ca21c961a33be3bc15e4292dc40c98c8dcc5463a7b6768a3afc123761630c09c golangci-lint-1.55.2-linux-amd64.tar.gz +8eb0cee9b1dbf0eaa49871798c7f8a5b35f2960c52d776a5f31eb7d886b92746 golangci-lint-1.55.2-linux-arm64.tar.gz +3195f3e0f37d353fd5bd415cabcd4e263f5c29d3d0ffb176c26ff3d2c75eb3bb golangci-lint-1.55.2-linux-armv6.tar.gz +c823ee36eb1a719e171de1f2f5ca3068033dce8d9817232fd10ed71fd6650406 golangci-lint-1.55.2-linux-armv7.tar.gz +758a5d2a356dc494bd13ed4c0d4bf5a54a4dc91267ea5ecdd87b86c7ca0624e7 golangci-lint-1.55.2-linux-loong64.tar.gz +2c7b9abdce7cae802a67d583cd7c6dca520bff6d0e17c8535a918e2f2b437aa0 golangci-lint-1.55.2-linux-mips64.tar.gz +024e0a15b85352cc27271285526e16a4ab66d3e67afbbe446c9808c06cb8dbed golangci-lint-1.55.2-linux-mips64le.tar.gz +6b00f89ba5506c1de1efdd9fa17c54093013a294fefd8b9b31534db626a672ee golangci-lint-1.55.2-linux-ppc64le.tar.gz +0faa0d047d9bf7b703ed3ea65b6117043c93504f9ca1de25ae929d3901c73d4a golangci-lint-1.55.2-linux-riscv64.tar.gz +30dec9b22e7d5bb4e9d5ccea96da20f71cd7db3c8cf30b8ddc7cb9174c4d742a golangci-lint-1.55.2-linux-s390x.tar.gz +5a0ede48f79ad707902fdb29be8cd2abd8302dc122b65ebae3fdfc86751c7698 golangci-lint-1.55.2-netbsd-386.tar.gz +95af20a2e617126dd5b08122ece7819101070e1582a961067ce8c41172f901ad golangci-lint-1.55.2-netbsd-amd64.tar.gz +94fb7dacb7527847cc95d7120904e19a2a0a81a0d50d61766c9e0251da72ab9d golangci-lint-1.55.2-netbsd-armv6.tar.gz +ca906bce5fee9619400e4a321c56476fe4a4efb6ac4fc989d340eb5563348873 golangci-lint-1.55.2-netbsd-armv7.tar.gz +45b442f69fc8915c4500201c0247b7f3f69544dbc9165403a61f9095f2c57355 golangci-lint-1.55.2-windows-386.zip +f57d434d231d43417dfa631587522f8c1991220b43c8ffadb9c7bd279508bf81 golangci-lint-1.55.2-windows-amd64.zip +fd7dc8f4c6829ee6fafb252a4d81d2155cd35da7833665cbb25d53ce7cecd990 golangci-lint-1.55.2-windows-arm64.zip +1892c3c24f9e7ef44b02f6750c703864b6dc350129f3ec39510300007b2376f1 golangci-lint-1.55.2-windows-armv6.zip +a5e68ae73d38748b5269fad36ac7575e3c162a5dc63ef58abdea03cc5da4522a golangci-lint-1.55.2-windows-armv7.zip diff --git a/build/ci.go b/build/ci.go index 54cbf6e1f3..360e0390ec 100644 --- a/build/ci.go +++ b/build/ci.go @@ -24,19 +24,18 @@ Usage: go run build/ci.go Available commands are: - install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables - test [ -coverage ] [ packages... ] -- runs the tests - lint -- runs certain pre-selected linters - archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -signify key-envvar ] [ -upload dest ] -- archives build artifacts - importkeys -- imports signing keys from env - debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package - nsis -- creates a Windows NSIS installer - aar [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an Android archive - xcode [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an iOS XCode framework - purge [ -store blobstore ] [ -days threshold ] -- purges old archives from the blobstore + install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables + test [ -coverage ] [ packages... ] -- runs the tests + lint -- runs certain pre-selected linters + archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -signify key-envvar ] [ -upload dest ] -- archives build artifacts + importkeys -- imports signing keys from env + debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package + nsis -- creates a Windows NSIS installer + aar [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an Android archive + xcode [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an iOS XCode framework + purge [ -store blobstore ] [ -days threshold ] -- purges old archives from the blobstore For all commands, -n prevents execution of external programs (dry run mode). - */ package main @@ -148,7 +147,7 @@ var ( // This is the version of go that will be downloaded by // // go run ci.go install -dlgo - dlgoVersion = "1.17.2" + dlgoVersion = "1.20.2" ) var GOBIN, _ = filepath.Abs(filepath.Join("build", "bin")) @@ -336,7 +335,7 @@ func doLint(cmdline []string) { // downloadLinter downloads and unpacks golangci-lint. func downloadLinter(cachedir string) string { - const version = "1.46.2" + const version = "1.55.2" csdb := build.MustLoadChecksums("build/checksums.txt") base := fmt.Sprintf("golangci-lint-%s-%s-%s", version, runtime.GOOS, runtime.GOARCH) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index c6c360268c..24f64f1c3d 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -73,6 +73,7 @@ import ( "github.com/scroll-tech/go-ethereum/p2p/nat" "github.com/scroll-tech/go-ethereum/p2p/netutil" "github.com/scroll-tech/go-ethereum/params" + "github.com/scroll-tech/go-ethereum/rollup/tracing" "github.com/scroll-tech/go-ethereum/rpc" ) @@ -1904,7 +1905,8 @@ func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) (ethapi.Backend if err != nil { Fatalf("Failed to register the Ethereum service: %v", err) } - stack.RegisterAPIs(tracers.APIs(backend.ApiBackend)) + scrollTracerWrapper := tracing.NewTracerWrapper() + stack.RegisterAPIs(tracers.APIs(backend.ApiBackend, scrollTracerWrapper)) return backend.ApiBackend, nil } @@ -1933,7 +1935,8 @@ func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) (ethapi.Backend Fatalf("Failed to create the LES server: %v", err) } } - stack.RegisterAPIs(tracers.APIs(backend.APIBackend)) + scrollTracerWrapper := tracing.NewTracerWrapper() + stack.RegisterAPIs(tracers.APIs(backend.APIBackend, scrollTracerWrapper)) return backend.APIBackend, backend } @@ -2130,7 +2133,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai // TODO(rjl493456442) disable snapshot generation/wiping if the chain is read only. // Disable transaction indexing/unindexing by default. - chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg, nil, nil, false) + chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg, nil, nil) if err != nil { Fatalf("Can't create BlockChain: %v", err) } diff --git a/consensus/clique/clique_test.go b/consensus/clique/clique_test.go index 7f0d9a278d..4faa936501 100644 --- a/consensus/clique/clique_test.go +++ b/consensus/clique/clique_test.go @@ -55,7 +55,7 @@ func TestReimportMirroredState(t *testing.T) { genesis := genspec.MustCommit(db) // Generate a batch of blocks, each properly signed - chain, _ := core.NewBlockChain(db, nil, params.AllCliqueProtocolChanges, engine, vm.Config{}, nil, nil, false) + chain, _ := core.NewBlockChain(db, nil, params.AllCliqueProtocolChanges, engine, vm.Config{}, nil, nil) defer chain.Stop() blocks, _ := core.GenerateChain(params.AllCliqueProtocolChanges, genesis, engine, db, 3, func(i int, block *core.BlockGen) { @@ -89,7 +89,7 @@ func TestReimportMirroredState(t *testing.T) { db = rawdb.NewMemoryDatabase() genspec.MustCommit(db) - chain, _ = core.NewBlockChain(db, nil, params.AllCliqueProtocolChanges, engine, vm.Config{}, nil, nil, false) + chain, _ = core.NewBlockChain(db, nil, params.AllCliqueProtocolChanges, engine, vm.Config{}, nil, nil) defer chain.Stop() if _, err := chain.InsertChain(blocks[:2]); err != nil { @@ -102,7 +102,7 @@ func TestReimportMirroredState(t *testing.T) { // Simulate a crash by creating a new chain on top of the database, without // flushing the dirty states out. Insert the last block, triggering a sidechain // reimport. - chain, _ = core.NewBlockChain(db, nil, params.AllCliqueProtocolChanges, engine, vm.Config{}, nil, nil, false) + chain, _ = core.NewBlockChain(db, nil, params.AllCliqueProtocolChanges, engine, vm.Config{}, nil, nil) defer chain.Stop() if _, err := chain.InsertChain(blocks[2:]); err != nil { diff --git a/consensus/clique/snapshot_test.go b/consensus/clique/snapshot_test.go index 7b238cae4a..790f381031 100644 --- a/consensus/clique/snapshot_test.go +++ b/consensus/clique/snapshot_test.go @@ -450,7 +450,7 @@ func TestClique(t *testing.T) { batches[len(batches)-1] = append(batches[len(batches)-1], block) } // Pass all the headers through clique and ensure tallying succeeds - chain, err := core.NewBlockChain(db, nil, &config, engine, vm.Config{}, nil, nil, false) + chain, err := core.NewBlockChain(db, nil, &config, engine, vm.Config{}, nil, nil) if err != nil { t.Errorf("test %d: failed to create test chain: %v", i, err) continue diff --git a/core/bench_test.go b/core/bench_test.go index 86386944e1..622b4433cc 100644 --- a/core/bench_test.go +++ b/core/bench_test.go @@ -201,7 +201,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) { // Time the insertion of the new chain. // State and blocks are stored in the same DB. - chainman, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + chainman, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) defer chainman.Stop() b.ReportAllocs() b.ResetTimer() @@ -316,7 +316,7 @@ func benchReadChain(b *testing.B, full bool, count uint64) { if err != nil { b.Fatalf("error opening database at %v: %v", dir, err) } - chain, err := NewBlockChain(db, &cacheConfig, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(db, &cacheConfig, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil) if err != nil { b.Fatalf("error creating chain: %v", err) } diff --git a/core/block_validator.go b/core/block_validator.go index 80440af2d0..ad5221f434 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -43,25 +43,32 @@ type BlockValidator struct { // circuit capacity checker related fields checkCircuitCapacity bool // whether enable circuit capacity check - db ethdb.Database // db to store row consumption cMu sync.Mutex // mutex for circuit capacity checker + tracer tracerWrapper // scroll tracer wrapper circuitCapacityChecker *circuitcapacitychecker.CircuitCapacityChecker // circuit capacity checker instance } // NewBlockValidator returns a new block validator which is safe for re-use -func NewBlockValidator(config *params.ChainConfig, blockchain *BlockChain, engine consensus.Engine, db ethdb.Database, checkCircuitCapacity bool) *BlockValidator { +func NewBlockValidator(config *params.ChainConfig, blockchain *BlockChain, engine consensus.Engine) *BlockValidator { validator := &BlockValidator{ - config: config, - engine: engine, - bc: blockchain, - checkCircuitCapacity: checkCircuitCapacity, - db: db, - circuitCapacityChecker: circuitcapacitychecker.NewCircuitCapacityChecker(true), + config: config, + engine: engine, + bc: blockchain, } - log.Info("created new BlockValidator", "CircuitCapacityChecker ID", validator.circuitCapacityChecker.ID) return validator } +type tracerWrapper interface { + CreateTraceEnvAndGetBlockTrace(*params.ChainConfig, ChainContext, consensus.Engine, ethdb.Database, *state.StateDB, *types.Block, *types.Block, bool) (*types.BlockTrace, error) +} + +func (v *BlockValidator) SetupTracerAndCircuitCapacityChecker(tracer tracerWrapper) { + v.checkCircuitCapacity = true + v.tracer = tracer + v.circuitCapacityChecker = circuitcapacitychecker.NewCircuitCapacityChecker(true) + log.Info("new CircuitCapacityChecker in BlockValidator", "ID", v.circuitCapacityChecker.ID) +} + // ValidateBody validates the given block's uncles and verifies the block // header's transaction and uncle roots. The headers are assumed to be already // validated at this point. @@ -101,7 +108,7 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error { // if a block's RowConsumption has been stored, which means it has been processed before, // (e.g., in miner/worker.go or in insertChain), // we simply skip its calculation and validation - if rawdb.ReadBlockRowConsumption(v.db, block.Hash()) != nil { + if rawdb.ReadBlockRowConsumption(v.bc.db, block.Hash()) != nil { return nil } rowConsumption, err := v.validateCircuitRowConsumption(block) @@ -115,7 +122,7 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error { "hash", block.Hash().String(), "rowConsumption", rowConsumption, ) - rawdb.WriteBlockRowConsumption(v.db, block.Hash(), rowConsumption) + rawdb.WriteBlockRowConsumption(v.bc.db, block.Hash(), rowConsumption) } return nil } @@ -179,7 +186,7 @@ func (v *BlockValidator) ValidateL1Messages(block *types.Block) error { l1msg := it.L1Message() skippedTx := types.NewTx(&l1msg) log.Debug("Skipped L1 message", "queueIndex", index, "tx", skippedTx.Hash().String(), "block", blockHash.String()) - rawdb.WriteSkippedTransaction(v.db, skippedTx, nil, "unknown", block.NumberU64(), &blockHash) + rawdb.WriteSkippedTransaction(v.bc.db, skippedTx, nil, "unknown", block.NumberU64(), &blockHash) } queueIndex = txQueueIndex + 1 @@ -260,7 +267,7 @@ func CalcGasLimit(parentGasLimit, desiredLimit uint64) uint64 { return limit } -func (v *BlockValidator) createTraceEnv(block *types.Block) (*TraceEnv, error) { +func (v *BlockValidator) createTraceEnvAndGetBlockTrace(block *types.Block) (*types.BlockTrace, error) { parent := v.bc.GetBlock(block.ParentHash(), block.NumberU64()-1) if parent == nil { return nil, errors.New("validateCircuitRowConsumption: no parent block found") @@ -271,7 +278,7 @@ func (v *BlockValidator) createTraceEnv(block *types.Block) (*TraceEnv, error) { return nil, err } - return CreateTraceEnv(v.config, v.bc, v.engine, v.db, statedb, parent, block, true) + return v.tracer.CreateTraceEnvAndGetBlockTrace(v.config, v.bc, v.engine, v.bc.db, statedb, parent, block, true) } func (v *BlockValidator) validateCircuitRowConsumption(block *types.Block) (*types.RowConsumption, error) { @@ -283,12 +290,7 @@ func (v *BlockValidator) validateCircuitRowConsumption(block *types.Block) (*typ "len(txs)", block.Transactions().Len(), ) - env, err := v.createTraceEnv(block) - if err != nil { - return nil, err - } - - traces, err := env.GetBlockTrace(block) + traces, err := v.createTraceEnvAndGetBlockTrace(block) if err != nil { return nil, err } diff --git a/core/block_validator_test.go b/core/block_validator_test.go index 57121b9ecd..c94132d001 100644 --- a/core/block_validator_test.go +++ b/core/block_validator_test.go @@ -42,7 +42,7 @@ func TestHeaderVerification(t *testing.T) { headers[i] = block.Header() } // Run the header checker for blocks one-by-one, checking for both valid and invalid nonces - chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil, false) + chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil) defer chain.Stop() for i := 0; i < len(blocks); i++ { @@ -106,11 +106,11 @@ func testHeaderConcurrentVerification(t *testing.T, threads int) { var results <-chan error if valid { - chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil, false) + chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil) _, results = chain.engine.VerifyHeaders(chain, headers, seals) chain.Stop() } else { - chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFakeFailer(uint64(len(headers)-1)), vm.Config{}, nil, nil, false) + chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFakeFailer(uint64(len(headers)-1)), vm.Config{}, nil, nil) _, results = chain.engine.VerifyHeaders(chain, headers, seals) chain.Stop() } @@ -173,7 +173,7 @@ func testHeaderConcurrentAbortion(t *testing.T, threads int) { defer runtime.GOMAXPROCS(old) // Start the verifications and immediately abort - chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFakeDelayer(time.Millisecond), vm.Config{}, nil, nil, false) + chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFakeDelayer(time.Millisecond), vm.Config{}, nil, nil) defer chain.Stop() abort, results := chain.engine.VerifyHeaders(chain, headers, seals) diff --git a/core/blockchain.go b/core/blockchain.go index 68ef13c777..ee9de85b82 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -220,7 +220,7 @@ type BlockChain struct { // NewBlockChain returns a fully initialised block chain using information // available in the database. It initialises the default Ethereum Validator and // Processor. -func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config, shouldPreserve func(block *types.Block) bool, txLookupLimit *uint64, checkCircuitCapacity bool) (*BlockChain, error) { +func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config, shouldPreserve func(block *types.Block) bool, txLookupLimit *uint64) (*BlockChain, error) { if cacheConfig == nil { cacheConfig = defaultCacheConfig } @@ -263,7 +263,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par engine: engine, vmConfig: vmConfig, } - bc.validator = NewBlockValidator(chainConfig, bc, engine, db, checkCircuitCapacity) + bc.validator = NewBlockValidator(chainConfig, bc, engine) bc.prefetcher = newStatePrefetcher(chainConfig, bc, engine) bc.processor = NewStateProcessor(chainConfig, bc, engine) diff --git a/core/blockchain_repair_test.go b/core/blockchain_repair_test.go index 79aa52d4a0..8e846cf007 100644 --- a/core/blockchain_repair_test.go +++ b/core/blockchain_repair_test.go @@ -1783,7 +1783,7 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) { config.SnapshotLimit = 256 config.SnapshotWait = true } - chain, err := NewBlockChain(db, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(db, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to create chain: %v", err) } @@ -1836,7 +1836,7 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) { } defer db.Close() - chain, err = NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil, false) + chain, err = NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to recreate chain: %v", err) } @@ -1907,7 +1907,7 @@ func TestIssue23496(t *testing.T) { SnapshotWait: true, } ) - chain, err := NewBlockChain(db, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(db, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to create chain: %v", err) } @@ -1951,7 +1951,7 @@ func TestIssue23496(t *testing.T) { } defer db.Close() - chain, err = NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil, false) + chain, err = NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to recreate chain: %v", err) } diff --git a/core/blockchain_sethead_test.go b/core/blockchain_sethead_test.go index 1ddf2476f8..986ddd7c39 100644 --- a/core/blockchain_sethead_test.go +++ b/core/blockchain_sethead_test.go @@ -1982,7 +1982,7 @@ func testSetHead(t *testing.T, tt *rewindTest, snapshots bool) { config.SnapshotLimit = 256 config.SnapshotWait = true } - chain, err := NewBlockChain(db, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(db, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to create chain: %v", err) } diff --git a/core/blockchain_snapshot_test.go b/core/blockchain_snapshot_test.go index 29e179056d..4becdf9f4e 100644 --- a/core/blockchain_snapshot_test.go +++ b/core/blockchain_snapshot_test.go @@ -80,7 +80,7 @@ func (basic *snapshotTestBasic) prepare(t *testing.T) (*BlockChain, []*types.Blo // will happen during the block insertion. cacheConfig = defaultCacheConfig ) - chain, err := NewBlockChain(db, cacheConfig, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(db, cacheConfig, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to create chain: %v", err) } @@ -223,7 +223,7 @@ func (snaptest *snapshotTest) test(t *testing.T) { // Restart the chain normally chain.Stop() - newchain, err := NewBlockChain(snaptest.db, nil, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil, false) + newchain, err := NewBlockChain(snaptest.db, nil, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to recreate chain: %v", err) } @@ -259,13 +259,13 @@ func (snaptest *crashSnapshotTest) test(t *testing.T) { // the crash, we do restart twice here: one after the crash and one // after the normal stop. It's used to ensure the broken snapshot // can be detected all the time. - newchain, err := NewBlockChain(newdb, nil, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil, false) + newchain, err := NewBlockChain(newdb, nil, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to recreate chain: %v", err) } newchain.Stop() - newchain, err = NewBlockChain(newdb, nil, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil, false) + newchain, err = NewBlockChain(newdb, nil, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to recreate chain: %v", err) } @@ -301,7 +301,7 @@ func (snaptest *gappedSnapshotTest) test(t *testing.T) { TrieTimeLimit: 5 * time.Minute, SnapshotLimit: 0, } - newchain, err := NewBlockChain(snaptest.db, cacheConfig, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil, false) + newchain, err := NewBlockChain(snaptest.db, cacheConfig, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to recreate chain: %v", err) } @@ -309,7 +309,7 @@ func (snaptest *gappedSnapshotTest) test(t *testing.T) { newchain.Stop() // Restart the chain with enabling the snapshot - newchain, err = NewBlockChain(snaptest.db, nil, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil, false) + newchain, err = NewBlockChain(snaptest.db, nil, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to recreate chain: %v", err) } @@ -337,7 +337,7 @@ func (snaptest *setHeadSnapshotTest) test(t *testing.T) { chain.SetHead(snaptest.setHead) chain.Stop() - newchain, err := NewBlockChain(snaptest.db, nil, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil, false) + newchain, err := NewBlockChain(snaptest.db, nil, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to recreate chain: %v", err) } @@ -368,7 +368,7 @@ func (snaptest *restartCrashSnapshotTest) test(t *testing.T) { // and state committed. chain.Stop() - newchain, err := NewBlockChain(snaptest.db, nil, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil, false) + newchain, err := NewBlockChain(snaptest.db, nil, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to recreate chain: %v", err) } @@ -385,7 +385,7 @@ func (snaptest *restartCrashSnapshotTest) test(t *testing.T) { // journal and latest state will be committed // Restart the chain after the crash - newchain, err = NewBlockChain(snaptest.db, nil, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil, false) + newchain, err = NewBlockChain(snaptest.db, nil, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to recreate chain: %v", err) } @@ -420,7 +420,7 @@ func (snaptest *wipeCrashSnapshotTest) test(t *testing.T) { TrieTimeLimit: 5 * time.Minute, SnapshotLimit: 0, } - newchain, err := NewBlockChain(snaptest.db, config, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil, false) + newchain, err := NewBlockChain(snaptest.db, config, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to recreate chain: %v", err) } @@ -436,13 +436,13 @@ func (snaptest *wipeCrashSnapshotTest) test(t *testing.T) { SnapshotLimit: 256, SnapshotWait: false, // Don't wait rebuild } - newchain, err = NewBlockChain(snaptest.db, config, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil, false) + newchain, err = NewBlockChain(snaptest.db, config, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to recreate chain: %v", err) } // Simulate the blockchain crash. - newchain, err = NewBlockChain(snaptest.db, nil, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil, false) + newchain, err = NewBlockChain(snaptest.db, nil, params.AllEthashProtocolChanges, snaptest.engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to recreate chain: %v", err) } diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 2ea3c89a0d..84bd9f08f3 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -58,7 +58,7 @@ func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *B ) // Initialize a fresh chain with only a genesis block - blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil, false) + blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil) // Create and inject the requested chain if n == 0 { return db, blockchain, nil @@ -524,7 +524,7 @@ func testReorgBadHashes(t *testing.T, full bool) { blockchain.Stop() // Create a new BlockChain and check that it rolled back the state. - ncm, err := NewBlockChain(blockchain.db, nil, blockchain.chainConfig, ethash.NewFaker(), vm.Config{}, nil, nil, false) + ncm, err := NewBlockChain(blockchain.db, nil, blockchain.chainConfig, ethash.NewFaker(), vm.Config{}, nil, nil) if err != nil { t.Fatalf("failed to create new chain manager: %v", err) } @@ -637,7 +637,7 @@ func TestFastVsFullChains(t *testing.T) { // Import the chain as an archive node for the comparison baseline archiveDb := rawdb.NewMemoryDatabase() gspec.MustCommit(archiveDb) - archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) defer archive.Stop() if n, err := archive.InsertChain(blocks); err != nil { @@ -646,7 +646,7 @@ func TestFastVsFullChains(t *testing.T) { // Fast import the chain as a non-archive node to test fastDb := rawdb.NewMemoryDatabase() gspec.MustCommit(fastDb) - fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) defer fast.Stop() headers := make([]*types.Header, len(blocks)) @@ -670,7 +670,7 @@ func TestFastVsFullChains(t *testing.T) { t.Fatalf("failed to create temp freezer db: %v", err) } gspec.MustCommit(ancientDb) - ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) defer ancient.Stop() if n, err := ancient.InsertHeaderChain(headers, 1); err != nil { @@ -792,7 +792,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) { archiveCaching := *defaultCacheConfig archiveCaching.TrieDirtyDisabled = true - archive, _ := NewBlockChain(archiveDb, &archiveCaching, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + archive, _ := NewBlockChain(archiveDb, &archiveCaching, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) if n, err := archive.InsertChain(blocks); err != nil { t.Fatalf("failed to process block %d: %v", n, err) } @@ -805,7 +805,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) { // Import the chain as a non-archive node and ensure all pointers are updated fastDb, delfn := makeDb() defer delfn() - fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) defer fast.Stop() headers := make([]*types.Header, len(blocks)) @@ -825,7 +825,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) { // Import the chain as a ancient-first node and ensure all pointers are updated ancientDb, delfn := makeDb() defer delfn() - ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) defer ancient.Stop() if n, err := ancient.InsertHeaderChain(headers, 1); err != nil { @@ -844,7 +844,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) { // Import the chain as a light node and ensure all pointers are updated lightDb, delfn := makeDb() defer delfn() - light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) if n, err := light.InsertHeaderChain(headers, 1); err != nil { t.Fatalf("failed to insert header %d: %v", n, err) } @@ -913,7 +913,7 @@ func TestChainTxReorgs(t *testing.T) { } }) // Import the chain. This runs all block validation rules. - blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) if i, err := blockchain.InsertChain(chain); err != nil { t.Fatalf("failed to insert original chain[%d]: %v", i, err) } @@ -983,7 +983,7 @@ func TestLogReorgs(t *testing.T) { signer = types.LatestSigner(gspec.Config) ) - blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) defer blockchain.Stop() rmLogsCh := make(chan RemovedLogsEvent) @@ -1036,7 +1036,7 @@ func TestLogRebirth(t *testing.T) { genesis = gspec.MustCommit(db) signer = types.LatestSigner(gspec.Config) engine = ethash.NewFaker() - blockchain, _ = NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil, nil, false) + blockchain, _ = NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil, nil) ) defer blockchain.Stop() @@ -1099,7 +1099,7 @@ func TestSideLogRebirth(t *testing.T) { gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}} genesis = gspec.MustCommit(db) signer = types.LatestSigner(gspec.Config) - blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) ) defer blockchain.Stop() @@ -1174,7 +1174,7 @@ func TestReorgSideEvent(t *testing.T) { signer = types.LatestSigner(gspec.Config) ) - blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) defer blockchain.Stop() chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {}) @@ -1306,7 +1306,7 @@ func TestEIP155Transition(t *testing.T) { genesis = gspec.MustCommit(db) ) - blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) defer blockchain.Stop() blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, block *BlockGen) { @@ -1414,7 +1414,7 @@ func TestEIP161AccountRemoval(t *testing.T) { } genesis = gspec.MustCommit(db) ) - blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) defer blockchain.Stop() blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, block *BlockGen) { @@ -1489,7 +1489,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) { diskdb := rawdb.NewMemoryDatabase() (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb) - chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -1533,7 +1533,7 @@ func TestTrieForkGC(t *testing.T) { diskdb := rawdb.NewMemoryDatabase() (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb) - chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -1572,7 +1572,7 @@ func TestLargeReorgTrieGC(t *testing.T) { diskdb := rawdb.NewMemoryDatabase() (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb) - chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -1633,7 +1633,7 @@ func TestBlockchainRecovery(t *testing.T) { t.Fatalf("failed to create temp freezer db: %v", err) } gspec.MustCommit(ancientDb) - ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) headers := make([]*types.Header, len(blocks)) for i, block := range blocks { @@ -1653,7 +1653,7 @@ func TestBlockchainRecovery(t *testing.T) { rawdb.WriteHeadFastBlockHash(ancientDb, midBlock.Hash()) // Reopen broken blockchain again - ancient, _ = NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + ancient, _ = NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) defer ancient.Stop() if num := ancient.CurrentBlock().NumberU64(); num != 0 { t.Errorf("head block mismatch: have #%v, want #%v", num, 0) @@ -1705,7 +1705,7 @@ func TestInsertReceiptChainRollback(t *testing.T) { } gspec := Genesis{Config: params.AllEthashProtocolChanges} gspec.MustCommit(ancientDb) - ancientChain, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + ancientChain, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) defer ancientChain.Stop() // Import the canonical header chain. @@ -1747,8 +1747,8 @@ func TestInsertReceiptChainRollback(t *testing.T) { // overtake the 'canon' chain until after it's passed canon by about 200 blocks. // // Details at: -// - https://github.com/scroll-tech/go-ethereum/issues/18977 -// - https://github.com/scroll-tech/go-ethereum/pull/18988 +// - https://github.com/scroll-tech/go-ethereum/issues/18977 +// - https://github.com/scroll-tech/go-ethereum/pull/18988 func TestLowDiffLongChain(t *testing.T) { // Generate a canonical chain to act as the main dataset engine := ethash.NewFaker() @@ -1766,7 +1766,7 @@ func TestLowDiffLongChain(t *testing.T) { diskdb := rawdb.NewMemoryDatabase() (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb) - chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -1813,7 +1813,7 @@ func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommon blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, nil) diskdb := rawdb.NewMemoryDatabase() (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb) - chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -1867,7 +1867,8 @@ func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommon // That is: the sidechain for import contains some blocks already present in canon chain. // So the blocks are // [ Cn, Cn+1, Cc, Sn+3 ... Sm] -// ^ ^ ^ pruned +// +// ^ ^ ^ pruned func TestPrunedImportSide(t *testing.T) { //glogger := log.NewGlogHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false))) //glogger.Verbosity(3) @@ -1910,7 +1911,7 @@ func testInsertKnownChainData(t *testing.T, typ string) { (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(chaindb) defer os.RemoveAll(dir) - chain, err := NewBlockChain(chaindb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(chaindb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -2019,7 +2020,7 @@ func getLongAndShortChains() (bc *BlockChain, longChain []*types.Block, heavyCha diskdb := rawdb.NewMemoryDatabase() (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb) - chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil) if err != nil { return nil, nil, nil, fmt.Errorf("failed to create tester chain: %v", err) } @@ -2212,7 +2213,7 @@ func TestTransactionIndices(t *testing.T) { // Import all blocks into ancient db l := uint64(0) - chain, err := NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l, false) + chain, err := NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -2237,7 +2238,7 @@ func TestTransactionIndices(t *testing.T) { t.Fatalf("failed to create temp freezer db: %v", err) } gspec.MustCommit(ancientDb) - chain, err = NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l, false) + chain, err = NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -2261,7 +2262,7 @@ func TestTransactionIndices(t *testing.T) { limit = []uint64{0, 64 /* drop stale */, 32 /* shorten history */, 64 /* extend history */, 0 /* restore all */} tails := []uint64{0, 67 /* 130 - 64 + 1 */, 100 /* 131 - 32 + 1 */, 69 /* 132 - 64 + 1 */, 0} for i, l := range limit { - chain, err = NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l, false) + chain, err = NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -2339,7 +2340,7 @@ func TestSkipStaleTxIndicesInFastSync(t *testing.T) { // Import all blocks into ancient db, only HEAD-32 indices are kept. l := uint64(32) - chain, err := NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l, false) + chain, err := NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -2403,7 +2404,7 @@ func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks in diskdb := rawdb.NewMemoryDatabase() gspec.MustCommit(diskdb) - chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil) if err != nil { b.Fatalf("failed to create tester chain: %v", err) } @@ -2472,9 +2473,9 @@ func BenchmarkBlockChain_1x1000Executions(b *testing.B) { // This internally leads to a sidechain import, since the blocks trigger an // ErrPrunedAncestor error. // This may e.g. happen if -// 1. Downloader rollbacks a batch of inserted blocks and exits -// 2. Downloader starts to sync again -// 3. The blocks fetched are all known and canonical blocks +// 1. Downloader rollbacks a batch of inserted blocks and exits +// 2. Downloader starts to sync again +// 3. The blocks fetched are all known and canonical blocks func TestSideImportPrunedBlocks(t *testing.T) { // Generate a canonical chain to act as the main dataset engine := ethash.NewFaker() @@ -2485,7 +2486,7 @@ func TestSideImportPrunedBlocks(t *testing.T) { blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, nil) diskdb := rawdb.NewMemoryDatabase() (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb) - chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -2625,7 +2626,7 @@ func TestDeleteCreateRevert(t *testing.T) { diskdb := rawdb.NewMemoryDatabase() gspec.MustCommit(diskdb) - chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -2636,20 +2637,19 @@ func TestDeleteCreateRevert(t *testing.T) { // TestInitThenFailCreateContract tests a pretty notorious case that happened // on mainnet over blocks 7338108, 7338110 and 7338115. -// - Block 7338108: address e771789f5cccac282f23bb7add5690e1f6ca467c is initiated -// with 0.001 ether (thus created but no code) -// - Block 7338110: a CREATE2 is attempted. The CREATE2 would deploy code on -// the same address e771789f5cccac282f23bb7add5690e1f6ca467c. However, the -// deployment fails due to OOG during initcode execution -// - Block 7338115: another tx checks the balance of -// e771789f5cccac282f23bb7add5690e1f6ca467c, and the snapshotter returned it as -// zero. +// - Block 7338108: address e771789f5cccac282f23bb7add5690e1f6ca467c is initiated +// with 0.001 ether (thus created but no code) +// - Block 7338110: a CREATE2 is attempted. The CREATE2 would deploy code on +// the same address e771789f5cccac282f23bb7add5690e1f6ca467c. However, the +// deployment fails due to OOG during initcode execution +// - Block 7338115: another tx checks the balance of +// e771789f5cccac282f23bb7add5690e1f6ca467c, and the snapshotter returned it as +// zero. // // The problem being that the snapshotter maintains a destructset, and adds items // to the destructset in case something is created "onto" an existing item. // We need to either roll back the snapDestructs, or not place it into snapDestructs // in the first place. -// func TestInitThenFailCreateContract(t *testing.T) { var ( // Generate a canonical chain to act as the main dataset @@ -2730,7 +2730,7 @@ func TestInitThenFailCreateContract(t *testing.T) { chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{ //Debug: true, //Tracer: vm.NewJSONLogger(nil, os.Stdout), - }, nil, nil, false) + }, nil, nil) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -2817,7 +2817,7 @@ func TestEIP2718Transition(t *testing.T) { diskdb := rawdb.NewMemoryDatabase() gspec.MustCommit(diskdb) - chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -2838,13 +2838,13 @@ func TestEIP2718Transition(t *testing.T) { // TestEIP1559Transition tests the following: // -// 1. A transaction whose gasFeeCap is greater than the baseFee is valid. -// 2. Gas accounting for access lists on EIP-1559 transactions is correct. -// 3. Only the transaction's tip will be received by the coinbase. -// 4. The transaction sender pays for both the tip and baseFee. -// 5. The coinbase receives only the partially realized tip when -// gasFeeCap - gasTipCap < baseFee. -// 6. Legacy transaction behave as expected (e.g. gasPrice = gasFeeCap = gasTipCap). +// 1. A transaction whose gasFeeCap is greater than the baseFee is valid. +// 2. Gas accounting for access lists on EIP-1559 transactions is correct. +// 3. Only the transaction's tip will be received by the coinbase. +// 4. The transaction sender pays for both the tip and baseFee. +// 5. The coinbase receives only the partially realized tip when +// gasFeeCap - gasTipCap < baseFee. +// 6. Legacy transaction behave as expected (e.g. gasPrice = gasFeeCap = gasTipCap). func TestEIP1559Transition(t *testing.T) { var ( aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa") @@ -2912,7 +2912,7 @@ func TestEIP1559Transition(t *testing.T) { diskdb := rawdb.NewMemoryDatabase() gspec.MustCommit(diskdb) - chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -3036,7 +3036,7 @@ func TestPoseidonCodeHash(t *testing.T) { genesis = gspec.MustCommit(db) signer = types.LatestSigner(gspec.Config) engine = ethash.NewFaker() - blockchain, _ = NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil, nil, false) + blockchain, _ = NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil, nil) ) defer blockchain.Stop() @@ -3150,7 +3150,7 @@ func TestFeeVault(t *testing.T) { diskdb := rawdb.NewMemoryDatabase() gspec.MustCommit(diskdb) - chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -3202,7 +3202,7 @@ func TestTransactionCountLimit(t *testing.T) { } // Initialize blockchain - blockchain, err := NewBlockChain(db, nil, config, engine, vm.Config{}, nil, nil, false) + blockchain, err := NewBlockChain(db, nil, config, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("failed to create new chain manager: %v", err) } @@ -3266,7 +3266,7 @@ func TestInsertBlocksWithL1Messages(t *testing.T) { rawdb.WriteL1Messages(db, msgs) // initialize blockchain - blockchain, _ := NewBlockChain(db, nil, config, engine, vm.Config{}, nil, nil, false) + blockchain, _ := NewBlockChain(db, nil, config, engine, vm.Config{}, nil, nil) defer blockchain.Stop() // generate blocks with 1 L1 message in each @@ -3377,7 +3377,7 @@ func TestL1MessageValidationFailure(t *testing.T) { rawdb.WriteL1Messages(db, msgs) // initialize blockchain - blockchain, _ := NewBlockChain(db, nil, config, engine, vm.Config{}, nil, nil, false) + blockchain, _ := NewBlockChain(db, nil, config, engine, vm.Config{}, nil, nil) defer blockchain.Stop() generateBlock := func(txs []*types.Transaction) ([]*types.Block, []types.Receipts) { @@ -3452,7 +3452,7 @@ func TestBlockPayloadSizeLimit(t *testing.T) { } // Initialize blockchain - blockchain, err := NewBlockChain(db, nil, config, engine, vm.Config{}, nil, nil, false) + blockchain, err := NewBlockChain(db, nil, config, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("failed to create new chain manager: %v", err) } @@ -3564,7 +3564,7 @@ func TestEIP3651(t *testing.T) { } b.AddTx(tx) }) - chain, err := NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil, nil, false) + chain, err := NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } diff --git a/core/chain_makers_test.go b/core/chain_makers_test.go index 93cf3ce381..78fcdae5c7 100644 --- a/core/chain_makers_test.go +++ b/core/chain_makers_test.go @@ -79,7 +79,7 @@ func ExampleGenerateChain() { }) // Import the chain. This runs all block validation rules. - blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) defer blockchain.Stop() if i, err := blockchain.InsertChain(chain); err != nil { diff --git a/core/dao_test.go b/core/dao_test.go index 680302f463..6f221973b8 100644 --- a/core/dao_test.go +++ b/core/dao_test.go @@ -45,7 +45,7 @@ func TestDAOForkRangeExtradata(t *testing.T) { proConf.DAOForkBlock = forkBlock proConf.DAOForkSupport = true - proBc, _ := NewBlockChain(proDb, nil, &proConf, ethash.NewFaker(), vm.Config{}, nil, nil, false) + proBc, _ := NewBlockChain(proDb, nil, &proConf, ethash.NewFaker(), vm.Config{}, nil, nil) defer proBc.Stop() conDb := rawdb.NewMemoryDatabase() @@ -55,7 +55,7 @@ func TestDAOForkRangeExtradata(t *testing.T) { conConf.DAOForkBlock = forkBlock conConf.DAOForkSupport = false - conBc, _ := NewBlockChain(conDb, nil, &conConf, ethash.NewFaker(), vm.Config{}, nil, nil, false) + conBc, _ := NewBlockChain(conDb, nil, &conConf, ethash.NewFaker(), vm.Config{}, nil, nil) defer conBc.Stop() if _, err := proBc.InsertChain(prefix); err != nil { @@ -69,7 +69,7 @@ func TestDAOForkRangeExtradata(t *testing.T) { // Create a pro-fork block, and try to feed into the no-fork chain db = rawdb.NewMemoryDatabase() gspec.MustCommit(db) - bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{}, nil, nil, false) + bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{}, nil, nil) defer bc.Stop() blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().NumberU64())) @@ -94,7 +94,7 @@ func TestDAOForkRangeExtradata(t *testing.T) { // Create a no-fork block, and try to feed into the pro-fork chain db = rawdb.NewMemoryDatabase() gspec.MustCommit(db) - bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{}, nil, nil, false) + bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{}, nil, nil) defer bc.Stop() blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().NumberU64())) @@ -120,7 +120,7 @@ func TestDAOForkRangeExtradata(t *testing.T) { // Verify that contra-forkers accept pro-fork extra-datas after forking finishes db = rawdb.NewMemoryDatabase() gspec.MustCommit(db) - bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{}, nil, nil, false) + bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{}, nil, nil) defer bc.Stop() blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().NumberU64())) @@ -140,7 +140,7 @@ func TestDAOForkRangeExtradata(t *testing.T) { // Verify that pro-forkers accept contra-fork extra-datas after forking finishes db = rawdb.NewMemoryDatabase() gspec.MustCommit(db) - bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{}, nil, nil, false) + bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{}, nil, nil) defer bc.Stop() blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().NumberU64())) diff --git a/core/genesis_test.go b/core/genesis_test.go index c1ad60a8eb..eaf39252ba 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -118,7 +118,7 @@ func TestSetupGenesis(t *testing.T) { // Advance to block #4, past the homestead transition block of customg. genesis := oldcustomg.MustCommit(db) - bc, _ := NewBlockChain(db, nil, oldcustomg.Config, ethash.NewFullFaker(), vm.Config{}, nil, nil, false) + bc, _ := NewBlockChain(db, nil, oldcustomg.Config, ethash.NewFullFaker(), vm.Config{}, nil, nil) defer bc.Stop() blocks, _ := GenerateChain(oldcustomg.Config, genesis, ethash.NewFaker(), db, 4, nil) diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 5835d5b42f..860c6da741 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -105,7 +105,7 @@ func TestStateProcessorErrors(t *testing.T) { }, } genesis = gspec.MustCommit(db) - blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) ) defer blockchain.Stop() bigNumber := new(big.Int).SetBytes(common.FromHex("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) @@ -246,7 +246,7 @@ func TestStateProcessorErrors(t *testing.T) { }, } genesis = gspec.MustCommit(db) - blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) ) defer blockchain.Stop() for i, tt := range []struct { @@ -286,7 +286,7 @@ func TestStateProcessorErrors(t *testing.T) { }, } genesis = gspec.MustCommit(db) - blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) ) defer blockchain.Stop() for i, tt := range []struct { @@ -341,7 +341,7 @@ func TestStateProcessorErrors(t *testing.T) { }, } genesis = gspec.MustCommit(db) - blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) tooBigInitCode = [params.MaxInitCodeSize + 1]byte{} smallInitCode = [320]byte{} ) diff --git a/core/types.go b/core/types.go index 75c01e61c4..da8e31cbdc 100644 --- a/core/types.go +++ b/core/types.go @@ -32,6 +32,10 @@ type Validator interface { // ValidateState validates the given statedb and optionally the receipts and // gas used. ValidateState(block *types.Block, state *state.StateDB, receipts types.Receipts, usedGas uint64) error + + // SetupTracerAndCircuitCapacityChecker sets up ScrollTracerWrapper and CircuitCapacityChecker for validator, + // to get scroll-related traces and to validate the circuit row consumption + SetupTracerAndCircuitCapacityChecker(tracer tracerWrapper) } // Prefetcher is an interface for pre-caching transaction signatures and state. diff --git a/core/types/l2trace.go b/core/types/l2trace.go index a4a8dd4843..482afda647 100644 --- a/core/types/l2trace.go +++ b/core/types/l2trace.go @@ -67,6 +67,8 @@ type ExecutionResult struct { // If it is a contract call, the contract code is returned. ByteCode string `json:"byteCode,omitempty"` StructLogs []*StructLogRes `json:"structLogs"` + CallTrace json.RawMessage `json:"callTrace"` + Prestate json.RawMessage `json:"prestate"` } // StructLogRes stores a structured log emitted by the EVM while replaying a diff --git a/eth/backend.go b/eth/backend.go index 28ca1ccc1b..c25147e635 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -57,6 +57,7 @@ import ( "github.com/scroll-tech/go-ethereum/rlp" "github.com/scroll-tech/go-ethereum/rollup/rollup_sync_service" "github.com/scroll-tech/go-ethereum/rollup/sync_service" + "github.com/scroll-tech/go-ethereum/rollup/tracing" "github.com/scroll-tech/go-ethereum/rpc" ) @@ -194,10 +195,15 @@ func New(stack *node.Node, config *ethconfig.Config, l1Client sync_service.EthCl MPTWitness: config.MPTWitness, } ) - eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, chainConfig, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit, config.CheckCircuitCapacity) + eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, chainConfig, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit) if err != nil { return nil, err } + if config.CheckCircuitCapacity { + tracer := tracing.NewTracerWrapper() + eth.blockchain.Validator().SetupTracerAndCircuitCapacityChecker(tracer) + } + // Rewind the chain in case of an incompatible config upgrade. if compat, ok := genesisErr.(*params.ConfigCompatError); ok { log.Warn("Rewinding chain to upgrade configuration", "err", compat) diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index f59205e3ce..49274ffe6a 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -370,7 +370,7 @@ func TestGetLogsRange(t *testing.T) { (&core.Genesis{ Config: params.TestChainConfig, }).MustCommit(db) - chain, _ := core.NewBlockChain(db, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil, false) + chain, _ := core.NewBlockChain(db, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil) bs, _ := core.GenerateChain(params.TestChainConfig, chain.Genesis(), ethash.NewFaker(), db, 10, nil) if _, err := chain.InsertChain(bs); err != nil { panic(err) diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index f0415206b1..5cb58687f4 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -144,7 +144,7 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke // Construct testing chain diskdb := rawdb.NewMemoryDatabase() gspec.Commit(diskdb) - chain, err := core.NewBlockChain(diskdb, &core.CacheConfig{TrieCleanNoPrefetch: true}, &config, engine, vm.Config{}, nil, nil, false) + chain, err := core.NewBlockChain(diskdb, &core.CacheConfig{TrieCleanNoPrefetch: true}, &config, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("Failed to create local chain, %v", err) } diff --git a/eth/handler_eth_test.go b/eth/handler_eth_test.go index 02cf618a99..d24705cec0 100644 --- a/eth/handler_eth_test.go +++ b/eth/handler_eth_test.go @@ -105,8 +105,8 @@ func testForkIDSplit(t *testing.T, protocol uint) { genesisNoFork = gspecNoFork.MustCommit(dbNoFork) genesisProFork = gspecProFork.MustCommit(dbProFork) - chainNoFork, _ = core.NewBlockChain(dbNoFork, nil, configNoFork, engine, vm.Config{}, nil, nil, false) - chainProFork, _ = core.NewBlockChain(dbProFork, nil, configProFork, engine, vm.Config{}, nil, nil, false) + chainNoFork, _ = core.NewBlockChain(dbNoFork, nil, configNoFork, engine, vm.Config{}, nil, nil) + chainProFork, _ = core.NewBlockChain(dbProFork, nil, configProFork, engine, vm.Config{}, nil, nil) blocksNoFork, _ = core.GenerateChain(configNoFork, genesisNoFork, engine, dbNoFork, 2, nil) blocksProFork, _ = core.GenerateChain(configProFork, genesisProFork, engine, dbProFork, 2, nil) diff --git a/eth/handler_test.go b/eth/handler_test.go index 41d23567a4..b9931a4b38 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -137,7 +137,7 @@ func newTestHandlerWithBlocks(blocks int) *testHandler { Alloc: core.GenesisAlloc{testAddr: {Balance: big.NewInt(1000000)}}, }).MustCommit(db) - chain, _ := core.NewBlockChain(db, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil, false) + chain, _ := core.NewBlockChain(db, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil) bs, _ := core.GenerateChain(params.TestChainConfig, chain.Genesis(), ethash.NewFaker(), db, blocks, nil) if _, err := chain.InsertChain(bs); err != nil { diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go index 4b9f2493db..ec5a5e7648 100644 --- a/eth/protocols/eth/handler_test.go +++ b/eth/protocols/eth/handler_test.go @@ -69,7 +69,7 @@ func newTestBackendWithGenerator(blocks int, generator func(int, *core.BlockGen) Alloc: core.GenesisAlloc{testAddr: {Balance: big.NewInt(100_000_000_000_000_000)}}, }).MustCommit(db) - chain, _ := core.NewBlockChain(db, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil, false) + chain, _ := core.NewBlockChain(db, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil) bs, _ := core.GenerateChain(params.TestChainConfig, chain.Genesis(), ethash.NewFaker(), db, blocks, generator) if _, err := chain.InsertChain(bs); err != nil { diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 6347a2ddd7..833d20cba7 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -86,12 +86,13 @@ type Backend interface { // API is the collection of tracing APIs exposed over the private debugging endpoint. type API struct { - backend Backend + backend Backend + scrollTracerWrapper scrollTracerWrapper } // NewAPI creates a new API definition for the tracing methods of the Ethereum service. -func NewAPI(backend Backend) *API { - return &API{backend: backend} +func NewAPI(backend Backend, scrollTracerWrapper scrollTracerWrapper) *API { + return &API{backend: backend, scrollTracerWrapper: scrollTracerWrapper} } type chainContext struct { @@ -979,19 +980,19 @@ func (api *API) traceTx(ctx context.Context, message core.Message, txctx *Contex } // APIs return the collection of RPC services the tracer package offers. -func APIs(backend Backend) []rpc.API { +func APIs(backend Backend, scrollTracerWrapper scrollTracerWrapper) []rpc.API { // Append all the local APIs and return return []rpc.API{ { Namespace: "debug", Version: "1.0", - Service: NewAPI(backend), + Service: NewAPI(backend, scrollTracerWrapper), Public: false, }, { Namespace: "scroll", Version: "1.0", - Service: TraceBlock(NewAPI(backend)), + Service: TraceBlock(NewAPI(backend, scrollTracerWrapper)), Public: true, }, } diff --git a/eth/tracers/api_blocktrace.go b/eth/tracers/api_blocktrace.go index 61ca504384..3fc08e849f 100644 --- a/eth/tracers/api_blocktrace.go +++ b/eth/tracers/api_blocktrace.go @@ -4,20 +4,34 @@ import ( "context" "errors" + "github.com/scroll-tech/go-ethereum/consensus" "github.com/scroll-tech/go-ethereum/core" + "github.com/scroll-tech/go-ethereum/core/state" "github.com/scroll-tech/go-ethereum/core/types" "github.com/scroll-tech/go-ethereum/core/vm" + "github.com/scroll-tech/go-ethereum/ethdb" "github.com/scroll-tech/go-ethereum/log" + "github.com/scroll-tech/go-ethereum/params" "github.com/scroll-tech/go-ethereum/rpc" ) +var errNoScrollTracerWrapper = errors.New("no ScrollTracerWrapper") + type TraceBlock interface { GetBlockTraceByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, config *TraceConfig) (trace *types.BlockTrace, err error) GetTxBlockTraceOnTopOfBlock(ctx context.Context, tx *types.Transaction, blockNrOrHash rpc.BlockNumberOrHash, config *TraceConfig) (*types.BlockTrace, error) } +type scrollTracerWrapper interface { + CreateTraceEnvAndGetBlockTrace(*params.ChainConfig, core.ChainContext, consensus.Engine, ethdb.Database, *state.StateDB, *types.Block, *types.Block, bool) (*types.BlockTrace, error) +} + // GetBlockTraceByNumberOrHash replays the block and returns the structured BlockTrace by hash or number. func (api *API) GetBlockTraceByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, config *TraceConfig) (trace *types.BlockTrace, err error) { + if api.scrollTracerWrapper == nil { + return nil, errNoScrollTracerWrapper + } + var block *types.Block if number, ok := blockNrOrHash.Number(); ok { block, err = api.blockByNumber(ctx, number) @@ -33,15 +47,14 @@ func (api *API) GetBlockTraceByNumberOrHash(ctx context.Context, blockNrOrHash r return nil, errors.New("genesis is not traceable") } - env, err := api.createTraceEnv(ctx, config, block) - if err != nil { - return nil, err - } - - return env.GetBlockTrace(block) + return api.createTraceEnvAndGetBlockTrace(ctx, config, block) } func (api *API) GetTxBlockTraceOnTopOfBlock(ctx context.Context, tx *types.Transaction, blockNrOrHash rpc.BlockNumberOrHash, config *TraceConfig) (*types.BlockTrace, error) { + if api.scrollTracerWrapper == nil { + return nil, errNoScrollTracerWrapper + } + // Try to retrieve the specified block var ( err error @@ -63,17 +76,11 @@ func (api *API) GetTxBlockTraceOnTopOfBlock(ctx context.Context, tx *types.Trans block = types.NewBlockWithHeader(block.Header()).WithBody([]*types.Transaction{tx}, nil) - // create current execution environment. - env, err := api.createTraceEnv(ctx, config, block) - if err != nil { - return nil, err - } - - return env.GetBlockTrace(block) + return api.createTraceEnvAndGetBlockTrace(ctx, config, block) } -// Make trace environment for current block. -func (api *API) createTraceEnv(ctx context.Context, config *TraceConfig, block *types.Block) (*core.TraceEnv, error) { +// Make trace environment for current block, and then get the trace for the block. +func (api *API) createTraceEnvAndGetBlockTrace(ctx context.Context, config *TraceConfig, block *types.Block) (*types.BlockTrace, error) { if config == nil { config = &TraceConfig{ LogConfig: &vm.LogConfig{ @@ -100,5 +107,5 @@ func (api *API) createTraceEnv(ctx context.Context, config *TraceConfig, block * } chaindb := api.backend.ChainDb() - return core.CreateTraceEnv(api.backend.ChainConfig(), api.chainContext(ctx), api.backend.Engine(), chaindb, statedb, parent, block, true) + return api.scrollTracerWrapper.CreateTraceEnvAndGetBlockTrace(api.backend.ChainConfig(), api.chainContext(ctx), api.backend.Engine(), chaindb, statedb, parent, block, true) } diff --git a/eth/tracers/api_blocktrace_test.go b/eth/tracers/api_blocktrace_test.go index c67942f64e..6b632ffbec 100644 --- a/eth/tracers/api_blocktrace_test.go +++ b/eth/tracers/api_blocktrace_test.go @@ -1,225 +1,227 @@ package tracers -import ( - "context" - "encoding/json" - "math/big" - "testing" +// import ( +// "context" +// "encoding/json" +// "math/big" +// "testing" - "github.com/stretchr/testify/assert" +// "github.com/stretchr/testify/assert" - "github.com/scroll-tech/go-ethereum/accounts/abi/bind" - "github.com/scroll-tech/go-ethereum/common" - "github.com/scroll-tech/go-ethereum/common/hexutil" - "github.com/scroll-tech/go-ethereum/core" - "github.com/scroll-tech/go-ethereum/core/types" - "github.com/scroll-tech/go-ethereum/params" - "github.com/scroll-tech/go-ethereum/rpc" -) +// "github.com/scroll-tech/go-ethereum/accounts/abi/bind" +// "github.com/scroll-tech/go-ethereum/common" +// "github.com/scroll-tech/go-ethereum/common/hexutil" +// "github.com/scroll-tech/go-ethereum/core" +// "github.com/scroll-tech/go-ethereum/core/types" +// "github.com/scroll-tech/go-ethereum/params" +// "github.com/scroll-tech/go-ethereum/rollup/tracing" +// "github.com/scroll-tech/go-ethereum/rpc" +// ) -// erc20MetaData contains all meta data concerning the ERC20 contract. -var erc20MetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pauser\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimal\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"new_operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"new_pauser\",\"type\":\"address\"}],\"name\":\"changeUser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "dd62ed3e": "allowance(address,address)", - "095ea7b3": "approve(address,uint256)", - "70a08231": "balanceOf(address)", - "9dc29fac": "burn(address,uint256)", - "8e50817a": "changeUser(address,address)", - "313ce567": "decimals()", - "a457c2d7": "decreaseAllowance(address,uint256)", - "39509351": "increaseAllowance(address,uint256)", - "40c10f19": "mint(address,uint256)", - "06fdde03": "name()", - "8456cb59": "pause()", - "5c975abb": "paused()", - "95d89b41": "symbol()", - "18160ddd": "totalSupply()", - "a9059cbb": "transfer(address,uint256)", - "23b872dd": "transferFrom(address,address,uint256)", - "3f4ba83a": "unpause()", - }, - Bin: "0x60806040523480156200001157600080fd5b50604051620014b2380380620014b2833981810160405260a08110156200003757600080fd5b815160208301516040808501805191519395929483019291846401000000008211156200006357600080fd5b9083019060208201858111156200007957600080fd5b82516401000000008111828201881017156200009457600080fd5b82525081516020918201929091019080838360005b83811015620000c3578181015183820152602001620000a9565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011557600080fd5b9083019060208201858111156200012b57600080fd5b82516401000000008111828201881017156200014657600080fd5b82525081516020918201929091019080838360005b83811015620001755781810151838201526020016200015b565b50505050905090810190601f168015620001a35780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001c8916003918501906200026b565b508051620001de9060049060208401906200026b565b50506005805461ff001960ff1990911660121716905550600680546001600160a01b038088166001600160a01b0319928316179092556007805492871692909116919091179055620002308162000255565b50506005805462010000600160b01b0319163362010000021790555062000307915050565b6005805460ff191660ff92909216919091179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620002ae57805160ff1916838001178555620002de565b82800160010185558215620002de579182015b82811115620002de578251825591602001919060010190620002c1565b50620002ec929150620002f0565b5090565b5b80821115620002ec5760008155600101620002f1565b61119b80620003176000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c80635c975abb116100a257806395d89b411161007157806395d89b41146103015780639dc29fac14610309578063a457c2d714610335578063a9059cbb14610361578063dd62ed3e1461038d5761010b565b80635c975abb1461029d57806370a08231146102a55780638456cb59146102cb5780638e50817a146102d35761010b565b8063313ce567116100de578063313ce5671461021d578063395093511461023b5780633f4ba83a1461026757806340c10f19146102715761010b565b806306fdde0314610110578063095ea7b31461018d57806318160ddd146101cd57806323b872dd146101e7575b600080fd5b6101186103bb565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b038135169060200135610451565b604080519115158252519081900360200190f35b6101d561046e565b60408051918252519081900360200190f35b6101b9600480360360608110156101fd57600080fd5b506001600160a01b03813581169160208101359091169060400135610474565b6102256104fb565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561025157600080fd5b506001600160a01b038135169060200135610504565b61026f610552565b005b61026f6004803603604081101561028757600080fd5b506001600160a01b0381351690602001356105a9565b6101b9610654565b6101d5600480360360208110156102bb57600080fd5b50356001600160a01b0316610662565b61026f61067d565b61026f600480360360408110156102e957600080fd5b506001600160a01b03813581169160200135166106d2565b610118610757565b61026f6004803603604081101561031f57600080fd5b506001600160a01b0381351690602001356107b8565b6101b96004803603604081101561034b57600080fd5b506001600160a01b03813516906020013561085f565b6101b96004803603604081101561037757600080fd5b506001600160a01b0381351690602001356108c7565b6101d5600480360360408110156103a357600080fd5b506001600160a01b03813581169160200135166108db565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104475780601f1061041c57610100808354040283529160200191610447565b820191906000526020600020905b81548152906001019060200180831161042a57829003601f168201915b5050505050905090565b600061046561045e610906565b848461090a565b50600192915050565b60025490565b60006104818484846109f6565b6104f18461048d610906565b6104ec85604051806060016040528060288152602001611085602891396001600160a01b038a166000908152600160205260408120906104cb610906565b6001600160a01b031681526020810191909152604001600020549190610b51565b61090a565b5060019392505050565b60055460ff1690565b6000610465610511610906565b846104ec8560016000610522610906565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610be8565b6007546001600160a01b0316331461059f576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd08185b1b1bddd95960aa1b604482015290519081900360640190fd5b6105a7610c49565b565b600554610100900460ff16156105f9576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6006546001600160a01b03163314610646576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd08185b1b1bddd95960aa1b604482015290519081900360640190fd5b6106508282610ced565b5050565b600554610100900460ff1690565b6001600160a01b031660009081526020819052604090205490565b6007546001600160a01b031633146106ca576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd08185b1b1bddd95960aa1b604482015290519081900360640190fd5b6105a7610ddd565b6005546201000090046001600160a01b03163314610726576040805162461bcd60e51b815260206004820152600c60248201526b6f6e6c7920466163746f727960a01b604482015290519081900360640190fd5b600780546001600160a01b039283166001600160a01b03199182161790915560068054939092169216919091179055565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104475780601f1061041c57610100808354040283529160200191610447565b600554610100900460ff1615610808576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6006546001600160a01b03163314610855576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd08185b1b1bddd95960aa1b604482015290519081900360640190fd5b6106508282610e65565b600061046561086c610906565b846104ec856040518060600160405280602581526020016111176025913960016000610896610906565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610b51565b60006104656108d4610906565b84846109f6565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b3390565b6001600160a01b03831661094f5760405162461bcd60e51b81526004018080602001828103825260248152602001806110f36024913960400191505060405180910390fd5b6001600160a01b0382166109945760405162461bcd60e51b815260040180806020018281038252602281526020018061103d6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b038316610a3b5760405162461bcd60e51b81526004018080602001828103825260258152602001806110ce6025913960400191505060405180910390fd5b6001600160a01b038216610a805760405162461bcd60e51b8152600401808060200182810382526023815260200180610ff86023913960400191505060405180910390fd5b610a8b838383610f61565b610ac88160405180606001604052806026815260200161105f602691396001600160a01b0386166000908152602081905260409020549190610b51565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610af79082610be8565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610be05760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ba5578181015183820152602001610b8d565b50505050905090810190601f168015610bd25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610c42576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600554610100900460ff16610c9c576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6005805461ff00191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610cd0610906565b604080516001600160a01b039092168252519081900360200190a1565b6001600160a01b038216610d48576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610d5460008383610f61565b600254610d619082610be8565b6002556001600160a01b038216600090815260208190526040902054610d879082610be8565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600554610100900460ff1615610e2d576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6005805461ff0019166101001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610cd0610906565b6001600160a01b038216610eaa5760405162461bcd60e51b81526004018080602001828103825260218152602001806110ad6021913960400191505060405180910390fd5b610eb682600083610f61565b610ef38160405180606001604052806022815260200161101b602291396001600160a01b0385166000908152602081905260409020549190610b51565b6001600160a01b038316600090815260208190526040902055600254610f199082610fb5565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b610f6c838383610fb0565b610f74610654565b15610fb05760405162461bcd60e51b815260040180806020018281038252602a81526020018061113c602a913960400191505060405180910390fd5b505050565b6000610c4283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610b5156fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f45524332305061757361626c653a20746f6b656e207472616e73666572207768696c6520706175736564a2646970667358221220e96342bec8f6c2bf72815a39998973b64c3bed57770f402e9a7b7eeda0265d4c64736f6c634300060c0033", -} +// // erc20MetaData contains all meta data concerning the ERC20 contract. +// var erc20MetaData = &bind.MetaData{ +// ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pauser\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimal\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"new_operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"new_pauser\",\"type\":\"address\"}],\"name\":\"changeUser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +// Sigs: map[string]string{ +// "dd62ed3e": "allowance(address,address)", +// "095ea7b3": "approve(address,uint256)", +// "70a08231": "balanceOf(address)", +// "9dc29fac": "burn(address,uint256)", +// "8e50817a": "changeUser(address,address)", +// "313ce567": "decimals()", +// "a457c2d7": "decreaseAllowance(address,uint256)", +// "39509351": "increaseAllowance(address,uint256)", +// "40c10f19": "mint(address,uint256)", +// "06fdde03": "name()", +// "8456cb59": "pause()", +// "5c975abb": "paused()", +// "95d89b41": "symbol()", +// "18160ddd": "totalSupply()", +// "a9059cbb": "transfer(address,uint256)", +// "23b872dd": "transferFrom(address,address,uint256)", +// "3f4ba83a": "unpause()", +// }, +// Bin: "0x60806040523480156200001157600080fd5b50604051620014b2380380620014b2833981810160405260a08110156200003757600080fd5b815160208301516040808501805191519395929483019291846401000000008211156200006357600080fd5b9083019060208201858111156200007957600080fd5b82516401000000008111828201881017156200009457600080fd5b82525081516020918201929091019080838360005b83811015620000c3578181015183820152602001620000a9565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011557600080fd5b9083019060208201858111156200012b57600080fd5b82516401000000008111828201881017156200014657600080fd5b82525081516020918201929091019080838360005b83811015620001755781810151838201526020016200015b565b50505050905090810190601f168015620001a35780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001c8916003918501906200026b565b508051620001de9060049060208401906200026b565b50506005805461ff001960ff1990911660121716905550600680546001600160a01b038088166001600160a01b0319928316179092556007805492871692909116919091179055620002308162000255565b50506005805462010000600160b01b0319163362010000021790555062000307915050565b6005805460ff191660ff92909216919091179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620002ae57805160ff1916838001178555620002de565b82800160010185558215620002de579182015b82811115620002de578251825591602001919060010190620002c1565b50620002ec929150620002f0565b5090565b5b80821115620002ec5760008155600101620002f1565b61119b80620003176000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c80635c975abb116100a257806395d89b411161007157806395d89b41146103015780639dc29fac14610309578063a457c2d714610335578063a9059cbb14610361578063dd62ed3e1461038d5761010b565b80635c975abb1461029d57806370a08231146102a55780638456cb59146102cb5780638e50817a146102d35761010b565b8063313ce567116100de578063313ce5671461021d578063395093511461023b5780633f4ba83a1461026757806340c10f19146102715761010b565b806306fdde0314610110578063095ea7b31461018d57806318160ddd146101cd57806323b872dd146101e7575b600080fd5b6101186103bb565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b038135169060200135610451565b604080519115158252519081900360200190f35b6101d561046e565b60408051918252519081900360200190f35b6101b9600480360360608110156101fd57600080fd5b506001600160a01b03813581169160208101359091169060400135610474565b6102256104fb565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561025157600080fd5b506001600160a01b038135169060200135610504565b61026f610552565b005b61026f6004803603604081101561028757600080fd5b506001600160a01b0381351690602001356105a9565b6101b9610654565b6101d5600480360360208110156102bb57600080fd5b50356001600160a01b0316610662565b61026f61067d565b61026f600480360360408110156102e957600080fd5b506001600160a01b03813581169160200135166106d2565b610118610757565b61026f6004803603604081101561031f57600080fd5b506001600160a01b0381351690602001356107b8565b6101b96004803603604081101561034b57600080fd5b506001600160a01b03813516906020013561085f565b6101b96004803603604081101561037757600080fd5b506001600160a01b0381351690602001356108c7565b6101d5600480360360408110156103a357600080fd5b506001600160a01b03813581169160200135166108db565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104475780601f1061041c57610100808354040283529160200191610447565b820191906000526020600020905b81548152906001019060200180831161042a57829003601f168201915b5050505050905090565b600061046561045e610906565b848461090a565b50600192915050565b60025490565b60006104818484846109f6565b6104f18461048d610906565b6104ec85604051806060016040528060288152602001611085602891396001600160a01b038a166000908152600160205260408120906104cb610906565b6001600160a01b031681526020810191909152604001600020549190610b51565b61090a565b5060019392505050565b60055460ff1690565b6000610465610511610906565b846104ec8560016000610522610906565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610be8565b6007546001600160a01b0316331461059f576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd08185b1b1bddd95960aa1b604482015290519081900360640190fd5b6105a7610c49565b565b600554610100900460ff16156105f9576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6006546001600160a01b03163314610646576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd08185b1b1bddd95960aa1b604482015290519081900360640190fd5b6106508282610ced565b5050565b600554610100900460ff1690565b6001600160a01b031660009081526020819052604090205490565b6007546001600160a01b031633146106ca576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd08185b1b1bddd95960aa1b604482015290519081900360640190fd5b6105a7610ddd565b6005546201000090046001600160a01b03163314610726576040805162461bcd60e51b815260206004820152600c60248201526b6f6e6c7920466163746f727960a01b604482015290519081900360640190fd5b600780546001600160a01b039283166001600160a01b03199182161790915560068054939092169216919091179055565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104475780601f1061041c57610100808354040283529160200191610447565b600554610100900460ff1615610808576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6006546001600160a01b03163314610855576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd08185b1b1bddd95960aa1b604482015290519081900360640190fd5b6106508282610e65565b600061046561086c610906565b846104ec856040518060600160405280602581526020016111176025913960016000610896610906565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610b51565b60006104656108d4610906565b84846109f6565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b3390565b6001600160a01b03831661094f5760405162461bcd60e51b81526004018080602001828103825260248152602001806110f36024913960400191505060405180910390fd5b6001600160a01b0382166109945760405162461bcd60e51b815260040180806020018281038252602281526020018061103d6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b038316610a3b5760405162461bcd60e51b81526004018080602001828103825260258152602001806110ce6025913960400191505060405180910390fd5b6001600160a01b038216610a805760405162461bcd60e51b8152600401808060200182810382526023815260200180610ff86023913960400191505060405180910390fd5b610a8b838383610f61565b610ac88160405180606001604052806026815260200161105f602691396001600160a01b0386166000908152602081905260409020549190610b51565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610af79082610be8565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610be05760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ba5578181015183820152602001610b8d565b50505050905090810190601f168015610bd25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610c42576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600554610100900460ff16610c9c576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6005805461ff00191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610cd0610906565b604080516001600160a01b039092168252519081900360200190a1565b6001600160a01b038216610d48576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610d5460008383610f61565b600254610d619082610be8565b6002556001600160a01b038216600090815260208190526040902054610d879082610be8565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600554610100900460ff1615610e2d576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6005805461ff0019166101001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610cd0610906565b6001600160a01b038216610eaa5760405162461bcd60e51b81526004018080602001828103825260218152602001806110ad6021913960400191505060405180910390fd5b610eb682600083610f61565b610ef38160405180606001604052806022815260200161101b602291396001600160a01b0385166000908152602081905260409020549190610b51565b6001600160a01b038316600090815260208190526040902055600254610f199082610fb5565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b610f6c838383610fb0565b610f74610654565b15610fb05760405162461bcd60e51b815260040180806020018281038252602a81526020018061113c602a913960400191505060405180910390fd5b505050565b6000610c4283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610b5156fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f45524332305061757361626c653a20746f6b656e207472616e73666572207768696c6520706175736564a2646970667358221220e96342bec8f6c2bf72815a39998973b64c3bed57770f402e9a7b7eeda0265d4c64736f6c634300060c0033", +// } -func TestAPI_GetBlockTraceByNumberOrHash(t *testing.T) { - t.Parallel() - erc20Abi, err := erc20MetaData.GetAbi() - assert.NoError(t, err) +// func TestAPI_GetBlockTraceByNumberOrHash(t *testing.T) { +// t.Parallel() +// erc20Abi, err := erc20MetaData.GetAbi() +// assert.NoError(t, err) - var ( - accounts = createAccounts(5) - genesis = &core.Genesis{Alloc: core.GenesisAlloc{ - accounts[0].From: {Balance: big.NewInt(params.Ether)}, - accounts[1].From: {Balance: big.NewInt(params.Ether)}, - accounts[2].From: {Balance: big.NewInt(params.Ether)}, - accounts[3].From: {Balance: big.NewInt(params.Ether)}, - accounts[4].From: {Balance: big.NewInt(params.Ether)}, - }} +// var ( +// accounts = createAccounts(5) +// genesis = &core.Genesis{Alloc: core.GenesisAlloc{ +// accounts[0].From: {Balance: big.NewInt(params.Ether)}, +// accounts[1].From: {Balance: big.NewInt(params.Ether)}, +// accounts[2].From: {Balance: big.NewInt(params.Ether)}, +// accounts[3].From: {Balance: big.NewInt(params.Ether)}, +// accounts[4].From: {Balance: big.NewInt(params.Ether)}, +// }} - txs = make([]*types.Transaction, 0, 6) - ) +// txs = make([]*types.Transaction, 0, 6) +// ) - // deploy erc20 contract - backend := newTestBackend(t, 1, genesis, func(i int, b *core.BlockGen) { - // deploy erc20 contract - tx, err := createTx(b, accounts[0], nil, nil, common.FromHex(erc20MetaData.Bin)) - assert.NoError(t, err) - txs = append(txs, tx) - }) - parent, err := backend.BlockByNumber(context.Background(), 1) - assert.NoError(t, err) +// // deploy erc20 contract +// backend := newTestBackend(t, 1, genesis, func(i int, b *core.BlockGen) { +// // deploy erc20 contract +// tx, err := createTx(b, accounts[0], nil, nil, common.FromHex(erc20MetaData.Bin)) +// assert.NoError(t, err) +// txs = append(txs, tx) +// }) +// parent, err := backend.BlockByNumber(context.Background(), 1) +// assert.NoError(t, err) - // mint erc20 balance - blocks, _ := core.GenerateChain(backend.chainConfig, parent, backend.engine, backend.chaindb, 1, func(i int, gen *core.BlockGen) { - // mint erc20 tokens - for _, acc := range accounts { - to := common.BigToAddress(big.NewInt(int64(i))) - data, err := erc20Abi.Pack("mint", acc.From, big.NewInt(1e18)) - assert.NoError(t, err) - tx, err := createTx(gen, acc, &to, nil, data) - assert.NoError(t, err) - txs = append(txs, tx) - } - }) - _, err = backend.chain.InsertChain(blocks) - assert.NoError(t, err) +// // mint erc20 balance +// blocks, _ := core.GenerateChain(backend.chainConfig, parent, backend.engine, backend.chaindb, 1, func(i int, gen *core.BlockGen) { +// // mint erc20 tokens +// for _, acc := range accounts { +// to := common.BigToAddress(big.NewInt(int64(i))) +// data, err := erc20Abi.Pack("mint", acc.From, big.NewInt(1e18)) +// assert.NoError(t, err) +// tx, err := createTx(gen, acc, &to, nil, data) +// assert.NoError(t, err) +// txs = append(txs, tx) +// } +// }) +// _, err = backend.chain.InsertChain(blocks) +// assert.NoError(t, err) - block, err := backend.BlockByNumber(context.Background(), 2) - assert.NoError(t, err) +// block, err := backend.BlockByNumber(context.Background(), 2) +// assert.NoError(t, err) - api := NewAPI(backend) - // get trace - hash := block.Hash() - blockTrace, err := api.GetBlockTraceByNumberOrHash(context.Background(), rpc.BlockNumberOrHash{ - BlockHash: &hash, - }, nil) - assert.NoError(t, err) +// scrollTracerWrapper := tracing.NewTracerWrapper() +// api := NewAPI(backend, scrollTracerWrapper) +// // get trace +// hash := block.Hash() +// blockTrace, err := api.GetBlockTraceByNumberOrHash(context.Background(), rpc.BlockNumberOrHash{ +// BlockHash: &hash, +// }, nil) +// assert.NoError(t, err) - // check chain status - checkChainAndProof(t, backend, parent, block, blockTrace) +// // check chain status +// checkChainAndProof(t, backend, parent, block, blockTrace) - // check txs. - checkTxs(t, block.Transactions(), blockTrace.Transactions) +// // check txs. +// checkTxs(t, block.Transactions(), blockTrace.Transactions) - txTraces, err := api.TraceBlockByNumber(context.Background(), 2, nil) - assert.NoError(t, err) +// txTraces, err := api.TraceBlockByNumber(context.Background(), 2, nil) +// assert.NoError(t, err) - // check executionResults - checkStructLogs(t, txTraces, blockTrace.ExecutionResults) +// // check executionResults +// checkStructLogs(t, txTraces, blockTrace.ExecutionResults) - // check coinbase - checkCoinbase(t, backend, blockTrace.Coinbase) -} +// // check coinbase +// checkCoinbase(t, backend, blockTrace.Coinbase) +// } -func verifyProof(t *testing.T, expect [][]byte, actual []hexutil.Bytes) { - assert.Equal(t, true, actual != nil) - assert.Equal(t, len(expect), len(actual)) - for i, val := range expect { - assert.Equal(t, hexutil.Encode(val), actual[i].String()) - } -} +// func verifyProof(t *testing.T, expect [][]byte, actual []hexutil.Bytes) { +// assert.Equal(t, true, actual != nil) +// assert.Equal(t, len(expect), len(actual)) +// for i, val := range expect { +// assert.Equal(t, hexutil.Encode(val), actual[i].String()) +// } +// } -func checkChainAndProof(t *testing.T, b *testBackend, parent *types.Block, block *types.Block, blockTrace *types.BlockTrace) { - assert.Equal(t, parent.Hash(), block.ParentHash()) - storgeTrace := blockTrace.StorageTrace - assert.Equal(t, parent.Root().String(), storgeTrace.RootBefore.String()) - assert.Equal(t, block.Root().String(), storgeTrace.RootAfter.String()) +// func checkChainAndProof(t *testing.T, b *testBackend, parent *types.Block, block *types.Block, blockTrace *types.BlockTrace) { +// assert.Equal(t, parent.Hash(), block.ParentHash()) +// storgeTrace := blockTrace.StorageTrace +// assert.Equal(t, parent.Root().String(), storgeTrace.RootBefore.String()) +// assert.Equal(t, block.Root().String(), storgeTrace.RootAfter.String()) - statedb, err := b.chain.StateAt(parent.Root()) - assert.NoError(t, err) +// statedb, err := b.chain.StateAt(parent.Root()) +// assert.NoError(t, err) - storageProof := blockTrace.StorageTrace.StorageProofs - for _, tx := range blockTrace.Transactions { - for _, addr := range []common.Address{tx.From, *tx.To} { - // verify proofs - if data2, ok := storgeTrace.Proofs[addr.String()]; ok { - data1, err := statedb.GetProof(addr) - assert.NoError(t, err) - verifyProof(t, data1, data2) - } - // verify storage proofs - for addr, wrappedProof := range storageProof { - for keyStr, data2 := range wrappedProof { - data1, err := statedb.GetStorageProof(common.HexToAddress(addr), common.HexToHash(keyStr)) - if len(data2) > 0 { - assert.NoError(t, err) - } - verifyProof(t, data1, data2) - } - } - } - } -} +// storageProof := blockTrace.StorageTrace.StorageProofs +// for _, tx := range blockTrace.Transactions { +// for _, addr := range []common.Address{tx.From, *tx.To} { +// // verify proofs +// if data2, ok := storgeTrace.Proofs[addr.String()]; ok { +// data1, err := statedb.GetProof(addr) +// assert.NoError(t, err) +// verifyProof(t, data1, data2) +// } +// // verify storage proofs +// for addr, wrappedProof := range storageProof { +// for keyStr, data2 := range wrappedProof { +// data1, err := statedb.GetStorageProof(common.HexToAddress(addr), common.HexToHash(keyStr)) +// if len(data2) > 0 { +// assert.NoError(t, err) +// } +// verifyProof(t, data1, data2) +// } +// } +// } +// } +// } -func checkTxs(t *testing.T, expect []*types.Transaction, actual []*types.TransactionData) { - assert.Equal(t, len(expect), len(actual)) - for i := range expect { - eTx, aTx := expect[i], actual[i] - assert.Equal(t, eTx.Hash().String(), aTx.TxHash) - assert.Equal(t, eTx.Gas(), aTx.Gas) - } -} +// func checkTxs(t *testing.T, expect []*types.Transaction, actual []*types.TransactionData) { +// assert.Equal(t, len(expect), len(actual)) +// for i := range expect { +// eTx, aTx := expect[i], actual[i] +// assert.Equal(t, eTx.Hash().String(), aTx.TxHash) +// assert.Equal(t, eTx.Gas(), aTx.Gas) +// } +// } -func checkStructLogs(t *testing.T, expect []*txTraceResult, actual []*types.ExecutionResult) { - // assert executionResults - assert.Equal(t, len(expect), len(actual)) - for i, val := range expect { - trace1, trace2 := val.Result.(*types.ExecutionResult), actual[i] - assert.Equal(t, trace1.L1DataFee, trace2.L1DataFee) - assert.Equal(t, trace1.Failed, trace2.Failed) - assert.Equal(t, trace1.Gas, trace2.Gas) - assert.Equal(t, trace1.ReturnValue, trace2.ReturnValue) - assert.Equal(t, len(trace1.StructLogs), len(trace2.StructLogs)) - // TODO: compare other fields +// func checkStructLogs(t *testing.T, expect []*txTraceResult, actual []*types.ExecutionResult) { +// // assert executionResults +// assert.Equal(t, len(expect), len(actual)) +// for i, val := range expect { +// trace1, trace2 := val.Result.(*types.ExecutionResult), actual[i] +// assert.Equal(t, trace1.L1DataFee, trace2.L1DataFee) +// assert.Equal(t, trace1.Failed, trace2.Failed) +// assert.Equal(t, trace1.Gas, trace2.Gas) +// assert.Equal(t, trace1.ReturnValue, trace2.ReturnValue) +// assert.Equal(t, len(trace1.StructLogs), len(trace2.StructLogs)) +// // TODO: compare other fields - for i, opcode := range trace1.StructLogs { - data1, err := json.Marshal(opcode) - assert.NoError(t, err) - data2, err := json.Marshal(trace2.StructLogs[i]) - assert.NoError(t, err) - assert.Equal(t, string(data1), string(data2)) - } - } -} +// for i, opcode := range trace1.StructLogs { +// data1, err := json.Marshal(opcode) +// assert.NoError(t, err) +// data2, err := json.Marshal(trace2.StructLogs[i]) +// assert.NoError(t, err) +// assert.Equal(t, string(data1), string(data2)) +// } +// } +// } -func checkCoinbase(t *testing.T, b *testBackend, wrapper *types.AccountWrapper) { - var coinbase common.Address - if b.chainConfig.Scroll.FeeVaultEnabled() { - coinbase = *b.chainConfig.Scroll.FeeVaultAddress - } else { - header, err := b.HeaderByNumber(context.Background(), 1) - assert.NoError(t, err) - coinbase, err = b.engine.Author(header) - assert.NoError(t, err) - } - assert.Equal(t, true, coinbase.String() == wrapper.Address.String()) -} +// func checkCoinbase(t *testing.T, b *testBackend, wrapper *types.AccountWrapper) { +// var coinbase common.Address +// if b.chainConfig.Scroll.FeeVaultEnabled() { +// coinbase = *b.chainConfig.Scroll.FeeVaultAddress +// } else { +// header, err := b.HeaderByNumber(context.Background(), 1) +// assert.NoError(t, err) +// coinbase, err = b.engine.Author(header) +// assert.NoError(t, err) +// } +// assert.Equal(t, true, coinbase.String() == wrapper.Address.String()) +// } -func createAccounts(n int) (auths []*bind.TransactOpts) { - accounts := newAccounts(5) - for _, acc := range accounts { - auth, _ := bind.NewKeyedTransactorWithChainID(acc.key, big.NewInt(1)) - auth.Nonce = big.NewInt(0) - auths = append(auths, auth) - } - return -} +// func createAccounts(n int) (auths []*bind.TransactOpts) { +// accounts := newAccounts(5) +// for _, acc := range accounts { +// auth, _ := bind.NewKeyedTransactorWithChainID(acc.key, big.NewInt(1)) +// auth.Nonce = big.NewInt(0) +// auths = append(auths, auth) +// } +// return +// } -func createTx(b *core.BlockGen, auth *bind.TransactOpts, to *common.Address, value *big.Int, data []byte) (*types.Transaction, error) { - nonce := auth.Nonce.Uint64() - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - To: to, - Value: value, - Gas: 200000, - GasPrice: b.BaseFee(), - Data: data, - }) - signedTx, err := auth.Signer(auth.From, tx) - if err == nil { - auth.Nonce = big.NewInt(int64(nonce + 1)) - b.AddTx(signedTx) - } - return signedTx, err -} +// func createTx(b *core.BlockGen, auth *bind.TransactOpts, to *common.Address, value *big.Int, data []byte) (*types.Transaction, error) { +// nonce := auth.Nonce.Uint64() +// tx := types.NewTx(&types.LegacyTx{ +// Nonce: nonce, +// To: to, +// Value: value, +// Gas: 200000, +// GasPrice: b.BaseFee(), +// Data: data, +// }) +// signedTx, err := auth.Signer(auth.From, tx) +// if err == nil { +// auth.Nonce = big.NewInt(int64(nonce + 1)) +// b.AddTx(signedTx) +// } +// return signedTx, err +// } diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index 52e6eed943..3a209c752b 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -82,7 +82,7 @@ func newTestBackend(t *testing.T, n int, gspec *core.Genesis, generator func(i i SnapshotLimit: 0, TrieDirtyDisabled: true, // Archive mode } - chain, err := core.NewBlockChain(backend.chaindb, cacheConfig, backend.chainConfig, backend.engine, vm.Config{}, nil, nil, false) + chain, err := core.NewBlockChain(backend.chaindb, cacheConfig, backend.chainConfig, backend.engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } @@ -203,7 +203,7 @@ func TestTraceCall(t *testing.T) { // fee: 0 wei tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, b.BaseFee(), nil), signer, accounts[0].key) b.AddTx(tx) - })) + }), nil) var testSuite = []struct { blockNumber rpc.BlockNumber @@ -337,7 +337,7 @@ func TestTraceTransaction(t *testing.T) { tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, b.BaseFee(), nil), signer, accounts[0].key) b.AddTx(tx) target = tx.Hash() - })) + }), nil) result, err := api.TraceTransaction(context.Background(), target, nil) if err != nil { t.Errorf("Failed to trace transaction %v", err) @@ -371,7 +371,7 @@ func TestTraceBlock(t *testing.T) { // fee: 0 wei tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, b.BaseFee(), nil), signer, accounts[0].key) b.AddTx(tx) - })) + }), nil) var testSuite = []struct { blockNumber rpc.BlockNumber @@ -446,7 +446,7 @@ func TestTracingWithOverrides(t *testing.T) { // fee: 0 wei tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, b.BaseFee(), nil), signer, accounts[0].key) b.AddTx(tx) - })) + }), nil) randomAccounts := newAccounts(3) type res struct { Gas int diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go new file mode 100644 index 0000000000..45d93160b3 --- /dev/null +++ b/eth/tracers/native/prestate.go @@ -0,0 +1,261 @@ +package native + +import ( + "bytes" + "encoding/json" + "math/big" + "sync/atomic" + "time" + + "github.com/scroll-tech/go-ethereum/common" + "github.com/scroll-tech/go-ethereum/core/vm" + "github.com/scroll-tech/go-ethereum/crypto" + "github.com/scroll-tech/go-ethereum/eth/tracers" + "github.com/scroll-tech/go-ethereum/log" +) + +func init() { + register("prestateTracer", newPrestateTracer) +} + +type state = map[common.Address]*account + +type account struct { + Balance *big.Int + Code []byte + Nonce uint64 + Storage map[common.Hash]common.Hash +} + +func (a *account) marshal() accountMarshaling { + return accountMarshaling{ + Balance: bigToHex(a.Balance), + Code: bytesToHex(a.Code), + Nonce: a.Nonce, + Storage: a.Storage, + } +} + +func (a *account) exists() bool { + return a.Nonce > 0 || len(a.Code) > 0 || len(a.Storage) > 0 || (a.Balance != nil && a.Balance.Sign() != 0) +} + +type accountMarshaling struct { + Balance string `json:"balance,omitempty"` + Code string `json:"code,omitempty"` + Nonce uint64 `json:"nonce,omitempty"` + Storage map[common.Hash]common.Hash `json:"storage,omitempty"` +} + +type prestateTracer struct { + noopTracer + env *vm.EVM + pre state + post state + create bool + to common.Address + gasLimit uint64 // Amount of gas bought for the whole tx + interrupt atomic.Bool // Atomic flag to signal execution interruption + reason error // Textual reason for the interruption + created map[common.Address]bool + deleted map[common.Address]bool +} + +func newPrestateTracer() tracers.Tracer { + return &prestateTracer{ + pre: state{}, + post: state{}, + created: make(map[common.Address]bool), + deleted: make(map[common.Address]bool), + } +} + +// CaptureStart implements the EVMLogger interface to initialize the tracing operation. +func (t *prestateTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { + t.env = env + t.create = create + t.to = to + + t.lookupAccount(from) + t.lookupAccount(to) + t.lookupAccount(env.Context.Coinbase) + + // The recipient balance includes the value transferred. + toBal := new(big.Int).Sub(t.pre[to].Balance, value) + t.pre[to].Balance = toBal + + // The sender balance is after reducing: value and gasLimit. + // We need to re-add them to get the pre-tx balance. + fromBal := new(big.Int).Set(t.pre[from].Balance) + gasPrice := env.TxContext.GasPrice + consumedGas := new(big.Int).Mul(gasPrice, new(big.Int).SetUint64(t.gasLimit)) + fromBal.Add(fromBal, new(big.Int).Add(value, consumedGas)) + t.pre[from].Balance = fromBal + t.pre[from].Nonce-- +} + +// CaptureEnd is called after the call finishes to finalize the tracing. +func (t *prestateTracer) CaptureEnd(output []byte, gasUsed uint64, d time.Duration, err error) { + if t.create { + // Keep existing account prior to contract creation at that address + if s := t.pre[t.to]; s != nil && !s.exists() { + // Exclude newly created contract. + delete(t.pre, t.to) + } + } +} + +// CaptureState implements the EVMLogger interface to trace a single step of VM execution. +func (t *prestateTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { + if err != nil { + return + } + // Skip if tracing was interrupted + if t.interrupt.Load() { + return + } + stack := scope.Stack + stackData := stack.Data() + stackLen := len(stackData) + caller := scope.Contract.Address() + switch { + case stackLen >= 1 && (op == vm.SLOAD || op == vm.SSTORE): + slot := common.Hash(stackData[stackLen-1].Bytes32()) + t.lookupStorage(caller, slot) + case stackLen >= 1 && (op == vm.EXTCODECOPY || op == vm.EXTCODEHASH || op == vm.EXTCODESIZE || op == vm.BALANCE || op == vm.SELFDESTRUCT): + addr := common.Address(stackData[stackLen-1].Bytes20()) + t.lookupAccount(addr) + if op == vm.SELFDESTRUCT { + t.deleted[caller] = true + } + case stackLen >= 5 && (op == vm.DELEGATECALL || op == vm.CALL || op == vm.STATICCALL || op == vm.CALLCODE): + addr := common.Address(stackData[stackLen-2].Bytes20()) + t.lookupAccount(addr) + case op == vm.CREATE: + nonce := t.env.StateDB.GetNonce(caller) + addr := crypto.CreateAddress(caller, nonce) + t.lookupAccount(addr) + t.created[addr] = true + case stackLen >= 4 && op == vm.CREATE2: + offset := stackData[stackLen-2] + size := stackData[stackLen-3] + init, err := tracers.GetMemoryCopyPadded(scope.Memory, int64(offset.Uint64()), int64(size.Uint64())) + if err != nil { + log.Warn("failed to copy CREATE2 input", "err", err, "tracer", "prestateTracer", "offset", offset, "size", size) + return + } + inithash := crypto.Keccak256(init) + salt := stackData[stackLen-4] + addr := crypto.CreateAddress2(caller, salt.Bytes32(), inithash) + t.lookupAccount(addr) + t.created[addr] = true + } +} + +func (t *prestateTracer) CaptureTxStart(gasLimit uint64) { + t.gasLimit = gasLimit +} + +func (t *prestateTracer) CaptureTxEnd(restGas uint64) { + for addr, state := range t.pre { + // The deleted account's state is pruned from `post` but kept in `pre` + if _, ok := t.deleted[addr]; ok { + continue + } + modified := false + postAccount := &account{Storage: make(map[common.Hash]common.Hash)} + newBalance := t.env.StateDB.GetBalance(addr) + newNonce := t.env.StateDB.GetNonce(addr) + newCode := t.env.StateDB.GetCode(addr) + + if newBalance.Cmp(t.pre[addr].Balance) != 0 { + modified = true + postAccount.Balance = newBalance + } + if newNonce != t.pre[addr].Nonce { + modified = true + postAccount.Nonce = newNonce + } + if !bytes.Equal(newCode, t.pre[addr].Code) { + modified = true + postAccount.Code = newCode + } + + for key, val := range state.Storage { + // don't include the empty slot + if val == (common.Hash{}) { + delete(t.pre[addr].Storage, key) + } + + newVal := t.env.StateDB.GetState(addr, key) + if val == newVal { + // Omit unchanged slots + delete(t.pre[addr].Storage, key) + } else { + modified = true + if newVal != (common.Hash{}) { + postAccount.Storage[key] = newVal + } + } + } + + if modified { + t.post[addr] = postAccount + } else { + // if state is not modified, then no need to include into the pre state + delete(t.pre, addr) + } + } + // the new created contracts' prestate were empty, so delete them + for a := range t.created { + // the created contract maybe exists in statedb before the creating tx + if s := t.pre[a]; s != nil && !s.exists() { + delete(t.pre, a) + } + } +} + +// GetResult returns the json-encoded nested list of call traces, and any +// error arising from the encoding or forceful termination (via `Stop`). +func (t *prestateTracer) GetResult() (json.RawMessage, error) { + pre := make(map[string]accountMarshaling) + for addr, state := range t.pre { + pre[addrToHex(addr)] = state.marshal() + } + res, err := json.Marshal(pre) + if err != nil { + return nil, err + } + return res, t.reason +} + +// Stop terminates execution of the tracer at the first opportune moment. +func (t *prestateTracer) Stop(err error) { + t.reason = err + t.interrupt.Store(true) +} + +// lookupAccount fetches details of an account and adds it to the prestate +// if it doesn't exist there. +func (t *prestateTracer) lookupAccount(addr common.Address) { + if _, ok := t.pre[addr]; ok { + return + } + + t.pre[addr] = &account{ + Balance: t.env.StateDB.GetBalance(addr), + Nonce: t.env.StateDB.GetNonce(addr), + Code: t.env.StateDB.GetCode(addr), + Storage: make(map[common.Hash]common.Hash), + } +} + +// lookupStorage fetches the requested storage slot and adds +// it to the prestate of the given contract. It assumes `lookupAccount` +// has been performed on the contract before. +func (t *prestateTracer) lookupStorage(addr common.Address, key common.Hash) { + if _, ok := t.pre[addr].Storage[key]; ok { + return + } + t.pre[addr].Storage[key] = t.env.StateDB.GetState(addr, key) +} diff --git a/eth/tracers/tracers.go b/eth/tracers/tracers.go index a07a2ba66c..69d3d2cdc2 100644 --- a/eth/tracers/tracers.go +++ b/eth/tracers/tracers.go @@ -20,6 +20,7 @@ package tracers import ( "encoding/json" "errors" + "fmt" "github.com/scroll-tech/go-ethereum/common" "github.com/scroll-tech/go-ethereum/core/vm" @@ -70,3 +71,27 @@ func New(code string, ctx *Context) (Tracer, error) { } return nil, errors.New("tracer not found") } + +const ( + memoryPadLimit = 1024 * 1024 +) + +// GetMemoryCopyPadded returns offset + size as a new slice. +// It zero-pads the slice if it extends beyond memory bounds. +func GetMemoryCopyPadded(m *vm.Memory, offset, size int64) ([]byte, error) { + if offset < 0 || size < 0 { + return nil, errors.New("offset or size must not be negative") + } + if int(offset+size) < m.Len() { // slice fully inside memory + return m.GetCopy(offset, size), nil + } + paddingNeeded := int(offset+size) - m.Len() + if paddingNeeded > memoryPadLimit { + return nil, fmt.Errorf("reached limit for padding memory slice: %d", paddingNeeded) + } + cpy := make([]byte, size) + if overlap := int64(m.Len()) - offset; overlap > 0 { + copy(cpy, m.GetPtr(offset, overlap)) + } + return cpy, nil +} diff --git a/go.mod b/go.mod index 28d60c7e4e..009882a337 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/scroll-tech/go-ethereum -go 1.18 +go 1.20 require ( github.com/Azure/azure-storage-blob-go v0.7.0 diff --git a/light/odr_test.go b/light/odr_test.go index a19c0d228e..41c6c48901 100644 --- a/light/odr_test.go +++ b/light/odr_test.go @@ -264,7 +264,7 @@ func testChainOdr(t *testing.T, protocol int, fn odrTestFn) { ) gspec.MustCommit(ldb) // Assemble the test environment - blockchain, _ := core.NewBlockChain(sdb, nil, params.TestChainConfig, ethash.NewFullFaker(), vm.Config{}, nil, nil, false) + blockchain, _ := core.NewBlockChain(sdb, nil, params.TestChainConfig, ethash.NewFullFaker(), vm.Config{}, nil, nil) gchain, _ := core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), sdb, 4, testChainGen) if _, err := blockchain.InsertChain(gchain); err != nil { t.Fatal(err) diff --git a/light/trie_test.go b/light/trie_test.go index ee4c0131c4..3dda9ebdb4 100644 --- a/light/trie_test.go +++ b/light/trie_test.go @@ -45,7 +45,7 @@ func TestNodeIterator(t *testing.T) { genesis = gspec.MustCommit(fulldb) ) gspec.MustCommit(lightdb) - blockchain, _ := core.NewBlockChain(fulldb, nil, params.TestChainConfig, ethash.NewFullFaker(), vm.Config{}, nil, nil, false) + blockchain, _ := core.NewBlockChain(fulldb, nil, params.TestChainConfig, ethash.NewFullFaker(), vm.Config{}, nil, nil) gchain, _ := core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), fulldb, 4, testChainGen) if _, err := blockchain.InsertChain(gchain); err != nil { panic(err) diff --git a/light/txpool_test.go b/light/txpool_test.go index 13757c4965..5bd8281c7a 100644 --- a/light/txpool_test.go +++ b/light/txpool_test.go @@ -91,7 +91,7 @@ func TestTxPool(t *testing.T) { ) gspec.MustCommit(ldb) // Assemble the test environment - blockchain, _ := core.NewBlockChain(sdb, nil, params.TestChainConfig, ethash.NewFullFaker(), vm.Config{}, nil, nil, false) + blockchain, _ := core.NewBlockChain(sdb, nil, params.TestChainConfig, ethash.NewFullFaker(), vm.Config{}, nil, nil) gchain, _ := core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), sdb, poolTestBlocks, txPoolTestChainGen) if _, err := blockchain.InsertChain(gchain); err != nil { panic(err) diff --git a/miner/miner_test.go b/miner/miner_test.go index 63bb1d4249..a83fc2c8b1 100644 --- a/miner/miner_test.go +++ b/miner/miner_test.go @@ -257,7 +257,7 @@ func createMiner(t *testing.T) (*Miner, *event.TypeMux) { // Create consensus engine engine := clique.New(chainConfig.Clique, chainDB) // Create Ethereum backend - bc, err := core.NewBlockChain(chainDB, nil, chainConfig, engine, vm.Config{}, nil, nil, false) + bc, err := core.NewBlockChain(chainDB, nil, chainConfig, engine, vm.Config{}, nil, nil) if err != nil { t.Fatalf("can't create new chain %v", err) } diff --git a/miner/worker.go b/miner/worker.go index d9596f7b7d..744d3ef657 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -39,6 +39,7 @@ import ( "github.com/scroll-tech/go-ethereum/metrics" "github.com/scroll-tech/go-ethereum/params" "github.com/scroll-tech/go-ethereum/rollup/circuitcapacitychecker" + "github.com/scroll-tech/go-ethereum/rollup/tracing" "github.com/scroll-tech/go-ethereum/trie" ) @@ -121,7 +122,7 @@ type environment struct { receipts []*types.Receipt // circuit capacity check related fields - traceEnv *core.TraceEnv // env for tracing + traceEnv *tracing.TraceEnv // env for tracing accRows *types.RowConsumption // accumulated row consumption for a block nextL1MsgIndex uint64 // next L1 queue index to be processed } @@ -808,7 +809,7 @@ func (w *worker) makeCurrent(parent *types.Block, header *types.Header) error { // don't commit the state during tracing for circuit capacity checker, otherwise we cannot revert. // and even if we don't commit the state, the `refund` value will still be correct, as explained in `CommitTransaction` commitStateAfterApply := false - traceEnv, err := core.CreateTraceEnv(w.chainConfig, w.chain, w.engine, w.eth.ChainDb(), state, parent, + traceEnv, err := tracing.CreateTraceEnv(w.chainConfig, w.chain, w.engine, w.eth.ChainDb(), state, parent, // new block with a placeholder tx, for traceEnv's ExecutionResults length & TxStorageTraces length types.NewBlockWithHeader(header).WithBody([]*types.Transaction{types.NewTx(&types.LegacyTx{})}, nil), commitStateAfterApply) diff --git a/miner/worker_test.go b/miner/worker_test.go index 0d0784098d..533c4289a9 100644 --- a/miner/worker_test.go +++ b/miner/worker_test.go @@ -141,7 +141,7 @@ func newTestWorkerBackend(t *testing.T, chainConfig *params.ChainConfig, engine chain, _ := core.NewBlockChain(db, &core.CacheConfig{TrieDirtyDisabled: true}, gspec.Config, engine, vm.Config{ Debug: true, - Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true})}, nil, nil, false) + Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true})}, nil, nil) txpool := core.NewTxPool(testTxPoolConfig, chainConfig, chain) // Generate a small n-block chain and an uncle block for it @@ -242,7 +242,7 @@ func testGenerateBlockAndImport(t *testing.T, isClique bool) { b.genesis.MustCommit(db2) chain, _ := core.NewBlockChain(db2, nil, b.chain.Config(), engine, vm.Config{ Debug: true, - Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true, EnableReturnData: true})}, nil, nil, false) + Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true, EnableReturnData: true})}, nil, nil) defer chain.Stop() // Ignore empty commit here for less noise. @@ -572,7 +572,7 @@ func testGenerateBlockWithL1Msg(t *testing.T, isClique bool) { b.genesis.MustCommit(db) chain, _ := core.NewBlockChain(db, nil, b.chain.Config(), engine, vm.Config{ Debug: true, - Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true, EnableReturnData: true})}, nil, nil, false) + Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true, EnableReturnData: true})}, nil, nil) defer chain.Stop() // Ignore empty commit here for less noise. @@ -639,7 +639,7 @@ func TestAcceptableTxlimit(t *testing.T) { b.genesis.MustCommit(db) chain, _ := core.NewBlockChain(db, nil, b.chain.Config(), engine, vm.Config{ Debug: true, - Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true, EnableReturnData: true})}, nil, nil, false) + Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true, EnableReturnData: true})}, nil, nil) defer chain.Stop() // Ignore empty commit here for less noise. @@ -702,7 +702,7 @@ func TestUnacceptableTxlimit(t *testing.T) { b.genesis.MustCommit(db) chain, _ := core.NewBlockChain(db, nil, b.chain.Config(), engine, vm.Config{ Debug: true, - Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true, EnableReturnData: true})}, nil, nil, false) + Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true, EnableReturnData: true})}, nil, nil) defer chain.Stop() // Ignore empty commit here for less noise. @@ -765,7 +765,7 @@ func TestL1MsgCorrectOrder(t *testing.T) { b.genesis.MustCommit(db) chain, _ := core.NewBlockChain(db, nil, b.chain.Config(), engine, vm.Config{ Debug: true, - Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true, EnableReturnData: true})}, nil, nil, false) + Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true, EnableReturnData: true})}, nil, nil) defer chain.Stop() // Ignore empty commit here for less noise. @@ -827,7 +827,7 @@ func l1MessageTest(t *testing.T, msgs []types.L1MessageTx, withL2Tx bool, callba b.genesis.MustCommit(db) chain, _ := core.NewBlockChain(db, nil, b.chain.Config(), engine, vm.Config{ Debug: true, - Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true, EnableReturnData: true})}, nil, nil, false) + Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true, EnableReturnData: true})}, nil, nil) defer chain.Stop() // Ignore empty commit here for less noise. @@ -1135,7 +1135,7 @@ func TestPrioritizeOverflowTx(t *testing.T) { b.genesis.MustCommit(db2) chain, _ := core.NewBlockChain(db2, nil, b.chain.Config(), engine, vm.Config{ Debug: true, - Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true, EnableReturnData: true})}, nil, nil, false) + Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true, EnableReturnData: true})}, nil, nil) defer chain.Stop() // Ignore empty commit here for less noise. diff --git a/params/version.go b/params/version.go index f41ff07025..9954431bc6 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 5 // Major version component of the current release VersionMinor = 1 // Minor version component of the current release - VersionPatch = 12 // Patch version component of the current release + VersionPatch = 13 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string ) diff --git a/rollup/tracing/mux_tracer.go b/rollup/tracing/mux_tracer.go new file mode 100644 index 0000000000..d71637ccc6 --- /dev/null +++ b/rollup/tracing/mux_tracer.go @@ -0,0 +1,69 @@ +package tracing + +import ( + "math/big" + "time" + + "github.com/scroll-tech/go-ethereum/common" + "github.com/scroll-tech/go-ethereum/core/vm" + _ "github.com/scroll-tech/go-ethereum/eth/tracers/native" +) + +// MuxTracer is a tracer mux, to support running multiple tracers together +type MuxTracer struct { + tracers []vm.EVMLogger +} + +// NewMuxTracer creates a new MuxTracer with multiple tracers +func NewMuxTracer(tracers ...vm.EVMLogger) *MuxTracer { + return &MuxTracer{tracers} +} + +// CaptureStart runs CaptureStart for each tracer in the MuxTracer +func (t *MuxTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { + for _, tracer := range t.tracers { + tracer.CaptureStart(env, from, to, create, input, gas, value) + } +} + +// CaptureState runs CaptureState for each tracer in the MuxTracer +func (t *MuxTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { + for _, tracer := range t.tracers { + tracer.CaptureState(pc, op, gas, cost, scope, rData, depth, err) + } +} + +// CaptureStateAfter runs CaptureStateAfter for each tracer in the MuxTracer +func (t *MuxTracer) CaptureStateAfter(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { + for _, tracer := range t.tracers { + tracer.CaptureStateAfter(pc, op, gas, cost, scope, rData, depth, err) + } +} + +// CaptureEnter runs CaptureEnter for each tracer in the MuxTracer +func (t *MuxTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { + for _, tracer := range t.tracers { + tracer.CaptureEnter(typ, from, to, input, gas, value) + } +} + +// CaptureExit runs CaptureExit for each tracer in the MuxTracer +func (t *MuxTracer) CaptureExit(output []byte, gasUsed uint64, err error) { + for _, tracer := range t.tracers { + tracer.CaptureExit(output, gasUsed, err) + } +} + +// CaptureFault runs CaptureFault for each tracer in the MuxTracer +func (t *MuxTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { + for _, tracer := range t.tracers { + tracer.CaptureFault(pc, op, gas, cost, scope, depth, err) + } +} + +// CaptureEnd runs CaptureEnd for each tracer in the MuxTracer +func (t *MuxTracer) CaptureEnd(output []byte, gasUsed uint64, d time.Duration, err error) { + for _, tracer := range t.tracers { + tracer.CaptureEnd(output, gasUsed, d, err) + } +} diff --git a/core/trace.go b/rollup/tracing/tracing.go similarity index 85% rename from core/trace.go rename to rollup/tracing/tracing.go index d91987dd2d..9a840d6271 100644 --- a/core/trace.go +++ b/rollup/tracing/tracing.go @@ -1,4 +1,4 @@ -package core +package tracing import ( "bytes" @@ -10,10 +10,13 @@ import ( "github.com/scroll-tech/go-ethereum/common" "github.com/scroll-tech/go-ethereum/common/hexutil" "github.com/scroll-tech/go-ethereum/consensus" + "github.com/scroll-tech/go-ethereum/core" "github.com/scroll-tech/go-ethereum/core/rawdb" "github.com/scroll-tech/go-ethereum/core/state" "github.com/scroll-tech/go-ethereum/core/types" "github.com/scroll-tech/go-ethereum/core/vm" + "github.com/scroll-tech/go-ethereum/eth/tracers" + _ "github.com/scroll-tech/go-ethereum/eth/tracers/native" "github.com/scroll-tech/go-ethereum/ethdb" "github.com/scroll-tech/go-ethereum/log" "github.com/scroll-tech/go-ethereum/params" @@ -23,6 +26,24 @@ import ( "github.com/scroll-tech/go-ethereum/trie/zkproof" ) +// TracerWrapper implements ScrollTracerWrapper interface +type TracerWrapper struct{} + +// TracerWrapper creates a new TracerWrapper +func NewTracerWrapper() *TracerWrapper { + return &TracerWrapper{} +} + +// CreateTraceEnvAndGetBlockTrace wraps the whole block tracing logic for a block +func (tw *TracerWrapper) CreateTraceEnvAndGetBlockTrace(chainConfig *params.ChainConfig, chainContext core.ChainContext, engine consensus.Engine, chaindb ethdb.Database, statedb *state.StateDB, parent *types.Block, block *types.Block, commitAfterApply bool) (*types.BlockTrace, error) { + traceEnv, err := CreateTraceEnv(chainConfig, chainContext, engine, chaindb, statedb, parent, block, commitAfterApply) + if err != nil { + return nil, err + } + + return traceEnv.GetBlockTrace(block) +} + type TraceEnv struct { logConfig *vm.LogConfig commitAfterApply bool @@ -88,8 +109,9 @@ func CreateTraceEnvHelper(chainConfig *params.ChainConfig, logConfig *vm.LogConf } } -func CreateTraceEnv(chainConfig *params.ChainConfig, chainContext ChainContext, engine consensus.Engine, chaindb ethdb.Database, statedb *state.StateDB, parent *types.Block, block *types.Block, commitAfterApply bool) (*TraceEnv, error) { +func CreateTraceEnv(chainConfig *params.ChainConfig, chainContext core.ChainContext, engine consensus.Engine, chaindb ethdb.Database, statedb *state.StateDB, parent *types.Block, block *types.Block, commitAfterApply bool) (*TraceEnv, error) { var coinbase common.Address + var err error if chainConfig.Scroll.FeeVaultEnabled() { coinbase = *chainConfig.Scroll.FeeVaultAddress @@ -119,11 +141,10 @@ func CreateTraceEnv(chainConfig *params.ChainConfig, chainContext ChainContext, env := CreateTraceEnvHelper( chainConfig, &vm.LogConfig{ - DisableStorage: true, EnableMemory: false, EnableReturnData: true, }, - NewEVMBlockContext(block.Header(), chainContext, chainConfig, nil), + core.NewEVMBlockContext(block.Header(), chainContext, chainConfig, nil), *startL1QueueIndex, coinbase, statedb, @@ -189,13 +210,13 @@ func (env *TraceEnv) GetBlockTrace(block *types.Block) (*types.BlockTrace, error // Generate the next state snapshot fast without tracing msg, _ := tx.AsMessage(env.signer, block.BaseFee()) env.state.Prepare(tx.Hash(), i) - vmenv := vm.NewEVM(env.blockCtx, NewEVMTxContext(msg), env.state, env.chainConfig, vm.Config{}) + vmenv := vm.NewEVM(env.blockCtx, core.NewEVMTxContext(msg), env.state, env.chainConfig, vm.Config{}) l1DataFee, err := fees.CalculateL1DataFee(tx, env.state) if err != nil { failed = err break } - if _, err = ApplyMessage(vmenv, msg, new(GasPool).AddGas(msg.Gas()), l1DataFee); err != nil { + if _, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), l1DataFee); err != nil { failed = err break } @@ -270,9 +291,24 @@ func (env *TraceEnv) getTxResult(state *state.StateDB, index int, block *types.B } } - tracer := vm.NewStructLogger(env.logConfig) + txContext := core.NewEVMTxContext(msg) + tracerContext := tracers.Context{ + BlockHash: block.Hash(), + TxIndex: index, + TxHash: tx.Hash(), + } + callTracer, err := tracers.New("callTracer", &tracerContext) + if err != nil { + return fmt.Errorf("failed to create callTracer: %w", err) + } + prestateTracer, err := tracers.New("prestateTracer", &tracerContext) + if err != nil { + return fmt.Errorf("failed to create prestateTracer: %w", err) + } + structLogger := vm.NewStructLogger(env.logConfig) + tracer := NewMuxTracer(structLogger, callTracer, prestateTracer) // Run the transaction with tracing enabled. - vmenv := vm.NewEVM(env.blockCtx, NewEVMTxContext(msg), state, env.chainConfig, vm.Config{Debug: true, Tracer: tracer, NoBaseFee: true}) + vmenv := vm.NewEVM(env.blockCtx, txContext, state, env.chainConfig, vm.Config{Debug: true, Tracer: tracer, NoBaseFee: true}) // Call Prepare to clear out the statedb access list state.Prepare(txctx.TxHash, txctx.TxIndex) @@ -282,7 +318,7 @@ func (env *TraceEnv) getTxResult(state *state.StateDB, index int, block *types.B if err != nil { return err } - result, err := ApplyMessage(vmenv, msg, new(GasPool).AddGas(msg.Gas()), l1DataFee) + result, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), l1DataFee) if err != nil { return err } @@ -292,7 +328,7 @@ func (env *TraceEnv) getTxResult(state *state.StateDB, index int, block *types.B returnVal = result.Revert() } - createdAcc := tracer.CreatedAccount() + createdAcc := structLogger.CreatedAccount() var after []*types.AccountWrapper if to == nil { if createdAcc == nil { @@ -325,7 +361,7 @@ func (env *TraceEnv) getTxResult(state *state.StateDB, index int, block *types.B } // merge required proof data - proofAccounts := tracer.UpdatedAccounts() + proofAccounts := structLogger.UpdatedAccounts() proofAccounts[vmenv.FeeRecipient()] = struct{}{} for addr := range proofAccounts { addrStr := addr.String() @@ -351,7 +387,7 @@ func (env *TraceEnv) getTxResult(state *state.StateDB, index int, block *types.B env.pMu.Unlock() } - proofStorages := tracer.UpdatedStorages() + proofStorages := structLogger.UpdatedStorages() for addr, keys := range proofStorages { if _, existed := txStorageTrace.StorageProofs[addr.String()]; !existed { txStorageTrace.StorageProofs[addr.String()] = make(map[string][]hexutil.Bytes) @@ -420,6 +456,15 @@ func (env *TraceEnv) getTxResult(state *state.StateDB, index int, block *types.B } } + callTrace, err := callTracer.GetResult() + if err != nil { + return fmt.Errorf("failed to get callTracer result: %w", err) + } + prestate, err := prestateTracer.GetResult() + if err != nil { + return fmt.Errorf("failed to get prestateTracer result: %w", err) + } + env.ExecutionResults[index] = &types.ExecutionResult{ From: sender, To: receiver, @@ -429,7 +474,9 @@ func (env *TraceEnv) getTxResult(state *state.StateDB, index int, block *types.B Gas: result.UsedGas, Failed: result.Failed(), ReturnValue: fmt.Sprintf("%x", returnVal), - StructLogs: vm.FormatLogs(tracer.StructLogs()), + StructLogs: vm.FormatLogs(structLogger.StructLogs()), + CallTrace: callTrace, + Prestate: prestate, } env.TxStorageTraces[index] = txStorageTrace diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 34bdc7c7e1..93aeaec91b 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -127,7 +127,7 @@ func (t *BlockTest) Run(snapshotter bool) error { cache.SnapshotLimit = 1 cache.SnapshotWait = true } - chain, err := core.NewBlockChain(db, cache, config, engine, vm.Config{}, nil, nil, false) + chain, err := core.NewBlockChain(db, cache, config, engine, vm.Config{}, nil, nil) if err != nil { return err } @@ -174,17 +174,18 @@ func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis { } } -/* See https://github.com/ethereum/tests/wiki/Blockchain-Tests-II +/* +See https://github.com/ethereum/tests/wiki/Blockchain-Tests-II - Whether a block is valid or not is a bit subtle, it's defined by presence of - blockHeader, transactions and uncleHeaders fields. If they are missing, the block is - invalid and we must verify that we do not accept it. + Whether a block is valid or not is a bit subtle, it's defined by presence of + blockHeader, transactions and uncleHeaders fields. If they are missing, the block is + invalid and we must verify that we do not accept it. - Since some tests mix valid and invalid blocks we need to check this for every block. + Since some tests mix valid and invalid blocks we need to check this for every block. - If a block is invalid it does not necessarily fail the test, if it's invalidness is - expected we are expected to ignore it and continue processing and then validate the - post state. + If a block is invalid it does not necessarily fail the test, if it's invalidness is + expected we are expected to ignore it and continue processing and then validate the + post state. */ func (t *BlockTest) insertBlocks(blockchain *core.BlockChain) ([]btBlock, error) { validBlocks := make([]btBlock, 0) diff --git a/tests/fuzzers/les/les-fuzzer.go b/tests/fuzzers/les/les-fuzzer.go index 3a5027bdd2..52dff68601 100644 --- a/tests/fuzzers/les/les-fuzzer.go +++ b/tests/fuzzers/les/les-fuzzer.go @@ -80,7 +80,7 @@ func makechain() (bc *core.BlockChain, addrHashes, txHashes []common.Hash) { addrHashes = append(addrHashes, crypto.Keccak256Hash(addr[:])) txHashes = append(txHashes, tx.Hash()) }) - bc, _ = core.NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, false) + bc, _ = core.NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) if _, err := bc.InsertChain(blocks); err != nil { panic(err) }