diff --git a/.github/workflows/evmc.yml b/.github/workflows/evmc.yml index 3fe5b3b244..28695e0a82 100644 --- a/.github/workflows/evmc.yml +++ b/.github/workflows/evmc.yml @@ -8,8 +8,8 @@ on: jobs: - build-ewasm: - name: EWASM State Tests + build-evmc: + name: EVMC/EVM+EWASM State Tests runs-on: ubuntu-latest steps: @@ -22,9 +22,31 @@ jobs: - name: Check out code into the Go module directory uses: actions/checkout@v2 + - name: Install cmake + run: | + sudo apt-get update -y + sudo apt-get upgrade -y + sudo apt-get install -y cmake + cmake --version + + - name: Install necessary GLIBCXX version + run: | + strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX + sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y + sudo apt-get update -y + sudo apt-get install -y gcc-9 g++-9 + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 90 + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90 + g++ --version + gcc --version + strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX + - name: Get dependencies run: | go get -v -t -d ./... + git config --global --add safe.directory $(pwd)/tests/evm-benchmarks + git config --global --add safe.directory $(pwd)/tests/testdata + git config --global --add safe.directory $(pwd)/tests/testdata/LegacyTests git submodule update --init --recursive export GOBIN=${HOME}/go/bin mkdir -p "${GOBIN}" diff --git a/.github/workflows/go-generate-check.yml b/.github/workflows/go-generate-check.yml new file mode 100644 index 0000000000..b36c833661 --- /dev/null +++ b/.github/workflows/go-generate-check.yml @@ -0,0 +1,67 @@ +name: Developer helper +on: pull_request +env: + # GENERATE_EXCEPTIONS are exceptions made to the 'go generate' command. + # These patterns are matched (negatively) against 'go list' output. + # + # - trezor: Ignore generating trezor package based on this comment: + # https://github.com/ethereum/go-ethereum/blob/master/accounts/usbwallet/trezor/trezor.go#L21-L43 + GENERATE_EXCEPTIONS: | + trezor +jobs: + go-generate-check: + name: Check if "go generate" has been run + runs-on: ubuntu-latest + steps: + - name: Set up Go 1.x + id: go + uses: actions/setup-go@v2 + with: + go-version: ^1.16 + - name: Check out code into the Go module directory + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Install deps + id: install-deps + run: | + SOLC_BIN=solc-linux-amd64-v0.6.0+commit.26b70077 + curl -OL https://binaries.soliditylang.org/linux-amd64/$SOLC_BIN + sudo mv $SOLC_BIN /usr/bin/solc + sudo chmod +x /usr/bin/solc + + shell: bash + - name: Install devtools + id: install-devtools + run: make devtools + - name: Run go:generate + id: go-generate + run: | + list="$(go list ./...)" + for pattern in ${GENERATE_EXCEPTIONS[@]}; do + list="$(grep -v "$pattern" <<< "$list")" + done + go generate "$list" + - name: Revert custom generated files modifications before comparing them + id: revert-custom-generated-modifications + run: | + # NOTE to developers checking what triggered this alert. + # This script is meant to alert you if some files have to be regenerated using `go generate`. + # If this happens, you have to run `go generate ./...` and then check the below commits that are being reverted and reapply them, after considering if they are needed. + + git config user.name github-actions + git config user.email github-actions@github.com + + # Intentionally revert this commit which has a custom modification to the genesis unmarshaling, + # with regards reading different genesis formats origniating from different clients + # This way, this script can alert us on any code changes that have to be applied on if file gets changed. + git revert --no-edit 4b2cf83737ffe7c46c334a11414d151de049e0b3 + + - name: Check for modified files + id: git-check + run: | + if ! git diff-index --quiet HEAD --; then + echo "🔴 ERROR: There are modified files after running 'go generate'" + git status + exit 1 + fi diff --git a/.gitmodules b/.gitmodules index 5d72021167..90207861e6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "tests"] path = tests/testdata - url = https://github.com/etclabscore/tests + url = https://github.com/ethereum/tests shallow = true [submodule "evm-benchmarks"] path = tests/evm-benchmarks @@ -8,4 +8,5 @@ shallow = true [submodule "tests-etc"] path = tests/testdata-etc - url = https://github.com/etclabscore/tests-etc + url = https://github.com/etclabscore/tests + shallow = true diff --git a/Makefile b/Makefile index d8f0c9935a..552a9e417a 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ ios: @echo "Import \"$(GOBIN)/Geth.framework\" to use the library." test: - $(GORUN) build/ci.go test + $(GORUN) build/ci.go test -timeout 20m # DEPRECATED. # No attempt will be made after the Istanbul fork to maintain @@ -48,24 +48,16 @@ test-coregeth: \ hera: ./build/hera.sh -ssvm: - ./build/ssvm.sh - evmone: ./build/evmone.sh -aleth-interpreter: - ./build/aleth-interpreter.sh - # Test EVMC support against various external interpreters. -test-evmc: hera ssvm evmone aleth-interpreter +test-evmc: hera evmone go test -count 1 ./tests -run TestState -evmc.ewasm=$(ROOT_DIR)/build/_workspace/hera/build/src/libhera.so - go test -count 1 ./tests -run TestState -evmc.ewasm=$(ROOT_DIR)/build/_workspace/SSVM/build/tools/ssvm-evmc/libssvmEVMC.so go test -count 1 ./tests -run TestState -evmc.evm=$(ROOT_DIR)/build/_workspace/evmone/lib/libevmone.so - go test -count 1 ./tests -run TestState -evmc.evm=$(ROOT_DIR)/build/_workspace/aleth/lib/libaleth-interpreter.so clean-evmc: - rm -rf ./build/_workspace/hera ./build/_workspace/SSVM ./build/_workspace/evmone ./build/_workspace/aleth + rm -rf ./build/_workspace/hera ./build/_workspace/evmone test-coregeth-features: \ test-coregeth-features-coregeth \ diff --git a/build/aleth-interpreter.sh b/build/aleth-interpreter.sh deleted file mode 100755 index 42942cabac..0000000000 --- a/build/aleth-interpreter.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -set -e - - -if [[ "$OSTYPE" != "linux"* ]]; then - echo "This script is only currently configured to work on Linux. Please see \"https://github.com/ethereum/aleth\" documentation for instructions to build in other environments." - exit 1 -fi - -mkdir -p build/_workspace/aleth -[[ -f build/_workspace/aleth/aleth-1.8.0-linux-x86_64.tar.gz ]] && exit 0 -wget -O build/_workspace/aleth/aleth-1.8.0-linux-x86_64.tar.gz https://github.com/ethereum/aleth/releases/download/v1.8.0/aleth-1.8.0-linux-x86_64.tar.gz -tar xzvf build/_workspace/aleth/aleth-1.8.0-linux-x86_64.tar.gz -C build/_workspace/aleth/ diff --git a/build/ci.go b/build/ci.go index 0d239fc9f0..1c05fc9f19 100644 --- a/build/ci.go +++ b/build/ci.go @@ -138,7 +138,7 @@ var ( "focal": "golang-go", // EOL: 04/2030 "impish": "golang-go", // EOL: 07/2022 "jammy": "golang-go", // EOL: 04/2032 - //"kinetic": "golang-go", // EOL: 07/2023 + // "kinetic": "golang-go", // EOL: 07/2023 } debGoBootPaths = map[string]string{ @@ -349,7 +349,7 @@ func doLint(cmdline []string) { } linter := downloadLinter(*cachedir) - lflags := []string{"run", "--timeout", "3m0s", "--config", ".golangci.yml"} + lflags := []string{"run", "--timeout", "5m0s", "--config", ".golangci.yml"} build.MustRunCommand(linter, append(lflags, packages...)...) fmt.Println("You have achieved perfection.") } diff --git a/build/evmone.sh b/build/evmone.sh index 36c379d13d..ba1f3cfac6 100755 --- a/build/evmone.sh +++ b/build/evmone.sh @@ -8,6 +8,6 @@ if [[ "$OSTYPE" != "linux"* ]]; then fi mkdir -p build/_workspace/evmone -[[ -f build/_workspace/evmone/evmone-0.5.0-linux-x86_64.tar.gz ]] && exit 0 -wget -O build/_workspace/evmone/evmone-0.5.0-linux-x86_64.tar.gz https://github.com/ethereum/evmone/releases/download/v0.5.0/evmone-0.5.0-linux-x86_64.tar.gz -tar xzvf build/_workspace/evmone/evmone-0.5.0-linux-x86_64.tar.gz -C build/_workspace/evmone/ +[[ -f build/_workspace/evmone/evmone-0.9.1-linux-x86_64.tar.gz ]] && exit 0 +wget -O build/_workspace/evmone/evmone-0.9.1-linux-x86_64.tar.gz https://github.com/ethereum/evmone/releases/download/v0.9.1/evmone-0.9.1-linux-x86_64.tar.gz +tar xzvf build/_workspace/evmone/evmone-0.9.1-linux-x86_64.tar.gz -C build/_workspace/evmone/ diff --git a/build/hera.sh b/build/hera.sh index e21e6aca2f..09fc3505ea 100755 --- a/build/hera.sh +++ b/build/hera.sh @@ -16,7 +16,7 @@ main() { mkdir -p build/_workspace [ ! -d build/_workspace/hera ] && git clone https://github.com/ewasm/hera build/_workspace/hera || echo "Hera exists." cd build/_workspace/hera - git checkout v0.3.2 + git checkout v0.6.0 git submodule update --init mkdir -p build cd build diff --git a/build/ssvm.sh b/build/ssvm.sh deleted file mode 100755 index c6d33c70f1..0000000000 --- a/build/ssvm.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -set -e - -if [[ "$OSTYPE" != "linux"* ]]; then - echo "This script is only currently configured to work on Linux. Please see \"https://github.com/second-state/ssvm-evmc#notice\" documentation for instructions to build in other environments." - exit 1 -fi - -mkdir -p build/_workspace/SSVM/build/tools/ssvm-evmc/ -[[ -f build/_workspace/SSVM/build/tools/ssvm-evmc/libssvmEVMC.so ]] && exit 0 -wget -O build/_workspace/SSVM/build/tools/ssvm-evmc/libssvmEVMC.so \ - https://github.com/second-state/ssvm-evmc/releases/download/evmc7-0.1.1/libssvm-evmc.so diff --git a/cmd/devp2p/internal/ethtest/suite_test.go b/cmd/devp2p/internal/ethtest/suite_test.go index 4117ccd269..18aabaf305 100644 --- a/cmd/devp2p/internal/ethtest/suite_test.go +++ b/cmd/devp2p/internal/ethtest/suite_test.go @@ -36,7 +36,7 @@ var ( ) func TestEthSuite(t *testing.T) { - geth, err := runGeth() + geth, err := runGeth(t) if err != nil { t.Fatalf("could not run geth: %v", err) } @@ -48,6 +48,7 @@ func TestEthSuite(t *testing.T) { } for _, test := range suite.EthTests() { t.Run(test.Name, func(t *testing.T) { + time.Sleep(time.Second) result := utesting.RunTAP([]utesting.Test{{Name: test.Name, Fn: test.Fn}}, os.Stdout) if result[0].Failed { t.Fatal() @@ -57,7 +58,7 @@ func TestEthSuite(t *testing.T) { } func TestSnapSuite(t *testing.T) { - geth, err := runGeth() + geth, err := runGeth(t) if err != nil { t.Fatalf("could not run geth: %v", err) } @@ -69,6 +70,7 @@ func TestSnapSuite(t *testing.T) { } for _, test := range suite.SnapTests() { t.Run(test.Name, func(t *testing.T) { + time.Sleep(time.Second) result := utesting.RunTAP([]utesting.Test{{Name: test.Name, Fn: test.Fn}}, os.Stdout) if result[0].Failed { t.Fatal() @@ -78,7 +80,8 @@ func TestSnapSuite(t *testing.T) { } // runGeth creates and starts a geth node -func runGeth() (*node.Node, error) { +func runGeth(t *testing.T) (*node.Node, error) { + t.Helper() stack, err := node.New(&node.Config{ P2P: p2p.Config{ ListenAddr: "127.0.0.1:0", @@ -100,6 +103,7 @@ func runGeth() (*node.Node, error) { stack.Close() return nil, err } + return stack, nil } diff --git a/cmd/echainspec/util.go b/cmd/echainspec/util.go index c97da2c8e2..78a2e2771d 100644 --- a/cmd/echainspec/util.go +++ b/cmd/echainspec/util.go @@ -3,7 +3,7 @@ package main import ( "encoding/json" "fmt" - "io/ioutil" + "io" "os" "strings" @@ -15,9 +15,9 @@ import ( func readInputData(ctx *cli.Context) ([]byte, error) { if !ctx.GlobalIsSet(fileInFlag.Name) { - return ioutil.ReadAll(os.Stdin) + return io.ReadAll(os.Stdin) } - return ioutil.ReadFile(ctx.GlobalString(fileInFlag.Name)) + return os.ReadFile(ctx.GlobalString(fileInFlag.Name)) } func unmarshalChainSpec(format string, data []byte) (conf ctypes.Configurator, err error) { diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 13d9eee8cd..d36eb1bffc 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -58,6 +58,7 @@ type ExecutionResult struct { Rejected []*rejectedTx `json:"rejected,omitempty"` Difficulty *math.HexOrDecimal256 `json:"currentDifficulty" gencodec:"required"` GasUsed math.HexOrDecimal64 `json:"gasUsed"` + BaseFee *math.HexOrDecimal256 `json:"currentBaseFee,omitempty"` } type ommer struct { @@ -273,6 +274,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig ctypes.ChainConfigura Rejected: rejectedTxs, Difficulty: (*math.HexOrDecimal256)(vmContext.Difficulty), GasUsed: (math.HexOrDecimal64)(gasUsed), + BaseFee: (*math.HexOrDecimal256)(vmContext.BaseFee), } return statedb, execRs, nil } diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index d5d1ba8939..3ad12890c4 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -26,6 +26,7 @@ import ( "path" "strings" + "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/state" @@ -178,9 +179,20 @@ func Transition(ctx *cli.Context) error { prestate.Env = *inputData.Env vmConfig := vm.Config{ - Tracer: tracer, - Debug: (tracer != nil), + Tracer: tracer, + Debug: (tracer != nil), + EVMInterpreter: ctx.String(utils.EVMInterpreterFlag.Name), + EWASMInterpreter: ctx.String(utils.EWASMInterpreterFlag.Name), } + + if vmConfig.EVMInterpreter != "" { + vm.InitEVMCEVM(vmConfig.EVMInterpreter) + } + + if vmConfig.EWASMInterpreter != "" { + vm.InitEVMCEwasm(vmConfig.EWASMInterpreter) + } + // Construct the chainconfig var chainConfig ctypes.ChainConfigurator if cConf, extraEips, err := tests.GetChainConfig(ctx.String(ForknameFlag.Name)); err != nil { diff --git a/cmd/evm/main.go b/cmd/evm/main.go index 5d4fefeb25..92131edc5e 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -23,6 +23,7 @@ import ( "os" "github.com/ethereum/go-ethereum/cmd/evm/internal/t8ntool" + "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/internal/flags" "github.com/urfave/cli/v2" ) @@ -132,11 +133,6 @@ var ( Value: true, Usage: "enable return data output", } - EVMInterpreterFlag = &cli.StringFlag{ - Name: "vm.evm", - Usage: "External EVM configuration (default = built-in interpreter)", - Value: "", - } ) var stateTransitionCommand = &cli.Command{ @@ -162,6 +158,8 @@ var stateTransitionCommand = &cli.Command{ t8ntool.ChainIDFlag, t8ntool.RewardFlag, t8ntool.VerbosityFlag, + utils.EVMInterpreterFlag, + utils.EWASMInterpreterFlag, }, } @@ -222,7 +220,7 @@ func init() { DisableStackFlag, DisableStorageFlag, DisableReturnDataFlag, - EVMInterpreterFlag, + utils.EVMInterpreterFlag, } app.Commands = []*cli.Command{ compileCommand, diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index 1299e7b195..c4186bb550 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -217,7 +217,7 @@ func runCmd(ctx *cli.Context) error { EVMConfig: vm.Config{ Tracer: tracer, Debug: ctx.Bool(DebugFlag.Name) || ctx.Bool(MachineFlag.Name), - EVMInterpreter: ctx.String(EVMInterpreterFlag.Name), + EVMInterpreter: ctx.String(utils.EVMInterpreterFlag.Name), }, } diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go index 29a689e3eb..3fa93aec7b 100644 --- a/cmd/evm/staterunner.go +++ b/cmd/evm/staterunner.go @@ -22,6 +22,7 @@ import ( "fmt" "os" + "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers/logger" @@ -37,8 +38,12 @@ var stateTestCommand = &cli.Command{ Name: "statetest", Usage: "executes the given state tests", ArgsUsage: "", - Flags: []cli.Flag{stateTestEVMCEWASMFlag, stateTestForkFlag}, - Category: flags.DevCategory, + Flags: []cli.Flag{ + stateTestForkFlag, + stateTestEVMCEWASMFlag, + utils.EVMInterpreterFlag, + }, + Category: flags.DevCategory, } var stateTestEVMCEWASMFlag = &cli.StringFlag{ @@ -113,7 +118,16 @@ func stateTestCmd(ctx *cli.Context) error { Tracer: tracer, Debug: ctx.Bool(DebugFlag.Name) || ctx.Bool(MachineFlag.Name), EWASMInterpreter: ctx.String(stateTestEVMCEWASMFlag.Name), + EVMInterpreter: ctx.String(utils.EVMInterpreterFlag.Name), + } + + if cfg.EVMInterpreter != "" { + vm.InitEVMCEVM(cfg.EVMInterpreter) } + if cfg.EWASMInterpreter != "" { + vm.InitEVMCEwasm(cfg.EWASMInterpreter) + } + results := make([]StatetestResult, 0, len(tests)) for key, test := range tests { for _, st := range test.Subtests(nil) { diff --git a/cmd/evm/testdata/13/exp2.json b/cmd/evm/testdata/13/exp2.json index ba8c9f865b..cbad6552c1 100644 --- a/cmd/evm/testdata/13/exp2.json +++ b/cmd/evm/testdata/13/exp2.json @@ -34,6 +34,7 @@ } ], "currentDifficulty": "0x20000", - "gasUsed": "0x109a0" + "gasUsed": "0x109a0", + "currentBaseFee": "0x36b" } } diff --git a/cmd/evm/testdata/14/exp.json b/cmd/evm/testdata/14/exp.json index 9bf5635f5b..26d49173ce 100644 --- a/cmd/evm/testdata/14/exp.json +++ b/cmd/evm/testdata/14/exp.json @@ -7,6 +7,7 @@ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "currentDifficulty": "0x2000020000000", "receipts": [], - "gasUsed": "0x0" + "gasUsed": "0x0", + "currentBaseFee": "0x500" } } diff --git a/cmd/evm/testdata/14/exp2.json b/cmd/evm/testdata/14/exp2.json index 9c9025381f..cd75b47d5a 100644 --- a/cmd/evm/testdata/14/exp2.json +++ b/cmd/evm/testdata/14/exp2.json @@ -7,6 +7,7 @@ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "receipts": [], "currentDifficulty": "0x1ff8020000000", - "gasUsed": "0x0" + "gasUsed": "0x0", + "currentBaseFee": "0x500" } } diff --git a/cmd/evm/testdata/14/exp_berlin.json b/cmd/evm/testdata/14/exp_berlin.json index c2bf953119..5c00ef130a 100644 --- a/cmd/evm/testdata/14/exp_berlin.json +++ b/cmd/evm/testdata/14/exp_berlin.json @@ -7,6 +7,7 @@ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "receipts": [], "currentDifficulty": "0x1ff9000000000", - "gasUsed": "0x0" + "gasUsed": "0x0", + "currentBaseFee": "0x500" } } diff --git a/cmd/evm/testdata/19/exp_arrowglacier.json b/cmd/evm/testdata/19/exp_arrowglacier.json index 9cf56ffafc..dd49f7d02e 100644 --- a/cmd/evm/testdata/19/exp_arrowglacier.json +++ b/cmd/evm/testdata/19/exp_arrowglacier.json @@ -7,6 +7,7 @@ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "currentDifficulty": "0x2000000200000", "receipts": [], - "gasUsed": "0x0" + "gasUsed": "0x0", + "currentBaseFee": "0x500" } } diff --git a/cmd/evm/testdata/19/exp_grayglacier.json b/cmd/evm/testdata/19/exp_grayglacier.json index 95a3cb1685..86fd8e6c13 100644 --- a/cmd/evm/testdata/19/exp_grayglacier.json +++ b/cmd/evm/testdata/19/exp_grayglacier.json @@ -7,6 +7,7 @@ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "receipts": [], "currentDifficulty": "0x2000000004000", - "gasUsed": "0x0" + "gasUsed": "0x0", + "currentBaseFee": "0x500" } } \ No newline at end of file diff --git a/cmd/evm/testdata/19/exp_london.json b/cmd/evm/testdata/19/exp_london.json index a06bc8ca69..9e9a17da90 100644 --- a/cmd/evm/testdata/19/exp_london.json +++ b/cmd/evm/testdata/19/exp_london.json @@ -7,6 +7,7 @@ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "currentDifficulty": "0x2000080000000", "receipts": [], - "gasUsed": "0x0" + "gasUsed": "0x0", + "currentBaseFee": "0x500" } } diff --git a/cmd/evm/testdata/24/exp.json b/cmd/evm/testdata/24/exp.json index 05d8c7a03b..d8cec59d6a 100644 --- a/cmd/evm/testdata/24/exp.json +++ b/cmd/evm/testdata/24/exp.json @@ -48,6 +48,7 @@ } ], "currentDifficulty": null, - "gasUsed": "0x10306" + "gasUsed": "0x10306", + "currentBaseFee": "0x500" } } diff --git a/cmd/evm/testdata/25/alloc.json b/cmd/evm/testdata/25/alloc.json new file mode 100644 index 0000000000..d66366718e --- /dev/null +++ b/cmd/evm/testdata/25/alloc.json @@ -0,0 +1,8 @@ +{ + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0x5ffd4878be161d74", + "code": "0x", + "nonce": "0xac", + "storage": {} + } +} diff --git a/cmd/evm/testdata/25/env.json b/cmd/evm/testdata/25/env.json new file mode 100644 index 0000000000..bb2c9e0d7d --- /dev/null +++ b/cmd/evm/testdata/25/env.json @@ -0,0 +1,11 @@ +{ + "currentCoinbase": "0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "currentDifficulty": null, + "currentRandom": "0xdeadc0de", + "currentGasLimit": "0x750a163df65e8a", + "parentBaseFee": "0x500", + "parentGasUsed": "0x0", + "parentGasLimit": "0x750a163df65e8a", + "currentNumber": "1", + "currentTimestamp": "1000" +} diff --git a/cmd/evm/testdata/25/exp.json b/cmd/evm/testdata/25/exp.json new file mode 100644 index 0000000000..a9c310a1e1 --- /dev/null +++ b/cmd/evm/testdata/25/exp.json @@ -0,0 +1,38 @@ +{ + "alloc": { + "0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192": { + "balance": "0x1" + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0x5ffd4878bc29ed73", + "nonce": "0xad" + }, + "0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0x854d00" + } + }, + "result": { + "stateRoot": "0x5139609e39f4d158a7d1ad1800908eb0349cea9b500a8273a6cf0a7e4392639b", + "txRoot": "0x572690baf4898c2972446e56ecf0aa2a027c08a863927d2dce34472f0c5496fe", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "receipts": [ + { + "root": "0x", + "status": "0x1", + "cumulativeGasUsed": "0x5208", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logs": null, + "transactionHash": "0x92ea4a28224d033afb20e0cc2b290d4c7c2d61f6a4800a680e4e19ac962ee941", + "contractAddress": "0x0000000000000000000000000000000000000000", + "gasUsed": "0x5208", + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "transactionIndex": "0x0" + } + ], + "currentDifficulty": null, + "gasUsed": "0x5208", + "currentBaseFee": "0x460" + } +} diff --git a/cmd/evm/testdata/25/txs.json b/cmd/evm/testdata/25/txs.json new file mode 100644 index 0000000000..acb4035fd1 --- /dev/null +++ b/cmd/evm/testdata/25/txs.json @@ -0,0 +1,15 @@ +[ + { + "gas": "0x186a0", + "gasPrice": "0x600", + "hash": "0x0557bacce3375c98d806609b8d5043072f0b6a8bae45ae5a67a00d3a1a18d673", + "input": "0x", + "nonce": "0xac", + "to": "0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192", + "value": "0x1", + "v" : "0x0", + "r" : "0x0", + "s" : "0x0", + "secretKey" : "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8" + } +] diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go index 3c7053d902..e9a94f3627 100644 --- a/cmd/faucet/faucet.go +++ b/cmd/faucet/faucet.go @@ -27,7 +27,6 @@ import ( "fmt" "html/template" "io" - "io/ioutil" "math" "math/big" "net/http" @@ -184,7 +183,7 @@ func parseChainFlags() (gs *genesisT.Genesis, bs string, netid uint64) { // allow overrides if *genesisFlag != "" { - blob, err := ioutil.ReadFile(*genesisFlag) + blob, err := os.ReadFile(*genesisFlag) if err != nil { log.Crit("Failed to read genesis block contents", "genesis", *genesisFlag, "err", err) } @@ -414,7 +413,7 @@ func main() { keystorePath := filepath.Join(faucetDirFromChainIndicators(chainID, genesisHash), "keys") ks := keystore.NewKeyStore(keystorePath, keystore.StandardScryptN, keystore.StandardScryptP) - if blob, err = ioutil.ReadFile(*accJSONFlag); err != nil { + if blob, err = os.ReadFile(*accJSONFlag); err != nil { log.Crit("Failed to read account key contents", "file", *accJSONFlag, "err", err) } acc, err := ks.Import(blob, pass, pass) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index 5f2577ae9d..9e980beac3 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -20,7 +20,6 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" "os" "runtime" "strconv" @@ -179,7 +178,7 @@ func initGenesis(ctx *cli.Context) error { } genesis := new(genesisT.Genesis) - bs, err := ioutil.ReadFile(genesisPath) + bs, err := os.ReadFile(genesisPath) if err != nil { utils.Fatalf("Failed to read genesis file: %v", err) } diff --git a/cmd/geth/consolecmd_cg_test.go b/cmd/geth/consolecmd_cg_test.go index 073634c813..1302250523 100644 --- a/cmd/geth/consolecmd_cg_test.go +++ b/cmd/geth/consolecmd_cg_test.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "math/rand" "os" "path/filepath" "regexp" @@ -48,14 +49,14 @@ func TestConsoleCmdNetworkIdentities(t *testing.T) { // or collisions with an existing geth service. p.flags = append(p.flags, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none") - t.Run(fmt.Sprintf("%d/%v/networkid", i, p.flags), + t.Run(fmt.Sprintf("%d/networkid", i), consoleCmdStdoutTest(p.flags, "admin.nodeInfo.protocols.eth.network", p.networkId)) - t.Run(fmt.Sprintf("%d/%v/chainid", i, p.flags), + t.Run(fmt.Sprintf("%d/chainid", i), consoleCmdStdoutTest(p.flags, "admin.nodeInfo.protocols.eth.config.chainId", p.chainId)) // The developer mode block has a dynamic genesis, depending on a parameterized address (coinbase) value. if p.genesisHash != "0x0" { - t.Run(fmt.Sprintf("%d/%v/genesis_hash", i, p.flags), + t.Run(fmt.Sprintf("%d/genesis_hash", i), consoleCmdStdoutTest(p.flags, "eth.getBlock(0, false).hash", strconv.Quote(p.genesisHash))) } } @@ -64,7 +65,9 @@ func TestConsoleCmdNetworkIdentities(t *testing.T) { func consoleCmdStdoutTest(flags []string, execCmd string, want interface{}) func(t *testing.T) { return func(t *testing.T) { flags = append(flags, "--ipcpath", filepath.Join(os.TempDir(), "geth.ipc"), "--exec", execCmd, "console") + t.Log("flags:", flags) geth := runGeth(t, flags...) + geth.KillTimeout = 20 * time.Second geth.Expect(fmt.Sprintf(`%v `, want)) geth.ExpectExit() @@ -85,8 +88,9 @@ func TestGethFailureToLaunch(t *testing.T) { expectErrorReStr: "(?ism)incorrect usage.*", }, } - for _, c := range cases { - t.Run(fmt.Sprintf("TestIncorrectUsage: %v", c.flags), func(t *testing.T) { + for i, c := range cases { + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + t.Log("flags:", c.flags) geth := runGeth(t, c.flags...) geth.ExpectRegexp(c.expectErrorReStr) geth.ExpectExit() @@ -97,11 +101,23 @@ func TestGethFailureToLaunch(t *testing.T) { } } +// randomStr is used in naming the geth tests' temporary datadir. +func randomStr(n int) string { + letterBytes := "abcdefghijklmnopqrstuvwxyz" + b := make([]byte, n) + for i := range b { + b[i] = letterBytes[rand.Int63()%int64(len(letterBytes))] + } + return string(b) +} + // TestGethStartupLogs tests that geth logs certain things (given some set of flags). // In these cases, geth is run with a console command to print its name (and tests that it does). func TestGethStartupLogs(t *testing.T) { // semiPersistentDatadir is used to house an adhoc datadir for co-dependent geth test cases. - semiPersistentDatadir := filepath.Join(os.TempDir(), fmt.Sprintf("geth-startup-logs-test-%d", time.Now().Unix())) + // WATCHOUT: For Unix-based operating systems, you're going to have problems if the IPC endpoint is + // longer than ___ characters. + semiPersistentDatadir := filepath.Join(os.TempDir(), fmt.Sprintf("geth-test-%x", randomStr(4))) defer os.RemoveAll(semiPersistentDatadir) type matching struct { @@ -164,8 +180,10 @@ func TestGethStartupLogs(t *testing.T) { }, } for i, c := range cases { - t.Run(fmt.Sprintf("TestGethStartupLogs/%d: %v", i, c.flags), func(t *testing.T) { - geth := runGeth(t, append(c.flags, "--exec", "admin.nodeInfo.name", "console")...) + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + caseFlags := append(c.flags, "--exec", "admin.nodeInfo.name", "console") + t.Log("flags:", caseFlags) + geth := runGeth(t, caseFlags...) geth.KillTimeout = 10 * time.Second geth.ExpectRegexp("(?ism).*CoreGeth.*") geth.ExpectExit() diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 1a32a0fa18..ff9abf713f 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2031,10 +2031,12 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { if ctx.IsSet(EWASMInterpreterFlag.Name) { cfg.EWASMInterpreter = ctx.String(EWASMInterpreterFlag.Name) + vm.InitEVMCEwasm(cfg.EWASMInterpreter) } if ctx.IsSet(EVMInterpreterFlag.Name) { cfg.EVMInterpreter = ctx.String(EVMInterpreterFlag.Name) + vm.InitEVMCEVM(cfg.EVMInterpreter) } if ctx.IsSet(RPCGlobalGasCapFlag.Name) { cfg.RPCGasCap = ctx.Uint64(RPCGlobalGasCapFlag.Name) diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go index 63e9ae6199..2327f7c990 100644 --- a/consensus/ethash/ethash.go +++ b/consensus/ethash/ethash.go @@ -463,7 +463,7 @@ func (d *dataset) generate(dir string, limit int, lock bool, test bool) { if !isLittleEndian() { endian = ".be" } - path := filepath.Join(dir, fmt.Sprintf("full-R%d-%x%s", algorithmRevision, seed[:8], endian)) + path := filepath.Join(dir, fmt.Sprintf("full-R%d-%d-%x%s", algorithmRevision, d.epoch, seed[:8], endian)) logger := log.New("epoch", d.epoch) // We're about to mmap the file, ensure that the mapping is cleaned up when the @@ -499,11 +499,34 @@ func (d *dataset) generate(dir string, limit int, lock bool, test bool) { d.dataset = make([]uint32, dsize/4) generateDataset(d.dataset, d.epoch, d.epochLength, cache) } - // Iterate over all previous instances and delete old ones - for ep := int(d.epoch) - limit; ep >= 0; ep-- { - seed := seedHash(uint64(ep), d.epochLength) - path := filepath.Join(dir, fmt.Sprintf("full-R%d-%x%s", algorithmRevision, seed[:8], endian)) - os.Remove(path) + + // Iterate over all full file instances, deleting any out of bounds (where epoch is below lower limit, or above upper limit). + matches, _ := filepath.Glob(filepath.Join(dir, fmt.Sprintf("full-R%d*", algorithmRevision))) + for _, file := range matches { + var ar int // algorithm revision + var e uint64 // epoch + var s string // seed + if _, err := fmt.Sscanf(filepath.Base(file), "full-R%d-%d-%s"+endian, &ar, &e, &s); err != nil { + // There is an unrecognized file in this directory. + // See if the name matches the expected pattern of the legacy naming scheme. + if _, err := fmt.Sscanf(filepath.Base(file), "full-R%d-%s"+endian, &ar, &s); err == nil { + // This file matches the previous generation naming pattern (sans epoch). + if err := os.Remove(file); err != nil { + logger.Error("Failed to remove legacy ethash full file", "file", file, "err", err) + } else { + logger.Warn("Deleted legacy ethash full file", "path", file) + } + } + // Else the file is unrecognized (unknown name format), leave it alone. + continue + } + if e <= d.epoch-uint64(limit) || e > d.epoch+1 { + if err := os.Remove(file); err == nil { + logger.Debug("Deleted ethash full file", "target.epoch", e, "file", file) + } else { + logger.Error("Failed to delete ethash full file", "target.epoch", e, "file", file, "err", err) + } + } } }) } diff --git a/contracts/checkpointoracle/combined.json b/contracts/checkpointoracle/combined.json new file mode 100644 index 0000000000..308ae63e67 --- /dev/null +++ b/contracts/checkpointoracle/combined.json @@ -0,0 +1 @@ +{"contracts":{"contract/oracle.sol:CheckpointOracle":{"abi":"[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_adminlist\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_sectionSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_processConfirms\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"index\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"checkpointHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"NewCheckpointVote\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"GetAllAdmin\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"GetLatestCheckpoint\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_recentNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_recentHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"_sectionIndex\",\"type\":\"uint64\"},{\"internalType\":\"uint8[]\",\"name\":\"v\",\"type\":\"uint8[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"r\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"s\",\"type\":\"bytes32[]\"}],\"name\":\"SetCheckpoint\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]","bin":"608060405234801561001057600080fd5b5060405161085a38038061085a8339818101604052608081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b90830190602082018581111561006857600080fd5b825186602082028301116401000000008211171561008557600080fd5b82525081516020918201928201910280838360005b838110156100b257818101518382015260200161009a565b50505050919091016040908152602083015190830151606090930151909450919250600090505b84518110156101855760016000808784815181106100f357fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550600185828151811061014057fe5b60209081029190910181015182546001808201855560009485529290932090920180546001600160a01b0319166001600160a01b0390931692909217909155016100d9565b50600592909255600655600755506106b8806101a26000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806345848dfc146100465780634d6a304c1461009e578063d459fc46146100cf575b600080fd5b61004e6102b0565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561008a578181015183820152602001610072565b505050509050019250505060405180910390f35b6100a661034f565b6040805167ffffffffffffffff9094168452602084019290925282820152519081900360600190f35b61029c600480360360e08110156100e557600080fd5b81359160208101359160408201359167ffffffffffffffff6060820135169181019060a08101608082013564010000000081111561012257600080fd5b82018360208201111561013457600080fd5b8035906020019184602083028401116401000000008311171561015657600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092959493602081019350359150506401000000008111156101a657600080fd5b8201836020820111156101b857600080fd5b803590602001918460208302840111640100000000831117156101da57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561022a57600080fd5b82018360208201111561023c57600080fd5b8035906020019184602083028401116401000000008311171561025e57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061036a945050505050565b604080519115158252519081900360200190f35b6060806001805490506040519080825280602002602001820160405280156102e2578160200160208202803883390190505b50905060005b60015481101561034957600181815481106102ff57fe5b9060005260206000200160009054906101000a90046001600160a01b031682828151811061032957fe5b6001600160a01b03909216602092830291909101909101526001016102e8565b50905090565b60025460045460035467ffffffffffffffff90921691909192565b3360009081526020819052604081205460ff1661038657600080fd5b8688401461039357600080fd5b82518451146103a157600080fd5b81518451146103af57600080fd5b6006546005548660010167ffffffffffffffff1602014310156103d457506000610677565b60025467ffffffffffffffff90811690861610156103f457506000610677565b60025467ffffffffffffffff8681169116148015610426575067ffffffffffffffff8516151580610426575060035415155b1561043357506000610677565b8561044057506000610677565b60408051601960f81b6020808301919091526000602183018190523060601b60228401526001600160c01b031960c08a901b166036840152603e8084018b905284518085039091018152605e909301909352815191012090805b86518110156106715760006001848984815181106104b457fe5b60200260200101518985815181106104c857fe5b60200260200101518986815181106104dc57fe5b602002602001015160405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561053b573d6000803e3d6000fd5b505060408051601f1901516001600160a01b03811660009081526020819052919091205490925060ff16905061057057600080fd5b826001600160a01b0316816001600160a01b03161161058e57600080fd5b8092508867ffffffffffffffff167fce51ffa16246bcaf0899f6504f473cd0114f430f566cef71ab7e03d3dde42a418b8a85815181106105ca57fe5b60200260200101518a86815181106105de57fe5b60200260200101518a87815181106105f257fe5b6020026020010151604051808581526020018460ff1660ff16815260200183815260200182815260200194505050505060405180910390a260075482600101106106685750505060048790555050436003556002805467ffffffffffffffff191667ffffffffffffffff86161790556001610677565b5060010161049a565b50600080fd5b97965050505050505056fea2646970667358221220dfd342cc8c4a864e30ffdf7f01340d7974f346a31969d46bceea09b75d46344764736f6c63430006000033","bin-runtime":"608060405234801561001057600080fd5b50600436106100415760003560e01c806345848dfc146100465780634d6a304c1461009e578063d459fc46146100cf575b600080fd5b61004e6102b0565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561008a578181015183820152602001610072565b505050509050019250505060405180910390f35b6100a661034f565b6040805167ffffffffffffffff9094168452602084019290925282820152519081900360600190f35b61029c600480360360e08110156100e557600080fd5b81359160208101359160408201359167ffffffffffffffff6060820135169181019060a08101608082013564010000000081111561012257600080fd5b82018360208201111561013457600080fd5b8035906020019184602083028401116401000000008311171561015657600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092959493602081019350359150506401000000008111156101a657600080fd5b8201836020820111156101b857600080fd5b803590602001918460208302840111640100000000831117156101da57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561022a57600080fd5b82018360208201111561023c57600080fd5b8035906020019184602083028401116401000000008311171561025e57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061036a945050505050565b604080519115158252519081900360200190f35b6060806001805490506040519080825280602002602001820160405280156102e2578160200160208202803883390190505b50905060005b60015481101561034957600181815481106102ff57fe5b9060005260206000200160009054906101000a90046001600160a01b031682828151811061032957fe5b6001600160a01b03909216602092830291909101909101526001016102e8565b50905090565b60025460045460035467ffffffffffffffff90921691909192565b3360009081526020819052604081205460ff1661038657600080fd5b8688401461039357600080fd5b82518451146103a157600080fd5b81518451146103af57600080fd5b6006546005548660010167ffffffffffffffff1602014310156103d457506000610677565b60025467ffffffffffffffff90811690861610156103f457506000610677565b60025467ffffffffffffffff8681169116148015610426575067ffffffffffffffff8516151580610426575060035415155b1561043357506000610677565b8561044057506000610677565b60408051601960f81b6020808301919091526000602183018190523060601b60228401526001600160c01b031960c08a901b166036840152603e8084018b905284518085039091018152605e909301909352815191012090805b86518110156106715760006001848984815181106104b457fe5b60200260200101518985815181106104c857fe5b60200260200101518986815181106104dc57fe5b602002602001015160405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561053b573d6000803e3d6000fd5b505060408051601f1901516001600160a01b03811660009081526020819052919091205490925060ff16905061057057600080fd5b826001600160a01b0316816001600160a01b03161161058e57600080fd5b8092508867ffffffffffffffff167fce51ffa16246bcaf0899f6504f473cd0114f430f566cef71ab7e03d3dde42a418b8a85815181106105ca57fe5b60200260200101518a86815181106105de57fe5b60200260200101518a87815181106105f257fe5b6020026020010151604051808581526020018460ff1660ff16815260200183815260200182815260200194505050505060405180910390a260075482600101106106685750505060048790555050436003556002805467ffffffffffffffff191667ffffffffffffffff86161790556001610677565b5060010161049a565b50600080fd5b97965050505050505056fea2646970667358221220dfd342cc8c4a864e30ffdf7f01340d7974f346a31969d46bceea09b75d46344764736f6c63430006000033","devdoc":"{\"author\":\"Gary Rong, Martin Swende \",\"details\":\"Implementation of the blockchain checkpoint registrar.\",\"methods\":{\"GetAllAdmin()\":{\"details\":\"Get all admin addresses\",\"returns\":{\"_0\":\"address list\"}},\"GetLatestCheckpoint()\":{\"details\":\"Get latest stable checkpoint information.\",\"returns\":{\"_0\":\"section index\",\"_1\":\"checkpoint hash\",\"_2\":\"block height associated with checkpoint\"}}},\"title\":\"CheckpointOracle\"}","hashes":{"GetAllAdmin()":"45848dfc","GetLatestCheckpoint()":"4d6a304c","SetCheckpoint(uint256,bytes32,bytes32,uint64,uint8[],bytes32[],bytes32[])":"d459fc46"},"metadata":"{\"compiler\":{\"version\":\"0.6.0+commit.26b70077\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_adminlist\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_sectionSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_processConfirms\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"index\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"checkpointHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"NewCheckpointVote\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"GetAllAdmin\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"GetLatestCheckpoint\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_recentNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_recentHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"_sectionIndex\",\"type\":\"uint64\"},{\"internalType\":\"uint8[]\",\"name\":\"v\",\"type\":\"uint8[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"r\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"s\",\"type\":\"bytes32[]\"}],\"name\":\"SetCheckpoint\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Gary Rong, Martin Swende \",\"details\":\"Implementation of the blockchain checkpoint registrar.\",\"methods\":{\"GetAllAdmin()\":{\"details\":\"Get all admin addresses\",\"returns\":{\"_0\":\"address list\"}},\"GetLatestCheckpoint()\":{\"details\":\"Get latest stable checkpoint information.\",\"returns\":{\"_0\":\"section index\",\"_1\":\"checkpoint hash\",\"_2\":\"block height associated with checkpoint\"}}},\"title\":\"CheckpointOracle\"},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"contract/oracle.sol\":\"CheckpointOracle\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contract/oracle.sol\":{\"keccak256\":\"0x738c2be3bcb2f7f06946ef3c467852e34a4e65120d2782d89d3fc9d88e6cb2eb\",\"urls\":[\"bzz-raw://f2798b17afac3e0d77555bf8ecae9c1c462d2e5317799dc0a83c7ef23de6a930\",\"dweb:/ipfs/QmYqFrDitrtbGuxu2a8BtPrCYp7gKQvbL9qwk9DUczh6Ct\"]}},\"version\":1}","srcmap":"211:5531:0:-:0;;;503:376;8:9:-1;5:2;;;30:1;27;20:12;5:2;503:376:0;;;;;;;;;;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;503:376:0;;;;;;;;;;;;;19:11:-1;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;219:3;213:10;331:9;325:2;311:12;307:21;289:16;285:44;282:59;261:11;247:12;244:29;233:116;230:2;;;362:1;359;352:12;230:2;373:25;;-1:-1;503:376:0;;421:4:-1;412:14;;;;503:376:0;;;;;412:14:-1;503:376:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;-1:-1;;;;503:376:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;503:376:0;;-1:-1:-1;625:6:0;;-1:-1:-1;620:141:0;641:10;:17;637:1;:21;620:141;;;703:4;679:6;:21;686:10;697:1;686:13;;;;;;;;;;;;;;-1:-1:-1;;;;;679:21:0;-1:-1:-1;;;;;679:21:0;;;;;;;;;;;;;:28;;;;;;;;;;;;;;;;;;721:9;736:10;747:1;736:13;;;;;;;;;;;;;;;;;;;27:10:-1;;39:1;23:18;;;45:23;;-1:-1;721:29:0;;;;;;;;;;;;-1:-1:-1;;;;;;721:29:0;-1:-1:-1;;;;;721:29:0;;;;;;;;;;660:3;620:141;;;-1:-1:-1;770:11:0;:26;;;;806:15;:34;850:9;:22;-1:-1:-1;211:5531:0;;;;;;","srcmap-runtime":"211:5531:0:-:0;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;211:5531:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4430:267;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;4430:267:0;;;;;;;;;;;;;;;;;1070:138;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1605:2739;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;1605:2739:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;1605:2739:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;1605:2739:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;1605:2739:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;1605:2739:0;;;;;;;;-1:-1:-1;1605:2739:0;;-1:-1:-1;;21:11;5:28;;2:2;;;46:1;43;36:12;2:2;1605:2739:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;1605:2739:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;1605:2739:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;1605:2739:0;;;;;;;;-1:-1:-1;1605:2739:0;;-1:-1:-1;;21:11;5:28;;2:2;;;46:1;43;36:12;2:2;1605:2739:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;1605:2739:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;1605:2739:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;1605:2739:0;;-1:-1:-1;1605:2739:0;;-1:-1:-1;;;;;1605:2739:0:i;:::-;;;;;;;;;;;;;;;;;;4430:267;4485:16;4517:20;4554:9;:16;;;;4540:31;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;4540:31:0;-1:-1:-1;4517:54:0;-1:-1:-1;4586:6:0;4581:90;4602:9;:16;4598:20;;4581:90;;;4648:9;4658:1;4648:12;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;4648:12:0;4639:3;4643:1;4639:6;;;;;;;;-1:-1:-1;;;;;4639:21:0;;;:6;;;;;;;;;;;:21;4620:3;;4581:90;;;-1:-1:-1;4687:3:0;-1:-1:-1;4430:267:0;:::o;1070:138::-;1174:12;;1188:4;;1194:6;;1174:12;;;;;1070:138;;;:::o;1605:2739::-;1932:10;1853:4;1925:18;;;;;;;;;;;;;1917:27;;;;;;2110:11;2092:13;2082:24;:39;2074:48;;;;;;2206:1;:8;2194:1;:8;:20;2186:29;;;;;;2245:1;:8;2233:1;:8;:20;2225:29;;;;;;2357:15;;2345:11;;2328:13;2342:1;2328:15;2327:29;;;:45;2312:12;:60;2308:103;;;-1:-1:-1;2395:5:0;2388:12;;2308:103;2481:12;;;;;;2465:28;;;;2461:71;;;-1:-1:-1;2516:5:0;2509:12;;2461:71;2605:12;;;2588:29;;;2605:12;;2588:29;:68;;;;-1:-1:-1;2622:18:0;;;;;;:33;;-1:-1:-1;2644:6:0;;:11;;2622:33;2584:111;;;-1:-1:-1;2679:5:0;2672:12;;2584:111;2753:11;2749:53;;-1:-1:-1;2786:5:0;2779:12;;2749:53;3325:65;;;-1:-1:-1;;;3325:65:0;;;;;;;;3294:18;3325:65;;;;;;3363:4;3325:65;;;;;;-1:-1:-1;;;;;;3325:65:0;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;3325:65:0;;;;;;;3315:76;;;;;;3294:18;3646:606;3671:1;:8;3665:3;:14;3646:606;;;3701:14;3718:45;3728:10;3740:1;3742:3;3740:6;;;;;;;;;;;;;;3748:1;3750:3;3748:6;;;;;;;;;;;;;;3756:1;3758:3;3756:6;;;;;;;;;;;;;;3718:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;3718:45:0;;;-1:-1:-1;;3718:45:0;;-1:-1:-1;;;;;3785:14:0;;:6;:14;;;3718:45;3785:14;;;;;;;;3718:45;;-1:-1:-1;3785:14:0;;;-1:-1:-1;3777:23:0;;;;;;3848:9;-1:-1:-1;;;;;3840:18:0;3830:6;-1:-1:-1;;;;;3822:15:0;:36;3814:45;;;;;;3885:6;3873:18;;3928:13;3910:63;;;3943:5;3950:1;3952:3;3950:6;;;;;;;;;;;;;;3958:1;3960:3;3958:6;;;;;;;;;;;;;;3966:1;3968:3;3966:6;;;;;;;;;;;;;;3910:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4073:9;;4064:3;4068:1;4064:5;:18;4060:182;;-1:-1:-1;;;4101:4:0;:12;;;-1:-1:-1;;4140:12:0;4131:6;:21;4170:12;:28;;-1:-1:-1;;4170:28:0;;;;;;;-1:-1:-1;4216:11:0;;4060:182;-1:-1:-1;3681:5:0;;3646:606;;;;4329:8;;;1605:2739;;;;;;;;;;:::o","userdoc":"{\"methods\":{}}"}},"sourceList":["contract/oracle.sol"],"version":"0.6.0+commit.26b70077.Linux.g++"} \ No newline at end of file diff --git a/contracts/checkpointoracle/contract/oracle.go b/contracts/checkpointoracle/contract/oracle.go index a4a308f5c5..5277750ec6 100644 --- a/contracts/checkpointoracle/contract/oracle.go +++ b/contracts/checkpointoracle/contract/oracle.go @@ -4,6 +4,7 @@ package contract import ( + "errors" "math/big" "strings" @@ -17,6 +18,7 @@ import ( // Reference imports to suppress errors if they are not otherwise used. var ( + _ = errors.New _ = big.NewInt _ = strings.NewReader _ = ethereum.NotFound @@ -26,27 +28,40 @@ var ( _ = event.NewSubscription ) +// CheckpointOracleMetaData contains all meta data concerning the CheckpointOracle contract. +var CheckpointOracleMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_adminlist\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_sectionSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_processConfirms\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"index\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"checkpointHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"NewCheckpointVote\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"GetAllAdmin\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"GetLatestCheckpoint\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_recentNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_recentHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"_sectionIndex\",\"type\":\"uint64\"},{\"internalType\":\"uint8[]\",\"name\":\"v\",\"type\":\"uint8[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"r\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"s\",\"type\":\"bytes32[]\"}],\"name\":\"SetCheckpoint\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "45848dfc": "GetAllAdmin()", + "4d6a304c": "GetLatestCheckpoint()", + "d459fc46": "SetCheckpoint(uint256,bytes32,bytes32,uint64,uint8[],bytes32[],bytes32[])", + }, + Bin: "0x608060405234801561001057600080fd5b5060405161085a38038061085a8339818101604052608081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b90830190602082018581111561006857600080fd5b825186602082028301116401000000008211171561008557600080fd5b82525081516020918201928201910280838360005b838110156100b257818101518382015260200161009a565b50505050919091016040908152602083015190830151606090930151909450919250600090505b84518110156101855760016000808784815181106100f357fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550600185828151811061014057fe5b60209081029190910181015182546001808201855560009485529290932090920180546001600160a01b0319166001600160a01b0390931692909217909155016100d9565b50600592909255600655600755506106b8806101a26000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806345848dfc146100465780634d6a304c1461009e578063d459fc46146100cf575b600080fd5b61004e6102b0565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561008a578181015183820152602001610072565b505050509050019250505060405180910390f35b6100a661034f565b6040805167ffffffffffffffff9094168452602084019290925282820152519081900360600190f35b61029c600480360360e08110156100e557600080fd5b81359160208101359160408201359167ffffffffffffffff6060820135169181019060a08101608082013564010000000081111561012257600080fd5b82018360208201111561013457600080fd5b8035906020019184602083028401116401000000008311171561015657600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092959493602081019350359150506401000000008111156101a657600080fd5b8201836020820111156101b857600080fd5b803590602001918460208302840111640100000000831117156101da57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561022a57600080fd5b82018360208201111561023c57600080fd5b8035906020019184602083028401116401000000008311171561025e57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061036a945050505050565b604080519115158252519081900360200190f35b6060806001805490506040519080825280602002602001820160405280156102e2578160200160208202803883390190505b50905060005b60015481101561034957600181815481106102ff57fe5b9060005260206000200160009054906101000a90046001600160a01b031682828151811061032957fe5b6001600160a01b03909216602092830291909101909101526001016102e8565b50905090565b60025460045460035467ffffffffffffffff90921691909192565b3360009081526020819052604081205460ff1661038657600080fd5b8688401461039357600080fd5b82518451146103a157600080fd5b81518451146103af57600080fd5b6006546005548660010167ffffffffffffffff1602014310156103d457506000610677565b60025467ffffffffffffffff90811690861610156103f457506000610677565b60025467ffffffffffffffff8681169116148015610426575067ffffffffffffffff8516151580610426575060035415155b1561043357506000610677565b8561044057506000610677565b60408051601960f81b6020808301919091526000602183018190523060601b60228401526001600160c01b031960c08a901b166036840152603e8084018b905284518085039091018152605e909301909352815191012090805b86518110156106715760006001848984815181106104b457fe5b60200260200101518985815181106104c857fe5b60200260200101518986815181106104dc57fe5b602002602001015160405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561053b573d6000803e3d6000fd5b505060408051601f1901516001600160a01b03811660009081526020819052919091205490925060ff16905061057057600080fd5b826001600160a01b0316816001600160a01b03161161058e57600080fd5b8092508867ffffffffffffffff167fce51ffa16246bcaf0899f6504f473cd0114f430f566cef71ab7e03d3dde42a418b8a85815181106105ca57fe5b60200260200101518a86815181106105de57fe5b60200260200101518a87815181106105f257fe5b6020026020010151604051808581526020018460ff1660ff16815260200183815260200182815260200194505050505060405180910390a260075482600101106106685750505060048790555050436003556002805467ffffffffffffffff191667ffffffffffffffff86161790556001610677565b5060010161049a565b50600080fd5b97965050505050505056fea2646970667358221220dfd342cc8c4a864e30ffdf7f01340d7974f346a31969d46bceea09b75d46344764736f6c63430006000033", +} + // CheckpointOracleABI is the input ABI used to generate the binding from. -const CheckpointOracleABI = "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_adminlist\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_sectionSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_processConfirms\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"index\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"checkpointHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"NewCheckpointVote\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"GetAllAdmin\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"GetLatestCheckpoint\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_recentNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_recentHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"_sectionIndex\",\"type\":\"uint64\"},{\"internalType\":\"uint8[]\",\"name\":\"v\",\"type\":\"uint8[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"r\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"s\",\"type\":\"bytes32[]\"}],\"name\":\"SetCheckpoint\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" +// Deprecated: Use CheckpointOracleMetaData.ABI instead. +var CheckpointOracleABI = CheckpointOracleMetaData.ABI +// Deprecated: Use CheckpointOracleMetaData.Sigs instead. // CheckpointOracleFuncSigs maps the 4-byte function signature to its string representation. -var CheckpointOracleFuncSigs = map[string]string{ - "45848dfc": "GetAllAdmin()", - "4d6a304c": "GetLatestCheckpoint()", - "d459fc46": "SetCheckpoint(uint256,bytes32,bytes32,uint64,uint8[],bytes32[],bytes32[])", -} +var CheckpointOracleFuncSigs = CheckpointOracleMetaData.Sigs // CheckpointOracleBin is the compiled bytecode used for deploying new contracts. -var CheckpointOracleBin = "0x608060405234801561001057600080fd5b506040516108703803806108708339818101604052608081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b90830190602082018581111561006857600080fd5b825186602082028301116401000000008211171561008557600080fd5b82525081516020918201928201910280838360005b838110156100b257818101518382015260200161009a565b50505050919091016040908152602083015190830151606090930151909450919250600090505b84518110156101855760016000808784815181106100f357fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550600185828151811061014057fe5b60209081029190910181015182546001808201855560009485529290932090920180546001600160a01b0319166001600160a01b0390931692909217909155016100d9565b50600592909255600655600755506106ce806101a26000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806345848dfc146100465780634d6a304c1461009e578063d459fc46146100cf575b600080fd5b61004e6102b0565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561008a578181015183820152602001610072565b505050509050019250505060405180910390f35b6100a6610365565b6040805167ffffffffffffffff9094168452602084019290925282820152519081900360600190f35b61029c600480360360e08110156100e557600080fd5b81359160208101359160408201359167ffffffffffffffff6060820135169181019060a08101608082013564010000000081111561012257600080fd5b82018360208201111561013457600080fd5b8035906020019184602083028401116401000000008311171561015657600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092959493602081019350359150506401000000008111156101a657600080fd5b8201836020820111156101b857600080fd5b803590602001918460208302840111640100000000831117156101da57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561022a57600080fd5b82018360208201111561023c57600080fd5b8035906020019184602083028401116401000000008311171561025e57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610380945050505050565b604080519115158252519081900360200190f35b600154606090819067ffffffffffffffff811180156102ce57600080fd5b506040519080825280602002602001820160405280156102f8578160200160208202803683370190505b50905060005b60015481101561035f576001818154811061031557fe5b9060005260206000200160009054906101000a90046001600160a01b031682828151811061033f57fe5b6001600160a01b03909216602092830291909101909101526001016102fe565b50905090565b60025460045460035467ffffffffffffffff90921691909192565b3360009081526020819052604081205460ff1661039c57600080fd5b868840146103a957600080fd5b82518451146103b757600080fd5b81518451146103c557600080fd5b6006546005548660010167ffffffffffffffff1602014310156103ea5750600061068d565b60025467ffffffffffffffff908116908616101561040a5750600061068d565b60025467ffffffffffffffff868116911614801561043c575067ffffffffffffffff851615158061043c575060035415155b156104495750600061068d565b856104565750600061068d565b60408051601960f81b6020808301919091526000602183018190523060601b60228401526001600160c01b031960c08a901b166036840152603e8084018b905284518085039091018152605e909301909352815191012090805b86518110156106875760006001848984815181106104ca57fe5b60200260200101518985815181106104de57fe5b60200260200101518986815181106104f257fe5b602002602001015160405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015610551573d6000803e3d6000fd5b505060408051601f1901516001600160a01b03811660009081526020819052919091205490925060ff16905061058657600080fd5b826001600160a01b0316816001600160a01b0316116105a457600080fd5b8092508867ffffffffffffffff167fce51ffa16246bcaf0899f6504f473cd0114f430f566cef71ab7e03d3dde42a418b8a85815181106105e057fe5b60200260200101518a86815181106105f457fe5b60200260200101518a878151811061060857fe5b6020026020010151604051808581526020018460ff1660ff16815260200183815260200182815260200194505050505060405180910390a2600754826001011061067e5750505060048790555050436003556002805467ffffffffffffffff191667ffffffffffffffff8616179055600161068d565b506001016104b0565b50600080fd5b97965050505050505056fea26469706673582212202ddf9eda76bf59c0fc65584c0b22d84ecef2c703765de60439596d6ac34c2b7264736f6c634300060b0033" +// Deprecated: Use CheckpointOracleMetaData.Bin instead. +var CheckpointOracleBin = CheckpointOracleMetaData.Bin // DeployCheckpointOracle deploys a new Ethereum contract, binding an instance of CheckpointOracle to it. func DeployCheckpointOracle(auth *bind.TransactOpts, backend bind.ContractBackend, _adminlist []common.Address, _sectionSize *big.Int, _processConfirms *big.Int, _threshold *big.Int) (common.Address, *types.Transaction, *CheckpointOracle, error) { - parsed, err := abi.JSON(strings.NewReader(CheckpointOracleABI)) + parsed, err := CheckpointOracleMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } - address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(CheckpointOracleBin), backend, _adminlist, _sectionSize, _processConfirms, _threshold) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(CheckpointOracleBin), backend, _adminlist, _sectionSize, _processConfirms, _threshold) if err != nil { return common.Address{}, nil, nil, err } @@ -424,5 +439,6 @@ func (_CheckpointOracle *CheckpointOracleFilterer) ParseNewCheckpointVote(log ty if err := _CheckpointOracle.contract.UnpackLog(event, "NewCheckpointVote", log); err != nil { return nil, err } + event.Raw = log return event, nil } diff --git a/core/genesis.go b/core/genesis.go index 6ec35eecfe..3dcbcfc9fb 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -36,9 +36,6 @@ import ( "github.com/ethereum/go-ethereum/trie" ) -//go:generate go run github.com/fjl/gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go -//go:generate go run github.com/fjl/gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go - // SetupGenesisBlock wraps SetupGenesisBlockWithOverride, always using a nil value for the override. func SetupGenesisBlock(db ethdb.Database, genesis *genesisT.Genesis) (ctypes.ChainConfigurator, common.Hash, error) { return SetupGenesisBlockWithOverride(db, genesis, nil, nil) diff --git a/core/state/statedb.go b/core/state/statedb.go index 6c14b98b89..ec6e357484 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -664,6 +664,7 @@ func (s *StateDB) Copy() *StateDB { // and in the Finalise-method, there is a case where an object is in the journal but not // in the stateObjects: OOG after touch on ripeMD prior to Byzantium. Thus, we need to check for // nil + // meowsbits-ripemd if object, exist := s.stateObjects[addr]; exist { // Even though the original object is dirty, we are not copying the journal, // so we need to make sure that anyside effect the journal would have caused @@ -785,6 +786,7 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) { // it will persist in the journal even though the journal is reverted. In this special circumstance, // it may exist in `s.journal.dirties` but not in `s.stateObjects`. // Thus, we can safely ignore it here + // meowsbits-ripemd continue } if obj.suicided || (deleteEmptyObjects && obj.empty()) { diff --git a/core/vm/evm.go b/core/vm/evm.go index c716f4d161..ed8a8e20ed 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -277,7 +277,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas gas = 0 } // TODO: consider clearing up unused snapshots: - //} else { + // } else { // evm.StateDB.DiscardSnapshot(snapshot) } return ret, gas, err diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index 4896204d51..e814e59bef 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -21,6 +21,7 @@ func (c Config) MarshalTOML() (interface{}, error) { type Config struct { Genesis *genesisT.Genesis `toml:",omitempty"` NetworkId uint64 + ProtocolVersions []uint SyncMode downloader.SyncMode EthDiscoveryURLs []string SnapDiscoveryURLs []string @@ -42,6 +43,7 @@ func (c Config) MarshalTOML() (interface{}, error) { DatabaseHandles int `toml:"-"` DatabaseCache int DatabaseFreezer string + DatabaseFreezerRemote string TrieCleanCache int TrieCleanCacheJournal string `toml:",omitempty"` TrieCleanCacheRejournal time.Duration `toml:",omitempty"` @@ -58,17 +60,21 @@ func (c Config) MarshalTOML() (interface{}, error) { DocRoot string `toml:"-"` EWASMInterpreter string EVMInterpreter string - RPCGasCap uint64 `toml:",omitempty"` + RPCGasCap uint64 RPCEVMTimeout time.Duration RPCTxFeeCap float64 Checkpoint *ctypes.TrustedCheckpoint `toml:",omitempty"` CheckpointOracle *ctypes.CheckpointOracleConfig `toml:",omitempty"` - OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"` - OverrideTerminalTotalDifficultyPassed *bool `toml:",omitempty"` + ECBP1100 *big.Int + ECBP1100NoDisable *bool `toml:",omitempty"` + OverrideMystique *big.Int `toml:",omitempty"` + OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"` + OverrideTerminalTotalDifficultyPassed *bool `toml:",omitempty"` } var enc Config enc.Genesis = c.Genesis enc.NetworkId = c.NetworkId + enc.ProtocolVersions = c.ProtocolVersions enc.SyncMode = c.SyncMode enc.EthDiscoveryURLs = c.EthDiscoveryURLs enc.SnapDiscoveryURLs = c.SnapDiscoveryURLs @@ -90,6 +96,7 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.DatabaseHandles = c.DatabaseHandles enc.DatabaseCache = c.DatabaseCache enc.DatabaseFreezer = c.DatabaseFreezer + enc.DatabaseFreezerRemote = c.DatabaseFreezerRemote enc.TrieCleanCache = c.TrieCleanCache enc.TrieCleanCacheJournal = c.TrieCleanCacheJournal enc.TrieCleanCacheRejournal = c.TrieCleanCacheRejournal @@ -111,6 +118,9 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.RPCTxFeeCap = c.RPCTxFeeCap enc.Checkpoint = c.Checkpoint enc.CheckpointOracle = c.CheckpointOracle + enc.ECBP1100 = c.ECBP1100 + enc.ECBP1100NoDisable = c.ECBP1100NoDisable + enc.OverrideMystique = c.OverrideMystique enc.OverrideTerminalTotalDifficulty = c.OverrideTerminalTotalDifficulty enc.OverrideTerminalTotalDifficultyPassed = c.OverrideTerminalTotalDifficultyPassed return &enc, nil @@ -121,6 +131,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { type Config struct { Genesis *genesisT.Genesis `toml:",omitempty"` NetworkId *uint64 + ProtocolVersions []uint SyncMode *downloader.SyncMode EthDiscoveryURLs []string SnapDiscoveryURLs []string @@ -142,6 +153,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { DatabaseHandles *int `toml:"-"` DatabaseCache *int DatabaseFreezer *string + DatabaseFreezerRemote *string TrieCleanCache *int TrieCleanCacheJournal *string `toml:",omitempty"` TrieCleanCacheRejournal *time.Duration `toml:",omitempty"` @@ -158,13 +170,16 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { DocRoot *string `toml:"-"` EWASMInterpreter *string EVMInterpreter *string - RPCGasCap *uint64 `toml:",omitempty"` + RPCGasCap *uint64 RPCEVMTimeout *time.Duration RPCTxFeeCap *float64 Checkpoint *ctypes.TrustedCheckpoint `toml:",omitempty"` CheckpointOracle *ctypes.CheckpointOracleConfig `toml:",omitempty"` - OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"` - OverrideTerminalTotalDifficultyPassed *bool `toml:",omitempty"` + ECBP1100 *big.Int + ECBP1100NoDisable *bool `toml:",omitempty"` + OverrideMystique *big.Int `toml:",omitempty"` + OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"` + OverrideTerminalTotalDifficultyPassed *bool `toml:",omitempty"` } var dec Config if err := unmarshal(&dec); err != nil { @@ -176,6 +191,9 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.NetworkId != nil { c.NetworkId = *dec.NetworkId } + if dec.ProtocolVersions != nil { + c.ProtocolVersions = dec.ProtocolVersions + } if dec.SyncMode != nil { c.SyncMode = *dec.SyncMode } @@ -239,6 +257,9 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.DatabaseFreezer != nil { c.DatabaseFreezer = *dec.DatabaseFreezer } + if dec.DatabaseFreezerRemote != nil { + c.DatabaseFreezerRemote = *dec.DatabaseFreezerRemote + } if dec.TrieCleanCache != nil { c.TrieCleanCache = *dec.TrieCleanCache } @@ -302,6 +323,15 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.CheckpointOracle != nil { c.CheckpointOracle = dec.CheckpointOracle } + if dec.ECBP1100 != nil { + c.ECBP1100 = dec.ECBP1100 + } + if dec.ECBP1100NoDisable != nil { + c.ECBP1100NoDisable = dec.ECBP1100NoDisable + } + if dec.OverrideMystique != nil { + c.OverrideMystique = dec.OverrideMystique + } if dec.OverrideTerminalTotalDifficulty != nil { c.OverrideTerminalTotalDifficulty = dec.OverrideTerminalTotalDifficulty } diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 0a70c9ece1..8d80647fc2 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -34,8 +34,8 @@ type Filter struct { addresses []common.Address topics [][]common.Hash - block common.Hash // Block hash if filtering a single block - begin, end int64 // Range interval if filtering multiple blocks + block *common.Hash // Block hash if filtering a single block + begin, end int64 // Range interval if filtering multiple blocks matcher *bloombits.Matcher } @@ -78,7 +78,7 @@ func (sys *FilterSystem) NewRangeFilter(begin, end int64, addresses []common.Add func (sys *FilterSystem) NewBlockFilter(block common.Hash, addresses []common.Address, topics [][]common.Hash) *Filter { // Create a generic filter and convert it into a block filter filter := newFilter(sys, addresses, topics) - filter.block = block + filter.block = &block return filter } @@ -96,8 +96,8 @@ func newFilter(sys *FilterSystem, addresses []common.Address, topics [][]common. // first block that contains matches, updating the start of the filter accordingly. func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { // If we're doing singleton block filtering, execute and return - if f.block != (common.Hash{}) { - header, err := f.sys.backend.HeaderByHash(ctx, f.block) + if f.block != nil { + header, err := f.sys.backend.HeaderByHash(ctx, *f.block) if err != nil { return nil, err } diff --git a/eth/handler.go b/eth/handler.go index a7d02ae2a8..7473942c9e 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -392,11 +392,16 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error { if h.checkpointHash != (common.Hash{}) { // Request the peer's checkpoint header for chain height/weight validation resCh := make(chan *eth.Response) - if _, err := peer.RequestHeadersByNumber(h.checkpointNumber, 1, 0, false, resCh); err != nil { + + req, err := peer.RequestHeadersByNumber(h.checkpointNumber, 1, 0, false, resCh) + if err != nil { return err } // Start a timer to disconnect if the peer doesn't reply in time go func() { + // Ensure the request gets cancelled in case of error/drop + defer req.Close() + timeout := time.NewTimer(syncChallengeTimeout) defer timeout.Stop() @@ -438,10 +443,15 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error { // If we have any explicit peer required block hashes, request them for number, hash := range h.requiredBlocks { resCh := make(chan *eth.Response) - if _, err := peer.RequestHeadersByNumber(number, 1, 0, false, resCh); err != nil { + + req, err := peer.RequestHeadersByNumber(number, 1, 0, false, resCh) + if err != nil { return err } - go func(number uint64, hash common.Hash) { + go func(number uint64, hash common.Hash, req *eth.Request) { + // Ensure the request gets cancelled in case of error/drop + defer req.Close() + timeout := time.NewTimer(syncChallengeTimeout) defer timeout.Stop() @@ -470,7 +480,7 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error { peer.Log().Warn("Required block challenge timed out, dropping", "addr", peer.RemoteAddr(), "type", peer.Name()) h.removePeer(peer.ID()) } - }(number, hash) + }(number, hash, req) } // Handle incoming messages until the connection is torn down return handler(peer) diff --git a/eth/protocols/snap/sync.go b/eth/protocols/snap/sync.go index deaa4456e0..eb8260bf7c 100644 --- a/eth/protocols/snap/sync.go +++ b/eth/protocols/snap/sync.go @@ -21,10 +21,12 @@ import ( "encoding/json" "errors" "fmt" + gomath "math" "math/big" "math/rand" "sort" "sync" + "sync/atomic" "time" "github.com/ethereum/go-ethereum/common" @@ -78,6 +80,29 @@ const ( // and waste round trip times. If it's too high, we're capping responses and // waste bandwidth. maxTrieRequestCount = maxRequestSize / 512 + + // trienodeHealRateMeasurementImpact is the impact a single measurement has on + // the local node's trienode processing capacity. A value closer to 0 reacts + // slower to sudden changes, but it is also more stable against temporary hiccups. + trienodeHealRateMeasurementImpact = 0.005 + + // minTrienodeHealThrottle is the minimum divisor for throttling trie node + // heal requests to avoid overloading the local node and exessively expanding + // the state trie bedth wise. + minTrienodeHealThrottle = 1 + + // maxTrienodeHealThrottle is the maximum divisor for throttling trie node + // heal requests to avoid overloading the local node and exessively expanding + // the state trie bedth wise. + maxTrienodeHealThrottle = maxTrieRequestCount + + // trienodeHealThrottleIncrease is the multiplier for the throttle when the + // rate of arriving data is higher than the rate of processing it. + trienodeHealThrottleIncrease = 1.33 + + // trienodeHealThrottleDecrease is the divisor for the throttle when the + // rate of arriving data is lower than the rate of processing it. + trienodeHealThrottleDecrease = 1.25 ) var ( @@ -431,6 +456,11 @@ type Syncer struct { trienodeHealReqs map[uint64]*trienodeHealRequest // Trie node requests currently running bytecodeHealReqs map[uint64]*bytecodeHealRequest // Bytecode requests currently running + trienodeHealRate float64 // Average heal rate for processing trie node data + trienodeHealPend uint64 // Number of trie nodes currently pending for processing + trienodeHealThrottle float64 // Divisor for throttling the amount of trienode heal data requested + trienodeHealThrottled time.Time // Timestamp the last time the throttle was updated + trienodeHealSynced uint64 // Number of state trie nodes downloaded trienodeHealBytes common.StorageSize // Number of state trie bytes persisted to disk trienodeHealDups uint64 // Number of state trie nodes already processed @@ -476,9 +506,10 @@ func NewSyncer(db ethdb.KeyValueStore) *Syncer { trienodeHealIdlers: make(map[string]struct{}), bytecodeHealIdlers: make(map[string]struct{}), - trienodeHealReqs: make(map[uint64]*trienodeHealRequest), - bytecodeHealReqs: make(map[uint64]*bytecodeHealRequest), - stateWriter: db.NewBatch(), + trienodeHealReqs: make(map[uint64]*trienodeHealRequest), + bytecodeHealReqs: make(map[uint64]*bytecodeHealRequest), + trienodeHealThrottle: maxTrienodeHealThrottle, // Tune downward instead of insta-filling with junk + stateWriter: db.NewBatch(), extProgress: new(SyncProgress), } @@ -1321,6 +1352,10 @@ func (s *Syncer) assignTrienodeHealTasks(success chan *trienodeHealResponse, fai if cap > maxTrieRequestCount { cap = maxTrieRequestCount } + cap = int(float64(cap) / s.trienodeHealThrottle) + if cap <= 0 { + cap = 1 + } var ( hashes = make([]common.Hash, 0, cap) paths = make([]string, 0, cap) @@ -2090,6 +2125,10 @@ func (s *Syncer) processStorageResponse(res *storageResponse) { // processTrienodeHealResponse integrates an already validated trienode response // into the healer tasks. func (s *Syncer) processTrienodeHealResponse(res *trienodeHealResponse) { + var ( + start = time.Now() + fills int + ) for i, hash := range res.hashes { node := res.nodes[i] @@ -2098,6 +2137,8 @@ func (s *Syncer) processTrienodeHealResponse(res *trienodeHealResponse) { res.task.trieTasks[res.paths[i]] = res.hashes[i] continue } + fills++ + // Push the trie node into the state syncer s.trienodeHealSynced++ s.trienodeHealBytes += common.StorageSize(len(node)) @@ -2121,6 +2162,50 @@ func (s *Syncer) processTrienodeHealResponse(res *trienodeHealResponse) { log.Crit("Failed to persist healing data", "err", err) } log.Debug("Persisted set of healing data", "type", "trienodes", "bytes", common.StorageSize(batch.ValueSize())) + + // Calculate the processing rate of one filled trie node + rate := float64(fills) / (float64(time.Since(start)) / float64(time.Second)) + + // Update the currently measured trienode queueing and processing throughput. + // + // The processing rate needs to be updated uniformly independent if we've + // processed 1x100 trie nodes or 100x1 to keep the rate consistent even in + // the face of varying network packets. As such, we cannot just measure the + // time it took to process N trie nodes and update once, we need one update + // per trie node. + // + // Naively, that would be: + // + // for i:=0; i time.Second { + // Periodically adjust the trie node throttler + if float64(pending) > 2*s.trienodeHealRate { + s.trienodeHealThrottle *= trienodeHealThrottleIncrease + } else { + s.trienodeHealThrottle /= trienodeHealThrottleDecrease + } + if s.trienodeHealThrottle > maxTrienodeHealThrottle { + s.trienodeHealThrottle = maxTrienodeHealThrottle + } else if s.trienodeHealThrottle < minTrienodeHealThrottle { + s.trienodeHealThrottle = minTrienodeHealThrottle + } + s.trienodeHealThrottled = time.Now() + + log.Debug("Updated trie node heal throttler", "rate", s.trienodeHealRate, "pending", pending, "throttle", s.trienodeHealThrottle) + } } // processBytecodeHealResponse integrates an already validated bytecode response @@ -2248,14 +2333,18 @@ func (s *Syncer) OnAccounts(peer SyncPeer, id uint64, hashes []common.Hash, acco // Whether or not the response is valid, we can mark the peer as idle and // notify the scheduler to assign a new task. If the response is invalid, // we'll drop the peer in a bit. + defer func() { + s.lock.Lock() + defer s.lock.Unlock() + if _, ok := s.peers[peer.ID()]; ok { + s.accountIdlers[peer.ID()] = struct{}{} + } + select { + case s.update <- struct{}{}: + default: + } + }() s.lock.Lock() - if _, ok := s.peers[peer.ID()]; ok { - s.accountIdlers[peer.ID()] = struct{}{} - } - select { - case s.update <- struct{}{}: - default: - } // Ensure the response is for a valid request req, ok := s.accountReqs[id] if !ok { @@ -2360,14 +2449,18 @@ func (s *Syncer) onByteCodes(peer SyncPeer, id uint64, bytecodes [][]byte) error // Whether or not the response is valid, we can mark the peer as idle and // notify the scheduler to assign a new task. If the response is invalid, // we'll drop the peer in a bit. + defer func() { + s.lock.Lock() + defer s.lock.Unlock() + if _, ok := s.peers[peer.ID()]; ok { + s.bytecodeIdlers[peer.ID()] = struct{}{} + } + select { + case s.update <- struct{}{}: + default: + } + }() s.lock.Lock() - if _, ok := s.peers[peer.ID()]; ok { - s.bytecodeIdlers[peer.ID()] = struct{}{} - } - select { - case s.update <- struct{}{}: - default: - } // Ensure the response is for a valid request req, ok := s.bytecodeReqs[id] if !ok { @@ -2469,14 +2562,18 @@ func (s *Syncer) OnStorage(peer SyncPeer, id uint64, hashes [][]common.Hash, slo // Whether or not the response is valid, we can mark the peer as idle and // notify the scheduler to assign a new task. If the response is invalid, // we'll drop the peer in a bit. + defer func() { + s.lock.Lock() + defer s.lock.Unlock() + if _, ok := s.peers[peer.ID()]; ok { + s.storageIdlers[peer.ID()] = struct{}{} + } + select { + case s.update <- struct{}{}: + default: + } + }() s.lock.Lock() - if _, ok := s.peers[peer.ID()]; ok { - s.storageIdlers[peer.ID()] = struct{}{} - } - select { - case s.update <- struct{}{}: - default: - } // Ensure the response is for a valid request req, ok := s.storageReqs[id] if !ok { @@ -2596,14 +2693,18 @@ func (s *Syncer) OnTrieNodes(peer SyncPeer, id uint64, trienodes [][]byte) error // Whether or not the response is valid, we can mark the peer as idle and // notify the scheduler to assign a new task. If the response is invalid, // we'll drop the peer in a bit. + defer func() { + s.lock.Lock() + defer s.lock.Unlock() + if _, ok := s.peers[peer.ID()]; ok { + s.trienodeHealIdlers[peer.ID()] = struct{}{} + } + select { + case s.update <- struct{}{}: + default: + } + }() s.lock.Lock() - if _, ok := s.peers[peer.ID()]; ok { - s.trienodeHealIdlers[peer.ID()] = struct{}{} - } - select { - case s.update <- struct{}{}: - default: - } // Ensure the response is for a valid request req, ok := s.trienodeHealReqs[id] if !ok { @@ -2639,10 +2740,12 @@ func (s *Syncer) OnTrieNodes(peer SyncPeer, id uint64, trienodes [][]byte) error // Cross reference the requested trienodes with the response to find gaps // that the serving node is missing - hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState) - hash := make([]byte, 32) - - nodes := make([][]byte, len(req.hashes)) + var ( + hasher = sha3.NewLegacyKeccak256().(crypto.KeccakState) + hash = make([]byte, 32) + nodes = make([][]byte, len(req.hashes)) + fills uint64 + ) for i, j := 0, 0; i < len(trienodes); i++ { // Find the next hash that we've been served, leaving misses with nils hasher.Reset() @@ -2654,16 +2757,22 @@ func (s *Syncer) OnTrieNodes(peer SyncPeer, id uint64, trienodes [][]byte) error } if j < len(req.hashes) { nodes[j] = trienodes[i] + fills++ j++ continue } // We've either ran out of hashes, or got unrequested data logger.Warn("Unexpected healing trienodes", "count", len(trienodes)-i) + // Signal this request as failed, and ready for rescheduling s.scheduleRevertTrienodeHealRequest(req) return errors.New("unexpected healing trienode") } // Response validated, send it to the scheduler for filling + atomic.AddUint64(&s.trienodeHealPend, fills) + defer func() { + atomic.AddUint64(&s.trienodeHealPend, ^(fills - 1)) + }() response := &trienodeHealResponse{ paths: req.paths, task: req.task, @@ -2691,14 +2800,18 @@ func (s *Syncer) onHealByteCodes(peer SyncPeer, id uint64, bytecodes [][]byte) e // Whether or not the response is valid, we can mark the peer as idle and // notify the scheduler to assign a new task. If the response is invalid, // we'll drop the peer in a bit. + defer func() { + s.lock.Lock() + defer s.lock.Unlock() + if _, ok := s.peers[peer.ID()]; ok { + s.bytecodeHealIdlers[peer.ID()] = struct{}{} + } + select { + case s.update <- struct{}{}: + default: + } + }() s.lock.Lock() - if _, ok := s.peers[peer.ID()]; ok { - s.bytecodeHealIdlers[peer.ID()] = struct{}{} - } - select { - case s.update <- struct{}{}: - default: - } // Ensure the response is for a valid request req, ok := s.bytecodeHealReqs[id] if !ok { diff --git a/eth/tracers/internal/tracetest/calltrace_parity_test.go b/eth/tracers/internal/tracetest/calltrace_parity_test.go index 3ae79db267..1f428791d2 100644 --- a/eth/tracers/internal/tracetest/calltrace_parity_test.go +++ b/eth/tracers/internal/tracetest/calltrace_parity_test.go @@ -3,8 +3,8 @@ package tracetest import ( "encoding/json" "fmt" - "io/ioutil" "math/big" + "os" "path/filepath" "reflect" "strings" @@ -51,7 +51,7 @@ type callTracerParityTest struct { func callTracerParityTestRunner(tracerName string, filename string, dirPath string, t testing.TB) error { // Call tracer test found, read if from disk - blob, err := ioutil.ReadFile(filepath.Join("testdata", dirPath, filename)) + blob, err := os.ReadFile(filepath.Join("testdata", dirPath, filename)) if err != nil { return fmt.Errorf("failed to read testcase: %v", err) } @@ -134,7 +134,7 @@ func TestCallTracerParityNative(t *testing.T) { } func testCallTracerParity(tracerName string, dirPath string, t *testing.T) { - files, err := ioutil.ReadDir(filepath.Join("testdata", dirPath)) + files, err := os.ReadDir(filepath.Join("testdata", dirPath)) if err != nil { t.Fatalf("failed to retrieve tracer test suite: %v", err) } @@ -208,7 +208,7 @@ type stateDiffTest struct { func stateDiffTracerTestRunner(tracerName string, filename string, dirPath string, t testing.TB) error { // Call tracer test found, read if from disk - blob, err := ioutil.ReadFile(filepath.Join("testdata", dirPath, filename)) + blob, err := os.ReadFile(filepath.Join("testdata", dirPath, filename)) if err != nil { return fmt.Errorf("failed to read testcase: %v", err) } @@ -300,7 +300,7 @@ func TestStateDiffTracerNative(t *testing.T) { // TestStateDiffTracer Iterates over all the input-output datasets in the state diff tracer test harness and // runs the JavaScript tracers against them. func testStateDiffTracer(tracerName string, dirPath string, t *testing.T) { - files, err := ioutil.ReadDir(filepath.Join("testdata", dirPath)) + files, err := os.ReadDir(filepath.Join("testdata", dirPath)) if err != nil { t.Fatalf("failed to retrieve tracer test suite: %v", err) } diff --git a/ethclient/docsgen_test.go b/ethclient/docsgen_test.go index ad3d8b029c..058a8888b9 100644 --- a/ethclient/docsgen_test.go +++ b/ethclient/docsgen_test.go @@ -3,7 +3,6 @@ package ethclient import ( "encoding/json" "fmt" - "io/ioutil" "os" "sort" "strings" @@ -49,7 +48,7 @@ func TestRPCDiscover_BuildStatic(t *testing.T) { if err != nil { t.Fatal(err) } - err = ioutil.WriteFile("../build/static/openrpc.json", data, os.ModePerm) + err = os.WriteFile("../build/static/openrpc.json", data, os.ModePerm) if err != nil { t.Fatal(err) } diff --git a/go.mod b/go.mod index 5522673696..06b336343b 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/docker/docker v1.6.2 github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf github.com/edsrzf/mmap-go v1.0.0 - github.com/etclabscore/go-openrpc-reflect v0.0.36 + github.com/etclabscore/go-openrpc-reflect v0.0.37 github.com/ethereum/evmc/v7 v7.5.0 github.com/fatih/color v1.7.0 github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c diff --git a/go.sum b/go.sum index 54223d2716..a1339c26ac 100644 --- a/go.sum +++ b/go.sum @@ -133,8 +133,8 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/etclabscore/go-jsonschema-walk v0.0.6 h1:DrNzoKWKd8f8XB5nFGBY00IcjakRE22OTI12k+2LkyY= github.com/etclabscore/go-jsonschema-walk v0.0.6/go.mod h1:VdfDY72AFAiUhy0ZXEaWSpveGjMT5JcDIm903NGqFwQ= -github.com/etclabscore/go-openrpc-reflect v0.0.36 h1:kSqNB2U8RVoW4si+4fsv13NGNkRAQ5j78zTUx1qiehk= -github.com/etclabscore/go-openrpc-reflect v0.0.36/go.mod h1:0404Ky3igAasAOpyj1eESjstTyneBAIk5PgJFbK4s5E= +github.com/etclabscore/go-openrpc-reflect v0.0.37 h1:IH0e7JqIvR9OhbbFWi/BHIkXrqbR3Zyia3RJ733eT6c= +github.com/etclabscore/go-openrpc-reflect v0.0.37/go.mod h1:0404Ky3igAasAOpyj1eESjstTyneBAIk5PgJFbK4s5E= github.com/ethereum/evmc/v7 v7.5.0 h1:vwKcs1DINXqvaymranmlpO64fysJJkirCCJ+kkaPaCs= github.com/ethereum/evmc/v7 v7.5.0/go.mod h1:q2Q0rCSUlIkngd+mZwfCzEUbvB0IIopH1+7hcs9QuDg= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= diff --git a/graphql/graphql.go b/graphql/graphql.go index 27ed185648..061fb3c2ee 100644 --- a/graphql/graphql.go +++ b/graphql/graphql.go @@ -22,6 +22,7 @@ import ( "errors" "fmt" "math/big" + "sort" "strconv" "github.com/ethereum/go-ethereum" @@ -478,13 +479,16 @@ func (t *Transaction) getLogs(ctx context.Context) (*[]*Log, error) { if err != nil { return nil, err } - ret := make([]*Log, 0, len(logs)) - for _, log := range logs { + var ret []*Log + // Select tx logs from all block logs + ix := sort.Search(len(logs), func(i int) bool { return uint64(logs[i].TxIndex) >= t.index }) + for ix < len(logs) && uint64(logs[ix].TxIndex) == t.index { ret = append(ret, &Log{ r: t.r, transaction: t, - log: log, + log: logs[ix], }) + ix++ } return &ret, nil } diff --git a/graphql/graphql_test.go b/graphql/graphql_test.go index 58b3c38227..71d871427e 100644 --- a/graphql/graphql_test.go +++ b/graphql/graphql_test.go @@ -17,6 +17,8 @@ package graphql import ( + "context" + "encoding/json" "fmt" "io" "math/big" @@ -53,15 +55,21 @@ func TestBuildSchema(t *testing.T) { } defer stack.Close() // Make sure the schema can be parsed and matched up to the object model. - if err := newHandler(stack, nil, nil, []string{}, []string{}); err != nil { + if _, err := newHandler(stack, nil, nil, []string{}, []string{}); err != nil { t.Errorf("Could not construct GraphQL handler: %v", err) } } // Tests that a graphQL request is successfully handled when graphql is enabled on the specified endpoint func TestGraphQLBlockSerialization(t *testing.T) { - stack := createNode(t, true, false) + stack := createNode(t) defer stack.Close() + genesis := &genesisT.Genesis{ + Config: params.AllEthashProtocolChanges, + GasLimit: 11500000, + Difficulty: big.NewInt(1048576), + } + newGQLService(t, stack, genesis, 10, func(i int, gen *core.BlockGen) {}) // start node if err := stack.Start(); err != nil { t.Fatalf("could not start node: %v", err) @@ -163,8 +171,55 @@ func TestGraphQLBlockSerialization(t *testing.T) { } func TestGraphQLBlockSerializationEIP2718(t *testing.T) { - stack := createNode(t, true, true) + // Account for signing txes + var ( + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + address = crypto.PubkeyToAddress(key.PublicKey) + funds = big.NewInt(1000000000000000) + dad = common.HexToAddress("0x0000000000000000000000000000000000000dad") + ) + stack := createNode(t) defer stack.Close() + genesis := &genesisT.Genesis{ + Config: params.AllEthashProtocolChanges, + GasLimit: 11500000, + Difficulty: big.NewInt(1048576), + Alloc: genesisT.GenesisAlloc{ + address: {Balance: funds}, + // The address 0xdad sloads 0x00 and 0x01 + dad: { + Code: []byte{byte(vm.PC), byte(vm.PC), byte(vm.SLOAD), byte(vm.SLOAD)}, + Nonce: 0, + Balance: big.NewInt(0), + }, + }, + BaseFee: big.NewInt(vars.InitialBaseFee), + } + signer := types.LatestSigner(genesis.Config) + newGQLService(t, stack, genesis, 1, func(i int, gen *core.BlockGen) { + gen.SetCoinbase(common.Address{1}) + tx, _ := types.SignNewTx(key, signer, &types.LegacyTx{ + Nonce: uint64(0), + To: &dad, + Value: big.NewInt(100), + Gas: 50000, + GasPrice: big.NewInt(vars.InitialBaseFee), + }) + gen.AddTx(tx) + tx, _ = types.SignNewTx(key, signer, &types.AccessListTx{ + ChainID: genesis.Config.GetChainID(), + Nonce: uint64(1), + To: &dad, + Gas: 30000, + GasPrice: big.NewInt(vars.InitialBaseFee), + Value: big.NewInt(50), + AccessList: types.AccessList{{ + Address: dad, + StorageKeys: []common.Hash{{0}}, + }}, + }) + gen.AddTx(tx) + }) // start node if err := stack.Start(); err != nil { t.Fatalf("could not start node: %v", err) @@ -200,7 +255,7 @@ func TestGraphQLBlockSerializationEIP2718(t *testing.T) { // Tests that a graphQL request is not handled successfully when graphql is not enabled on the specified endpoint func TestGraphQLHTTPOnSamePort_GQLRequest_Unsuccessful(t *testing.T) { - stack := createNode(t, false, false) + stack := createNode(t) defer stack.Close() if err := stack.Start(); err != nil { t.Fatalf("could not start node: %v", err) @@ -214,7 +269,59 @@ func TestGraphQLHTTPOnSamePort_GQLRequest_Unsuccessful(t *testing.T) { assert.Equal(t, http.StatusNotFound, resp.StatusCode) } -func createNode(t *testing.T, gqlEnabled bool, txEnabled bool) *node.Node { +func TestGraphQLTransactionLogs(t *testing.T) { + var ( + key, _ = crypto.GenerateKey() + addr = crypto.PubkeyToAddress(key.PublicKey) + dadStr = "0x0000000000000000000000000000000000000dad" + dad = common.HexToAddress(dadStr) + genesis = &genesisT.Genesis{ + Config: params.AllEthashProtocolChanges, + GasLimit: 11500000, + Difficulty: big.NewInt(1048576), + Alloc: genesisT.GenesisAlloc{ + addr: {Balance: big.NewInt(vars.Ether)}, + dad: { + // LOG0(0, 0), LOG0(0, 0), RETURN(0, 0) + Code: common.Hex2Bytes("60006000a060006000a060006000f3"), + Nonce: 0, + Balance: big.NewInt(0), + }, + }, + } + signer = types.LatestSigner(genesis.Config) + stack = createNode(t) + ) + defer stack.Close() + + handler := newGQLService(t, stack, genesis, 1, func(i int, gen *core.BlockGen) { + tx, _ := types.SignNewTx(key, signer, &types.LegacyTx{To: &dad, Gas: 100000, GasPrice: big.NewInt(vars.InitialBaseFee)}) + gen.AddTx(tx) + tx, _ = types.SignNewTx(key, signer, &types.LegacyTx{To: &dad, Nonce: 1, Gas: 100000, GasPrice: big.NewInt(vars.InitialBaseFee)}) + gen.AddTx(tx) + tx, _ = types.SignNewTx(key, signer, &types.LegacyTx{To: &dad, Nonce: 2, Gas: 100000, GasPrice: big.NewInt(vars.InitialBaseFee)}) + gen.AddTx(tx) + }) + // start node + if err := stack.Start(); err != nil { + t.Fatalf("could not start node: %v", err) + } + query := `{block { transactions { logs { account { address } } } } }` + res := handler.Schema.Exec(context.Background(), query, "", map[string]interface{}{}) + if res.Errors != nil { + t.Fatalf("graphql query failed: %v", res.Errors) + } + have, err := json.Marshal(res.Data) + if err != nil { + t.Fatalf("failed to encode graphql response: %s", err) + } + want := fmt.Sprintf(`{"block":{"transactions":[{"logs":[{"account":{"address":"%s"}},{"account":{"address":"%s"}}]},{"logs":[{"account":{"address":"%s"}},{"account":{"address":"%s"}}]},{"logs":[{"account":{"address":"%s"}},{"account":{"address":"%s"}}]}]}}`, dadStr, dadStr, dadStr, dadStr, dadStr, dadStr) + if string(have) != want { + t.Errorf("response unmatch. expected %s, got %s", want, have) + } +} + +func createNode(t *testing.T) *node.Node { stack, err := node.New(&node.Config{ HTTPHost: "127.0.0.1", HTTPPort: 0, @@ -224,83 +331,12 @@ func createNode(t *testing.T, gqlEnabled bool, txEnabled bool) *node.Node { if err != nil { t.Fatalf("could not create node: %v", err) } - if !gqlEnabled { - return stack - } - if !txEnabled { - createGQLService(t, stack) - } else { - createGQLServiceWithTransactions(t, stack) - } return stack } -func createGQLService(t *testing.T, stack *node.Node) { - // create backend - ethConf := ðconfig.Config{ - Genesis: &genesisT.Genesis{ - Config: params.AllEthashProtocolChanges, - GasLimit: 11500000, - Difficulty: big.NewInt(1048576), - }, - Ethash: ethash.Config{ - PowMode: ethash.ModeFake, - }, - NetworkId: 1337, - TrieCleanCache: 5, - TrieCleanCacheJournal: "triecache", - TrieCleanCacheRejournal: 60 * time.Minute, - TrieDirtyCache: 5, - TrieTimeout: 60 * time.Minute, - SnapshotCache: 5, - } - ethBackend, err := eth.New(stack, ethConf) - if err != nil { - t.Fatalf("could not create eth backend: %v", err) - } - // Create some blocks and import them - chain, _ := core.GenerateChain(params.AllEthashProtocolChanges, ethBackend.BlockChain().Genesis(), - ethash.NewFaker(), ethBackend.ChainDb(), 10, func(i int, gen *core.BlockGen) {}) - _, err = ethBackend.BlockChain().InsertChain(chain) - if err != nil { - t.Fatalf("could not create import blocks: %v", err) - } - // create gql service - filterSystem := filters.NewFilterSystem(ethBackend.APIBackend, filters.Config{}) - err = New(stack, ethBackend.APIBackend, filterSystem, []string{}, []string{}) - if err != nil { - t.Fatalf("could not create graphql service: %v", err) - } -} - -func createGQLServiceWithTransactions(t *testing.T, stack *node.Node) { - // create backend - key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - address := crypto.PubkeyToAddress(key.PublicKey) - funds := big.NewInt(1000000000000000) - dad := common.HexToAddress("0x0000000000000000000000000000000000000dad") - +func newGQLService(t *testing.T, stack *node.Node, gspec *genesisT.Genesis, genBlocks int, genfunc func(i int, gen *core.BlockGen)) *handler { ethConf := ðconfig.Config{ - Genesis: &genesisT.Genesis{ - Config: params.AllEthashProtocolChanges, - GasLimit: 11500000, - Difficulty: big.NewInt(1048576), - Alloc: genesisT.GenesisAlloc{ - address: {Balance: funds}, - // The address 0xdad sloads 0x00 and 0x01 - dad: { - Code: []byte{ - byte(vm.PC), - byte(vm.PC), - byte(vm.SLOAD), - byte(vm.SLOAD), - }, - Nonce: 0, - Balance: big.NewInt(0), - }, - }, - BaseFee: big.NewInt(vars.InitialBaseFee), - }, + Genesis: gspec, Ethash: ethash.Config{ PowMode: ethash.ModeFake, }, @@ -312,49 +348,22 @@ func createGQLServiceWithTransactions(t *testing.T, stack *node.Node) { TrieTimeout: 60 * time.Minute, SnapshotCache: 5, } - ethBackend, err := eth.New(stack, ethConf) if err != nil { t.Fatalf("could not create eth backend: %v", err) } - signer := types.LatestSigner(ethConf.Genesis.Config) - - legacyTx, _ := types.SignNewTx(key, signer, &types.LegacyTx{ - Nonce: uint64(0), - To: &dad, - Value: big.NewInt(100), - Gas: 50000, - GasPrice: big.NewInt(vars.InitialBaseFee), - }) - envelopTx, _ := types.SignNewTx(key, signer, &types.AccessListTx{ - ChainID: ethConf.Genesis.Config.GetChainID(), - Nonce: uint64(1), - To: &dad, - Gas: 30000, - GasPrice: big.NewInt(vars.InitialBaseFee), - Value: big.NewInt(50), - AccessList: types.AccessList{{ - Address: dad, - StorageKeys: []common.Hash{{0}}, - }}, - }) - // Create some blocks and import them chain, _ := core.GenerateChain(params.AllEthashProtocolChanges, ethBackend.BlockChain().Genesis(), - ethash.NewFaker(), ethBackend.ChainDb(), 1, func(i int, b *core.BlockGen) { - b.SetCoinbase(common.Address{1}) - b.AddTx(legacyTx) - b.AddTx(envelopTx) - }) - + ethash.NewFaker(), ethBackend.ChainDb(), genBlocks, genfunc) _, err = ethBackend.BlockChain().InsertChain(chain) if err != nil { t.Fatalf("could not create import blocks: %v", err) } - // create gql service + // Set up handler filterSystem := filters.NewFilterSystem(ethBackend.APIBackend, filters.Config{}) - err = New(stack, ethBackend.APIBackend, filterSystem, []string{}, []string{}) + handler, err := newHandler(stack, ethBackend.APIBackend, filterSystem, []string{}, []string{}) if err != nil { t.Fatalf("could not create graphql service: %v", err) } + return handler } diff --git a/graphql/service.go b/graphql/service.go index 019026bc7e..6f6e583359 100644 --- a/graphql/service.go +++ b/graphql/service.go @@ -57,17 +57,18 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // New constructs a new GraphQL service instance. func New(stack *node.Node, backend ethapi.Backend, filterSystem *filters.FilterSystem, cors, vhosts []string) error { - return newHandler(stack, backend, filterSystem, cors, vhosts) + _, err := newHandler(stack, backend, filterSystem, cors, vhosts) + return err } // newHandler returns a new `http.Handler` that will answer GraphQL queries. // It additionally exports an interactive query browser on the / endpoint. -func newHandler(stack *node.Node, backend ethapi.Backend, filterSystem *filters.FilterSystem, cors, vhosts []string) error { +func newHandler(stack *node.Node, backend ethapi.Backend, filterSystem *filters.FilterSystem, cors, vhosts []string) (*handler, error) { q := Resolver{backend, filterSystem} s, err := graphql.ParseSchema(schema, &q) if err != nil { - return err + return nil, err } h := handler{Schema: s} handler := node.NewHTTPHandlerStack(h, cors, vhosts, nil) @@ -76,5 +77,5 @@ func newHandler(stack *node.Node, backend ethapi.Backend, filterSystem *filters. stack.RegisterHandler("GraphQL", "/graphql", handler) stack.RegisterHandler("GraphQL", "/graphql/", handler) - return nil + return &h, nil } diff --git a/integration/configurator_test.go b/integration/configurator_test.go index 77c919b409..b85f25af11 100644 --- a/integration/configurator_test.go +++ b/integration/configurator_test.go @@ -18,8 +18,8 @@ package integration import ( "encoding/json" - "io/ioutil" "log" + "os" "path/filepath" "strings" "testing" @@ -176,7 +176,7 @@ func TestEquivalent_ReadParity(t *testing.T) { a := tests.Forks[k] b := &parity.ParityChainSpec{} - bs, err := ioutil.ReadFile(filepath.Join(parityP, v)) + bs, err := os.ReadFile(filepath.Join(parityP, v)) if err != nil { t.Fatal(err) } @@ -225,7 +225,7 @@ func TestParityGeneses(t *testing.T) { for _, tt := range testes { p := filepath.Join("..", "params", "parity.json.d", tt.filename) pspec := &parity.ParityChainSpec{} - b, err := ioutil.ReadFile(p) + b, err := os.ReadFile(p) if err != nil { t.Fatal(err) } diff --git a/node/node_test.go b/node/node_test.go index cec263fb00..d1f89b4c1f 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -22,7 +22,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "net/http" "os" @@ -328,7 +327,7 @@ func TestOpenRPCMetaSchemaSpecLatest(t *testing.T) { } localJSONFilePath := "./testdata/open-rpc-meta-schema-1.14.0.json" - localJSONFile, err := ioutil.ReadFile(localJSONFilePath) + localJSONFile, err := os.ReadFile(localJSONFilePath) if err != nil { t.Fatalf("failed to load local spec JSON file: %v", err) } diff --git a/params/alloc_test.go b/params/alloc_test.go new file mode 100644 index 0000000000..85abdb5c1c --- /dev/null +++ b/params/alloc_test.go @@ -0,0 +1,20 @@ +package params + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/params/types/genesisT" +) + +func ExampleMainnetAllocData() { + // Test that the mainnet alloc is parsable. + alloc := MainnetAllocData + ga := genesisT.DecodePreAlloc(alloc) + + fmt.Println(ga[common.Address{0x3}]) + fmt.Println(ga[common.HexToAddress("0x3000000000000000000000000000000000000003")]) + // Output: + // {[] map[] 0 []} + // {[] map[] 0 []} +} diff --git a/params/config.go b/params/config.go index b76cfab126..fe46cd0412 100644 --- a/params/config.go +++ b/params/config.go @@ -49,28 +49,29 @@ var ( // MainnetChainConfig is the chain parameters to run a node on the main network. MainnetChainConfig = &goethereum.ChainConfig{ - ChainID: big.NewInt(1), - SupportedProtocolVersions: vars.DefaultProtocolVersions, - HomesteadBlock: big.NewInt(1_150_000), - DAOForkBlock: big.NewInt(1_920_000), - DAOForkSupport: true, - EIP150Block: big.NewInt(2_463_000), - EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), - EIP155Block: big.NewInt(2_675_000), - EIP158Block: big.NewInt(2_675_000), - ByzantiumBlock: big.NewInt(4_370_000), - ConstantinopleBlock: big.NewInt(7_280_000), - PetersburgBlock: big.NewInt(7_280_000), - IstanbulBlock: big.NewInt(9_069_000), - MuirGlacierBlock: big.NewInt(9_200_000), - BerlinBlock: big.NewInt(12_244_000), - LondonBlock: big.NewInt(12_965_000), - ArrowGlacierBlock: big.NewInt(13_773_000), - GrayGlacierBlock: big.NewInt(15_050_000), - TerminalTotalDifficulty: MainnetTerminalTotalDifficulty, // 58_750_000_000_000_000_000_000 - TrustedCheckpoint: MainnetTrustedCheckpoint, - TrustedCheckpointOracle: RopstenCheckpointOracle, - Ethash: new(ctypes.EthashConfig), + ChainID: big.NewInt(1), + SupportedProtocolVersions: vars.DefaultProtocolVersions, + HomesteadBlock: big.NewInt(1_150_000), + DAOForkBlock: big.NewInt(1_920_000), + DAOForkSupport: true, + EIP150Block: big.NewInt(2_463_000), + EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), + EIP155Block: big.NewInt(2_675_000), + EIP158Block: big.NewInt(2_675_000), + ByzantiumBlock: big.NewInt(4_370_000), + ConstantinopleBlock: big.NewInt(7_280_000), + PetersburgBlock: big.NewInt(7_280_000), + IstanbulBlock: big.NewInt(9_069_000), + MuirGlacierBlock: big.NewInt(9_200_000), + BerlinBlock: big.NewInt(12_244_000), + LondonBlock: big.NewInt(12_965_000), + ArrowGlacierBlock: big.NewInt(13_773_000), + GrayGlacierBlock: big.NewInt(15_050_000), + TerminalTotalDifficulty: MainnetTerminalTotalDifficulty, // 58_750_000_000_000_000_000_000 + TrustedCheckpoint: MainnetTrustedCheckpoint, + TrustedCheckpointOracle: RopstenCheckpointOracle, + TerminalTotalDifficultyPassed: true, + Ethash: new(ctypes.EthashConfig), } // MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network. diff --git a/params/confp/generic/generic_test.go b/params/confp/generic/generic_test.go index 50f0560867..76204b8793 100644 --- a/params/confp/generic/generic_test.go +++ b/params/confp/generic/generic_test.go @@ -2,8 +2,8 @@ package generic import ( "encoding/json" - "io/ioutil" "math/big" + "os" "path/filepath" "reflect" "testing" @@ -39,7 +39,7 @@ func TestUnmarshalChainConfigurator(t *testing.T) { } for i, c := range cases { - b, err := ioutil.ReadFile(c.file) + b, err := os.ReadFile(c.file) if err != nil { t.Fatal(err) } @@ -250,19 +250,19 @@ func TestUnmarshalChainConfigurator2(t *testing.T) { wantType: reflect.TypeOf(&coregeth.CoreGethChainConfig{}), }, // FIXME - //{ + // { // versionid: "latest", // raw: func() string { // b, _ := json.MarshalIndent(params.ClassicChainConfig, "", " ") // return string(b) // }(), // wantType: reflect.TypeOf(&multigeth.CoreGethChainConfig{}), - //}, + // }, } head := uint64(10_000_000) - //outer: + // outer: for i := 0; i < len(cases); i++ { for j := 0; j < len(cases); j++ { if j >= i { diff --git a/params/confp/internal/convert_test.go b/params/confp/internal/convert_test.go index fff2acaf3c..2ba4b2f9ef 100644 --- a/params/confp/internal/convert_test.go +++ b/params/confp/internal/convert_test.go @@ -19,8 +19,8 @@ package convert_test import ( "encoding/json" "fmt" - "io/ioutil" "math/big" + "os" "path/filepath" "reflect" "testing" @@ -36,7 +36,7 @@ import ( ) func mustOpenF(t *testing.T, fabbrev string, into interface{}) { - b, err := ioutil.ReadFile(filepath.Join("..", "testdata", fmt.Sprintf("stureby_%s.json", fabbrev))) + b, err := os.ReadFile(filepath.Join("..", "testdata", fmt.Sprintf("stureby_%s.json", fabbrev))) if err != nil { t.Fatal(err) } diff --git a/params/confp/tconvert/aleth_test.go b/params/confp/tconvert/aleth_test.go index 8468049211..f73bdc0f02 100644 --- a/params/confp/tconvert/aleth_test.go +++ b/params/confp/tconvert/aleth_test.go @@ -18,7 +18,7 @@ package tconvert import ( "encoding/json" - "io/ioutil" + "os" "path/filepath" "testing" @@ -31,7 +31,7 @@ import ( // Tests the go-ethereum to Aleth chainspec conversion for the Stureby testnet. func TestAlethSturebyConverter(t *testing.T) { // Read GETH genesis type. - blob, err := ioutil.ReadFile(filepath.Join("..", "testdata", "stureby_geth.json")) + blob, err := os.ReadFile(filepath.Join("..", "testdata", "stureby_geth.json")) if err != nil { t.Fatalf("could not read file: %v", err) } @@ -47,7 +47,7 @@ func TestAlethSturebyConverter(t *testing.T) { } // Read the aleth JSON spec. - expBlob, err := ioutil.ReadFile(filepath.Join("..", "testdata", "stureby_aleth.json")) + expBlob, err := os.ReadFile(filepath.Join("..", "testdata", "stureby_aleth.json")) if err != nil { t.Fatalf("could not read file: %v", err) } diff --git a/params/types/coregeth/chain_config.go b/params/types/coregeth/chain_config.go index 71d9d49e48..07ae4f6079 100644 --- a/params/types/coregeth/chain_config.go +++ b/params/types/coregeth/chain_config.go @@ -215,7 +215,8 @@ type CoreGethChainConfig struct { EIP3541FBlock *big.Int `json:"eip3541FBlock,omitempty"` EIP3529FBlock *big.Int `json:"eip3529FBlock,omitempty"` - EIP5133FBlock *big.Int `json:"eip5133FBloc,omitempty"` + EIP5133FBlock *big.Int `json:"eip5133FBlock,omitempty"` + eip5133Inferred bool MergeNetsplitVBlock *big.Int `json:"mergeNetsplitVBlock,omitempty"` // Virtual fork after The Merge to use as a network splitter diff --git a/params/types/coregeth/chain_config_configurator.go b/params/types/coregeth/chain_config_configurator.go index 63b0b16553..2b07ca690e 100644 --- a/params/types/coregeth/chain_config_configurator.go +++ b/params/types/coregeth/chain_config_configurator.go @@ -1011,14 +1011,36 @@ func (c *CoreGethChainConfig) GetEthashEIP5133Transition() *uint64 { if c.GetConsensusEngineType() != ctypes.ConsensusEngineT_Ethash { return nil } - return bigNewU64(c.EIP5133FBlock) + if c.eip5133Inferred { + return bigNewU64(c.EIP5133FBlock) + } + + var diffN *uint64 + defer func() { + c.EIP5133FBlock = setBig(c.EIP5133FBlock, diffN) + c.eip5133Inferred = true + }() + + // Get block number (key) from map where EIP5133 criteria is met. + diffN = ctypes.MapMeetsSpecification(c.DifficultyBombDelaySchedule, nil, vars.EIP5133DifficultyBombDelay, nil) + return diffN } func (c *CoreGethChainConfig) SetEthashEIP5133Transition(n *uint64) error { if c.Ethash == nil { return ctypes.ErrUnsupportedConfigFatal } + c.EIP5133FBlock = setBig(c.EIP5133FBlock, n) + c.eip5133Inferred = true + + if n == nil { + return nil + } + + c.ensureExistingDifficultySchedule() + c.DifficultyBombDelaySchedule.SetValueTotalForHeight(n, vars.EIP5133DifficultyBombDelay) + return nil } diff --git a/params/types/genesisT/gen_genesis.go b/params/types/genesisT/gen_genesis.go index 5d592f151f..97f1ca4255 100644 --- a/params/types/genesisT/gen_genesis.go +++ b/params/types/genesisT/gen_genesis.go @@ -1,19 +1,3 @@ -// Copyright 2019 The multi-geth Authors -// This file is part of the multi-geth library. -// -// The multi-geth library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The multi-geth library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the multi-geth library. If not, see . - // Code generated by github.com/fjl/gencodec. DO NOT EDIT. package genesisT @@ -27,9 +11,9 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/params/confp/generic" - common0 "github.com/ethereum/go-ethereum/params/types/ctypes" - "github.com/ethereum/go-ethereum/params/types/goethereum" "github.com/ethereum/go-ethereum/params/types/coregeth" + "github.com/ethereum/go-ethereum/params/types/ctypes" + "github.com/ethereum/go-ethereum/params/types/goethereum" "github.com/ethereum/go-ethereum/params/types/multigeth" ) @@ -38,7 +22,7 @@ var _ = (*genesisSpecMarshaling)(nil) // MarshalJSON marshals as JSON. func (g Genesis) MarshalJSON() ([]byte, error) { type Genesis struct { - Config common0.ChainConfigurator `json:"config"` + Config ctypes.ChainConfigurator `json:"config"` Nonce math.HexOrDecimal64 `json:"nonce"` Timestamp math.HexOrDecimal64 `json:"timestamp"` ExtraData hexutil.Bytes `json:"extraData"` @@ -77,7 +61,7 @@ func (g Genesis) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (g *Genesis) UnmarshalJSON(input []byte) error { type Genesis struct { - Config common0.ChainConfigurator `json:"config"` + Config ctypes.ChainConfigurator `json:"config"` Nonce *math.HexOrDecimal64 `json:"nonce"` Timestamp *math.HexOrDecimal64 `json:"timestamp"` ExtraData *hexutil.Bytes `json:"extraData"` @@ -92,7 +76,6 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` } var dec Genesis - // We have to look at the raw input, decide what kind of configurator schema it's using, // then assign the decoder struct to use that schema type. conf, err := generic.UnmarshalChainConfigurator(input) @@ -114,7 +97,6 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { if err := json.Unmarshal(input, &dec); err != nil { return err } - if dec.Config != nil { g.Config = dec.Config } diff --git a/params/types/genesisT/gen_genesis_account.go b/params/types/genesisT/gen_genesis_account.go index 65e23b0fb6..77bba09883 100644 --- a/params/types/genesisT/gen_genesis_account.go +++ b/params/types/genesisT/gen_genesis_account.go @@ -1,19 +1,3 @@ -// Copyright 2019 The multi-geth Authors -// This file is part of the multi-geth library. -// -// The multi-geth library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The multi-geth library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the multi-geth library. If not, see . - // Code generated by github.com/fjl/gencodec. DO NOT EDIT. package genesisT diff --git a/params/types/genesisT/genesis.go b/params/types/genesisT/genesis.go index 3d3feac180..0a293d2969 100644 --- a/params/types/genesisT/genesis.go +++ b/params/types/genesisT/genesis.go @@ -32,6 +32,9 @@ import ( "github.com/ethereum/go-ethereum/rlp" ) +//go:generate go run github.com/fjl/gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go +//go:generate go run github.com/fjl/gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go + var ErrGenesisNoConfig = errors.New("genesis has no chain configuration") // Genesis specifies the header fields, state of a genesis block. It also defines hard diff --git a/params/types/parity/parity_configurator_test.go b/params/types/parity/parity_configurator_test.go index 801fbd60ca..962087c45a 100644 --- a/params/types/parity/parity_configurator_test.go +++ b/params/types/parity/parity_configurator_test.go @@ -18,7 +18,7 @@ package parity import ( "encoding/json" - "io/ioutil" + "os" "testing" "github.com/ethereum/go-ethereum/common/math" @@ -62,7 +62,7 @@ func TestParityChainSpec_GetSetUint64(t *testing.T) { func TestParityChainSpec_GetEIP2537(t *testing.T) { specFile := "../../parity.json.d/foundation.json" - b, err := ioutil.ReadFile(specFile) + b, err := os.ReadFile(specFile) if err != nil { t.Fatalf("read file: %v", err) } diff --git a/params/types/parity/parity_test.go b/params/types/parity/parity_test.go index f1a5b29f04..5c5ff39f04 100644 --- a/params/types/parity/parity_test.go +++ b/params/types/parity/parity_test.go @@ -18,7 +18,6 @@ package parity import ( "encoding/json" - "io/ioutil" "os" "path/filepath" "testing" @@ -98,7 +97,7 @@ func TestParityChainSpec_UnmarshalJSON(t *testing.T) { return nil } t.Run(info.Name(), func(t *testing.T) { - b, err := ioutil.ReadFile(path) + b, err := os.ReadFile(path) if err != nil { t.Fatal(err) } diff --git a/requirements-mkdocs.txt b/requirements-mkdocs.txt index d88161a02e..3d34e20ca6 100644 --- a/requirements-mkdocs.txt +++ b/requirements-mkdocs.txt @@ -5,7 +5,7 @@ gitdb==4.0.5 GitPython==3.1.12 htmlmin==0.1.12 Jinja2==3.0.2 -joblib==1.0.0 +joblib==1.2.0 jsmin==3.0.0 livereload==2.6.3 lunr==0.5.8 diff --git a/rpc/client.go b/rpc/client.go index d3ce029775..fcd31319a3 100644 --- a/rpc/client.go +++ b/rpc/client.go @@ -31,6 +31,7 @@ import ( ) var ( + ErrBadResult = errors.New("bad result in JSON-RPC response") ErrClientQuit = errors.New("client is closed") ErrNoResult = errors.New("no result in JSON-RPC response") ErrSubscriptionQueueOverflow = errors.New("subscription queue overflow") diff --git a/rpc/client_test.go b/rpc/client_test.go index 04c847d0d6..5ae549d865 100644 --- a/rpc/client_test.go +++ b/rpc/client_test.go @@ -19,6 +19,7 @@ package rpc import ( "context" "encoding/json" + "errors" "fmt" "math/rand" "net" @@ -144,6 +145,53 @@ func TestClientBatchRequest(t *testing.T) { } } +func TestClientBatchRequest_len(t *testing.T) { + b, err := json.Marshal([]jsonrpcMessage{ + {Version: "2.0", ID: json.RawMessage("1"), Method: "foo", Result: json.RawMessage(`"0x1"`)}, + {Version: "2.0", ID: json.RawMessage("2"), Method: "bar", Result: json.RawMessage(`"0x2"`)}, + }) + if err != nil { + t.Fatal("failed to encode jsonrpc message:", err) + } + s := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + _, err := rw.Write(b) + if err != nil { + t.Error("failed to write response:", err) + } + })) + t.Cleanup(s.Close) + + client, err := Dial(s.URL) + if err != nil { + t.Fatal("failed to dial test server:", err) + } + defer client.Close() + + t.Run("too-few", func(t *testing.T) { + batch := []BatchElem{ + {Method: "foo"}, + {Method: "bar"}, + {Method: "baz"}, + } + ctx, cancelFn := context.WithTimeout(context.Background(), time.Second) + defer cancelFn() + if err := client.BatchCallContext(ctx, batch); !errors.Is(err, ErrBadResult) { + t.Errorf("expected %q but got: %v", ErrBadResult, err) + } + }) + + t.Run("too-many", func(t *testing.T) { + batch := []BatchElem{ + {Method: "foo"}, + } + ctx, cancelFn := context.WithTimeout(context.Background(), time.Second) + defer cancelFn() + if err := client.BatchCallContext(ctx, batch); !errors.Is(err, ErrBadResult) { + t.Errorf("expected %q but got: %v", ErrBadResult, err) + } + }) +} + func TestClientNotify(t *testing.T) { server := newTestServer() defer server.Stop() diff --git a/rpc/http.go b/rpc/http.go index 858d808586..b82ea2707a 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -173,6 +173,9 @@ func (c *Client) sendBatchHTTP(ctx context.Context, op *requestOp, msgs []*jsonr if err := json.NewDecoder(respBody).Decode(&respmsgs); err != nil { return err } + if len(respmsgs) != len(msgs) { + return fmt.Errorf("batch has %d requests but response has %d: %w", len(msgs), len(respmsgs), ErrBadResult) + } for i := 0; i < len(respmsgs); i++ { op.resp <- &respmsgs[i] } diff --git a/tests/difficulty_mgen_test.go b/tests/difficulty_mgen_test.go index 8b9d23ef2e..1de0b6a746 100644 --- a/tests/difficulty_mgen_test.go +++ b/tests/difficulty_mgen_test.go @@ -19,7 +19,6 @@ package tests import ( "encoding/json" "fmt" - "io/ioutil" "math/big" "math/rand" "os" @@ -183,7 +182,7 @@ func writeDifficultyTestFileJSON(t *testing.T, filePath string, tests map[string if err != nil { t.Fatal(err) } - err = ioutil.WriteFile(filePath, b, os.ModePerm) + err = os.WriteFile(filePath, b, os.ModePerm) if err != nil { t.Fatal(err) } diff --git a/tests/difficulty_test.go b/tests/difficulty_test.go index cfb502a582..c0d68ce7c6 100644 --- a/tests/difficulty_test.go +++ b/tests/difficulty_test.go @@ -32,7 +32,7 @@ func TestDifficulty(t *testing.T) { } for _, dir := range []string{ - // difficultyTestDir, + difficultyTestDir, difficultyTestDirETC, } { dt.walk(t, dir, func(t *testing.T, name string, superTest map[string]json.RawMessage) { diff --git a/tests/difficulty_test_util.go b/tests/difficulty_test_util.go index 6882e75c4a..ee11301caa 100644 --- a/tests/difficulty_test_util.go +++ b/tests/difficulty_test_util.go @@ -103,6 +103,10 @@ var difficultyChainConfigurations = map[string]ctypes.ChainConfigurator{ Ethash: new(ctypes.EthashConfig), ByzantiumBlock: big.NewInt(0), }, + "GrayGlacier": &goethereum.ChainConfig{ + Ethash: new(ctypes.EthashConfig), + GrayGlacierBlock: big.NewInt(0), + }, "MainNetwork": mainnetChainConfig, "CustomMainNetwork": mainnetChainConfig, "Constantinople": &goethereum.ChainConfig{ diff --git a/tests/init.go b/tests/init.go index 65d634aa20..6ae5922862 100644 --- a/tests/init.go +++ b/tests/init.go @@ -63,7 +63,7 @@ var Forks = map[string]ctypes.ChainConfigurator{ "ETC_Atlantis": &coregeth.CoreGethChainConfig{ NetworkID: 1, Ethash: new(ctypes.EthashConfig), - ChainID: big.NewInt(1), + ChainID: big.NewInt(61), EIP2FBlock: big.NewInt(0), EIP7FBlock: big.NewInt(0), EIP150Block: big.NewInt(0), @@ -115,7 +115,7 @@ var Forks = map[string]ctypes.ChainConfigurator{ "ETC_Agharta": &coregeth.CoreGethChainConfig{ NetworkID: 1, Ethash: new(ctypes.EthashConfig), - ChainID: big.NewInt(1), + ChainID: big.NewInt(61), EIP2FBlock: big.NewInt(0), EIP7FBlock: big.NewInt(0), EIP150Block: big.NewInt(0), @@ -157,7 +157,7 @@ var Forks = map[string]ctypes.ChainConfigurator{ "ETC_Phoenix": &coregeth.CoreGethChainConfig{ NetworkID: 1, Ethash: new(ctypes.EthashConfig), - ChainID: big.NewInt(1), + ChainID: big.NewInt(61), EIP2FBlock: big.NewInt(0), EIP7FBlock: big.NewInt(0), EIP150Block: big.NewInt(0), @@ -342,26 +342,27 @@ var Forks = map[string]ctypes.ChainConfigurator{ GrayGlacierBlock: big.NewInt(0), }, "Merged": &goethereum.ChainConfig{ - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - ArrowGlacierBlock: big.NewInt(0), - MergeNetsplitBlock: big.NewInt(0), - TerminalTotalDifficulty: big.NewInt(0), + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + MergeNetsplitBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + TerminalTotalDifficultyPassed: true, }, "ETC_Magneto": &coregeth.CoreGethChainConfig{ NetworkID: 1, Ethash: new(ctypes.EthashConfig), - ChainID: big.NewInt(1), + ChainID: big.NewInt(61), EIP2FBlock: big.NewInt(0), EIP7FBlock: big.NewInt(0), EIP150Block: big.NewInt(0), @@ -406,7 +407,7 @@ var Forks = map[string]ctypes.ChainConfigurator{ "ETC_Mystique": &coregeth.CoreGethChainConfig{ NetworkID: 1, Ethash: new(ctypes.EthashConfig), - ChainID: big.NewInt(1), + ChainID: big.NewInt(61), EIP2FBlock: big.NewInt(0), EIP7FBlock: big.NewInt(0), EIP150Block: big.NewInt(0), diff --git a/tests/init_mgen_test.go b/tests/init_mgen_test.go index 2aa246c517..58e4e4b7d7 100644 --- a/tests/init_mgen_test.go +++ b/tests/init_mgen_test.go @@ -17,13 +17,9 @@ package tests import ( - "bufio" - "encoding/json" "fmt" "os" "path/filepath" - "reflect" - "strings" "testing" ) @@ -57,87 +53,3 @@ func (tm *testMatcher) walkFullName(t *testing.T, dir string, runTest interface{ t.Fatal(err) } } - -// walk invokes its runTest argument for all subtests in the given directory. -// -// runTest should be a function of type func(t *testing.T, name string, x ), -// where TestType is the type of the test contained in test files. -func (tm *testMatcher) walkScanNDJSON(t *testing.T, dir string, runTest interface{}) { - // Walk the directory. - dirinfo, err := os.Stat(dir) - if os.IsNotExist(err) || !dirinfo.IsDir() { - fmt.Fprintf(os.Stderr, "can't find test files in %s, did you clone the tests submodule?\n", dir) - t.Skip("missing test files") - } - err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - name := filepath.ToSlash(strings.TrimPrefix(path, dir+string(filepath.Separator))) - if info.IsDir() { - if _, skipload := tm.findSkip(name + "/"); skipload { - return filepath.SkipDir - } - return nil - } - if filepath.Ext(path) == ".ndjson" { - t.Run(name, func(t *testing.T) { tm.runTestFileNDJSON(t, path, name, runTest) }) - } - return nil - }) - if err != nil { - t.Fatal(err) - } -} - -func (tm *testMatcher) runTestFileNDJSON(t *testing.T, path, name string, runTest interface{}) { - if r, _ := tm.findSkip(name); r != "" { - t.Skip(r) - } - if tm.runonlylistpat != nil { - if !tm.runonlylistpat.MatchString(name) { - t.Skip("Skipped by whitelist") - } - } - t.Parallel() - - file, err := os.Open(path) - if err != nil { - t.Fatal(err) - } - defer file.Close() - - scanner := bufio.NewScanner(file) - - for scanner.Scan() { - m := makeVOfTestFunc(runTest) - ma := m.Addr().Interface() - err = json.Unmarshal(scanner.Bytes(), &ma) - if err != nil { - t.Fatal(err) - } - t.Run(name, func(t *testing.T) { - if r, _ := tm.findSkip(name); r != "" { - t.Skip(r) - } - runTestFuncNotMap(runTest, t, name, m) - }) - } -} - -func makeVOfTestFunc(f interface{}) reflect.Value { - stringT := reflect.TypeOf("") - testingT := reflect.TypeOf((*testing.T)(nil)) - ftyp := reflect.TypeOf(f) - if ftyp.Kind() != reflect.Func || ftyp.NumIn() != 3 || ftyp.NumOut() != 0 || ftyp.In(0) != testingT || ftyp.In(1) != stringT { - panic(fmt.Sprintf("bad test function type: want func(*testing.T, string, ), have %s", ftyp)) - } - testType := ftyp.In(2) - mp := reflect.New(testType) - return mp.Elem() -} - -func runTestFuncNotMap(runTest interface{}, t *testing.T, name string, m reflect.Value) { - reflect.ValueOf(runTest).Call([]reflect.Value{ - reflect.ValueOf(t), - reflect.ValueOf(name), - m, - }) -} diff --git a/tests/init_test.go b/tests/init_test.go index 6b160e6e98..c476a74030 100644 --- a/tests/init_test.go +++ b/tests/init_test.go @@ -32,7 +32,6 @@ import ( "testing" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/params/types/coregeth" "github.com/ethereum/go-ethereum/params/types/ctypes" ) @@ -192,18 +191,6 @@ func (tm *testMatcher) findSkip(name string) (reason string, skipload bool) { return "", false } -// findConfig returns the chain config matching defined patterns. -func (tm *testMatcher) findConfig(name string) (config ctypes.ChainConfigurator, configRegexKey string) { - // TODO(fjl): name can be derived from testing.T when min Go version is 1.8 - for _, m := range tm.configpat { - if m.p.MatchString(name) { - return m.config, m.p.String() - } - } - log.Println("using empty config", name) - return new(coregeth.CoreGethChainConfig), "" -} - // checkFailure checks whether a failure is expected. func (tm *testMatcher) checkFailure(t *testing.T, err error) error { failReason := "" diff --git a/tests/params.go b/tests/params.go index b438fe0484..772d4fdd0a 100644 --- a/tests/params.go +++ b/tests/params.go @@ -20,7 +20,6 @@ import ( "crypto/sha1" "encoding/json" "fmt" - "io/ioutil" "log" "os" "path/filepath" @@ -113,7 +112,7 @@ func readJSONFromFile(name string, value interface{}) (sha1sum []byte, err error } else { fi.Close() } - b, err := ioutil.ReadFile(name) + b, err := os.ReadFile(name) if err != nil { panic(fmt.Sprintf("%s err: %s\n%s", name, err, b)) } @@ -160,7 +159,7 @@ func writeDifficultyConfigFileParity(conf ctypes.ChainConfigurator, forkName str return "", [20]byte{}, err } - err = ioutil.WriteFile(filepath.Join("..", "params", "parity.json.d", specFilepath), b, os.ModePerm) + err = os.WriteFile(filepath.Join("..", "params", "parity.json.d", specFilepath), b, os.ModePerm) if err != nil { return "", [20]byte{}, err } @@ -291,7 +290,7 @@ func init() { config = pspec b, _ := json.MarshalIndent(pspec, "", " ") writePath := filepath.Join(paritySpecsDir, v) - err := ioutil.WriteFile(writePath, b, os.ModePerm) + err := os.WriteFile(writePath, b, os.ModePerm) if err != nil { panic(fmt.Sprintf("failed to write chainspec; wd: %s, config: %v/file: %v", wd, k, writePath)) } diff --git a/tests/state_mgen_test.go b/tests/state_mgen_test.go index 2562562e33..2ca1638f6a 100644 --- a/tests/state_mgen_test.go +++ b/tests/state_mgen_test.go @@ -21,7 +21,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "math/big" "os" "path/filepath" @@ -167,7 +166,7 @@ func (tm *testMatcherGen) testWriteTest(t *testing.T, name string, test *StateTe // Note that parallelism can cause greasy bugs around file during read/write which is why // we use a temporary file instead of immediately overwriting the canonical file in the first place; // for example, I saw regular encoding errors without this pattern. - tmpFile, err := ioutil.TempFile(os.TempDir(), "geth-state-test-generation") + tmpFile, err := os.CreateTemp(os.TempDir(), "geth-state-test-generation") if err != nil { t.Fatal(err) } @@ -215,7 +214,7 @@ func (tm *testMatcherGen) testWriteTest(t *testing.T, name string, test *StateTe configPathTarget := filepath.Join(targetDirCommon, "configs", fmt.Sprintf("%s_config.json", target)) // e.g. "testdata_generated/GeneralStateTests/ETC_Atlantis_config.json" os.MkdirAll(filepath.Dir(configPathTarget), os.ModePerm) if _, statErr := os.Stat(configPathTarget); os.IsNotExist(statErr) { - if err := ioutil.WriteFile(configPathTarget, b, os.ModePerm); err != nil { + if err := os.WriteFile(configPathTarget, b, os.ModePerm); err != nil { t.Fatal(err) } } @@ -456,7 +455,7 @@ func TestGenStateCoreGethConfigs(t *testing.T) { coregethSpecsDir, strcase.ToSnake(subtest.Fork)+"_test.json", ) - err = ioutil.WriteFile(filename, b, os.ModePerm) + err = os.WriteFile(filename, b, os.ModePerm) if err != nil { t.Fatal(err) } diff --git a/tests/state_test.go b/tests/state_test.go index 9b2657c453..d5ac501e05 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -58,6 +58,8 @@ func TestState(t *testing.T) { // Uses 1GB RAM per tested fork st.skipLoad(`^stStaticCall/static_Call1MB`) + st.skipLoad(`.*EOF1.*`) + if *testEWASM == "" { st.skipLoad(`^stEWASM`) } @@ -75,10 +77,11 @@ func TestState(t *testing.T) { if *testEVM != "" || *testEWASM != "" { // Berlin tests are not expected to pass for external EVMs, yet. // - st.skipFork("^Berlin$") // ETH + st.skipFork("Berlin") // ETH st.skipFork("Magneto") // ETC st.skipFork("London") // ETH st.skipFork("Mystique") // ETC + st.skipFork("Merged") // ETH } // The multigeth data type (like the Ethereum Foundation data type) doesn't support // the ETC_Mystique fork/feature configuration, which omits EIP1559 and the associated BASEFEE @@ -102,11 +105,11 @@ func TestState(t *testing.T) { // For Istanbul, older tests were moved into LegacyTests for _, dir := range []string{ stateTestDir, - // legacyStateTestDir, + legacyStateTestDir, benchmarksDir, stateTestDirETC, - // legacyTestDirETC, + legacyTestDirETC, } { st.walk(t, dir, func(t *testing.T, name string, test *StateTest) { for _, subtest := range test.Subtests(st.skipforkpat) { diff --git a/tests/state_test_util.go b/tests/state_test_util.go index e8824535c3..57175db1d8 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -318,6 +318,8 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh rnd := common.BigToHash(t.json.Env.Random) context.Random = &rnd context.Difficulty = big.NewInt(0) + } else { + context.Difficulty = t.json.Env.Difficulty } evm := vm.NewEVM(context, txContext, statedb, config, vmconfig) // Execute the message. diff --git a/tests/testdata-etc b/tests/testdata-etc index eee0383834..315779c508 160000 --- a/tests/testdata-etc +++ b/tests/testdata-etc @@ -1 +1 @@ -Subproject commit eee0383834a6e32ff17690d6c4763fffd04fcaaa +Subproject commit 315779c508f7fa385b57566cf610387f016c3477 diff --git a/trie/sync.go b/trie/sync.go index 303fcbfa22..862ce7e16e 100644 --- a/trie/sync.go +++ b/trie/sync.go @@ -19,6 +19,7 @@ package trie import ( "errors" "fmt" + "sync" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/prque" @@ -381,11 +382,11 @@ func (s *Sync) scheduleCodeRequest(req *codeRequest) { // retrieval scheduling. func (s *Sync) children(req *nodeRequest, object node) ([]*nodeRequest, error) { // Gather all the children of the node, irrelevant whether known or not - type child struct { + type childNode struct { path []byte node node } - var children []child + var children []childNode switch node := (object).(type) { case *shortNode: @@ -393,14 +394,14 @@ func (s *Sync) children(req *nodeRequest, object node) ([]*nodeRequest, error) { if hasTerm(key) { key = key[:len(key)-1] } - children = []child{{ + children = []childNode{{ node: node.Val, path: append(append([]byte(nil), req.path...), key...), }} case *fullNode: for i := 0; i < 17; i++ { if node.Children[i] != nil { - children = append(children, child{ + children = append(children, childNode{ node: node.Children[i], path: append(append([]byte(nil), req.path...), byte(i)), }) @@ -410,7 +411,10 @@ func (s *Sync) children(req *nodeRequest, object node) ([]*nodeRequest, error) { panic(fmt.Sprintf("unknown node: %+v", node)) } // Iterate over the children, and request all unknown ones - requests := make([]*nodeRequest, 0, len(children)) + var ( + missing = make(chan *nodeRequest, len(children)) + pending sync.WaitGroup + ) for _, child := range children { // Notify any external watcher of a new key/value node if req.callback != nil { @@ -433,19 +437,36 @@ func (s *Sync) children(req *nodeRequest, object node) ([]*nodeRequest, error) { if s.membatch.hasNode(child.path) { continue } - // If database says duplicate, then at least the trie node is present - // and we hold the assumption that it's NOT legacy contract code. - chash := common.BytesToHash(node) - if rawdb.HasTrieNode(s.database, chash) { - continue - } - // Locally unknown node, schedule for retrieval - requests = append(requests, &nodeRequest{ - path: child.path, - hash: chash, - parent: req, - callback: req.callback, - }) + // Check the presence of children concurrently + pending.Add(1) + go func(child childNode) { + defer pending.Done() + + // If database says duplicate, then at least the trie node is present + // and we hold the assumption that it's NOT legacy contract code. + chash := common.BytesToHash(node) + if rawdb.HasTrieNode(s.database, chash) { + return + } + // Locally unknown node, schedule for retrieval + missing <- &nodeRequest{ + path: child.path, + hash: chash, + parent: req, + callback: req.callback, + } + }(child) + } + } + pending.Wait() + + requests := make([]*nodeRequest, 0, len(children)) + for done := false; !done; { + select { + case miss := <-missing: + requests = append(requests, miss) + default: + done = true } } return requests, nil