Merge commit '12b4131ff' into po/par_exe

This commit is contained in:
Po 2025-08-04 05:04:32 +02:00
commit 86a72911a7
353 changed files with 18682 additions and 6727 deletions

View file

@ -0,0 +1,27 @@
on:
workflow_dispatch:
### Note we cannot use cron-triggered builds right now, Gitea seems to have
### a few bugs in that area. So this workflow is scheduled using an external
### triggering mechanism and workflow_dispatch.
#
# schedule:
# - cron: '0 15 * * *'
jobs:
azure-cleanup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.24
cache: false
- name: Run cleanup script
run: |
go run build/ci.go purge -store gethstore/builds -days 14
env:
AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }}

View file

@ -0,0 +1,46 @@
on:
push:
tags:
- "v*"
workflow_dispatch:
### Note we cannot use cron-triggered builds right now, Gitea seems to have
### a few bugs in that area. So this workflow is scheduled using an external
### triggering mechanism and workflow_dispatch.
#
# schedule:
# - cron: '0 16 * * *'
jobs:
ppa:
name: PPA Upload
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Show environment
run: |
env
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.24
cache: false
- name: Install deb toolchain
run: |
apt-get update
apt-get -yq --no-install-suggests --no-install-recommends install devscripts debhelper dput fakeroot
- name: Add launchpad to known_hosts
run: |
echo '|1|7SiYPr9xl3uctzovOTj4gMwAC1M=|t6ReES75Bo/PxlOPJ6/GsGbTrM0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0aKz5UTUndYgIGG7dQBV+HaeuEZJ2xPHo2DS2iSKvUL4xNMSAY4UguNW+pX56nAQmZKIZZ8MaEvSj6zMEDiq6HFfn5JcTlM80UwlnyKe8B8p7Nk06PPQLrnmQt5fh0HmEcZx+JU9TZsfCHPnX7MNz4ELfZE6cFsclClrKim3BHUIGq//t93DllB+h4O9LHjEUsQ1Sr63irDLSutkLJD6RXchjROXkNirlcNVHH/jwLWR5RcYilNX7S5bIkK8NlWPjsn/8Ua5O7I9/YoE97PpO6i73DTGLh5H9JN/SITwCKBkgSDWUt61uPK3Y11Gty7o2lWsBjhBUm2Y38CBsoGmBw==' >> ~/.ssh/known_hosts
- name: Run ci.go
run: |
go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user geth-ci -signer "Go Ethereum Linux Builder <geth-ci@ethereum.org>"
env:
PPA_SIGNING_KEY: ${{ secrets.PPA_SIGNING_KEY }}
PPA_SSH_KEY: ${{ secrets.PPA_SSH_KEY }}

View file

@ -0,0 +1,147 @@
on:
push:
branches:
- "master"
tags:
- "v*"
jobs:
linux-intel:
name: Linux Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.24
cache: false
- name: Install cross toolchain
run: |
apt-get update
apt-get -yq --no-install-suggests --no-install-recommends install gcc-multilib
- name: Build (amd64)
run: |
go run build/ci.go install -static -arch amd64 -dlgo
- name: Create/upload archive (amd64)
run: |
go run build/ci.go archive -arch amd64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
rm -f build/bin/*
env:
LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }}
AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }}
- name: Build (386)
run: |
go run build/ci.go install -static -arch 386 -dlgo
- name: Create/upload archive (386)
run: |
go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
rm -f build/bin/*
env:
LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }}
AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }}
linux-arm:
name: Linux Build (arm)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.24
cache: false
- name: Install cross toolchain
run: |
apt-get update
apt-get -yq --no-install-suggests --no-install-recommends install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross
ln -s /usr/include/asm-generic /usr/include/asm
- name: Build (arm64)
run: |
go run build/ci.go install -static -dlgo -arch arm64 -cc aarch64-linux-gnu-gcc
- name: Create/upload archive (arm64)
run: |
go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
rm -fr build/bin/*
env:
LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }}
AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }}
- name: Run build (arm5)
run: |
go run build/ci.go install -static -dlgo -arch arm -cc arm-linux-gnueabi-gcc
env:
GOARM: "5"
- name: Create/upload archive (arm5)
run: |
go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
env:
GOARM: "5"
LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }}
AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }}
- name: Run build (arm6)
run: |
go run build/ci.go install -static -dlgo -arch arm -cc arm-linux-gnueabi-gcc
env:
GOARM: "6"
- name: Create/upload archive (arm6)
run: |
go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
rm -fr build/bin/*
env:
GOARM: "6"
LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }}
AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }}
- name: Run build (arm7)
run: |
go run build/ci.go install -static -dlgo -arch arm -cc arm-linux-gnueabi-gcc
env:
GOARM: "7"
- name: Create/upload archive (arm7)
run: |
go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
rm -fr build/bin/*
env:
GOARM: "7"
LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }}
AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }}
docker:
name: Docker Image
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.24
cache: false
- name: Run docker build
env:
DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }}
DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }}
run: |
go run build/ci.go dockerx -platform linux/amd64,linux/arm64,linux/riscv64 -upload

View file

@ -1,115 +0,0 @@
language: go
go_import_path: github.com/ethereum/go-ethereum
sudo: false
jobs:
include:
# This builder create and push the Docker images for all architectures
- stage: build
if: type = push
os: linux
arch: amd64
dist: focal
go: 1.24.x
env:
- docker
services:
- docker
git:
submodules: false # avoid cloning ethereum/tests
before_install:
- export DOCKER_CLI_EXPERIMENTAL=enabled
script:
- go run build/ci.go dockerx -platform "linux/amd64,linux/arm64,linux/riscv64" -hub ethereum/client-go -upload
# This builder does the Linux Azure uploads
- stage: build
if: type = push
os: linux
dist: focal
sudo: required
go: 1.24.x
env:
- azure-linux
git:
submodules: false # avoid cloning ethereum/tests
script:
# build amd64
- go run build/ci.go install -dlgo
- go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
# build 386
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends install gcc-multilib
- git status --porcelain
- go run build/ci.go install -dlgo -arch 386
- go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
# Switch over GCC to cross compilation (breaks 386, hence why do it here only)
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross
- sudo ln -s /usr/include/asm-generic /usr/include/asm
- GOARM=5 go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc
- GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
- GOARM=6 go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc
- GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
- GOARM=7 go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabihf-gcc
- GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
- go run build/ci.go install -dlgo -arch arm64 -cc aarch64-linux-gnu-gcc
- go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
# These builders run the tests
- stage: build
if: type = push
os: linux
arch: amd64
dist: focal
go: 1.24.x
script:
- travis_wait 45 go run build/ci.go test $TEST_PACKAGES
- stage: build
if: type = push
os: linux
dist: focal
go: 1.23.x
script:
- travis_wait 45 go run build/ci.go test $TEST_PACKAGES
# This builder does the Ubuntu PPA nightly uploads
- stage: build
if: type = cron || (type = push && tag ~= /^v[0-9]/)
os: linux
dist: focal
go: 1.24.x
env:
- ubuntu-ppa
git:
submodules: false # avoid cloning ethereum/tests
before_install:
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends install devscripts debhelper dput fakeroot
script:
- echo '|1|7SiYPr9xl3uctzovOTj4gMwAC1M=|t6ReES75Bo/PxlOPJ6/GsGbTrM0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0aKz5UTUndYgIGG7dQBV+HaeuEZJ2xPHo2DS2iSKvUL4xNMSAY4UguNW+pX56nAQmZKIZZ8MaEvSj6zMEDiq6HFfn5JcTlM80UwlnyKe8B8p7Nk06PPQLrnmQt5fh0HmEcZx+JU9TZsfCHPnX7MNz4ELfZE6cFsclClrKim3BHUIGq//t93DllB+h4O9LHjEUsQ1Sr63irDLSutkLJD6RXchjROXkNirlcNVHH/jwLWR5RcYilNX7S5bIkK8NlWPjsn/8Ua5O7I9/YoE97PpO6i73DTGLh5H9JN/SITwCKBkgSDWUt61uPK3Y11Gty7o2lWsBjhBUm2Y38CBsoGmBw==' >> ~/.ssh/known_hosts
- go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user geth-ci -signer "Go Ethereum Linux Builder <geth-ci@ethereum.org>"
# This builder does the Azure archive purges to avoid accumulating junk
- stage: build
if: type = cron
os: linux
dist: focal
go: 1.24.x
env:
- azure-purge
git:
submodules: false # avoid cloning ethereum/tests
script:
- go run build/ci.go purge -store gethstore/builds -days 14
# This builder executes race tests
- stage: build
if: type = cron
os: linux
dist: focal
go: 1.24.x
env:
- racetests
script:
- travis_wait 60 go run build/ci.go test -race $TEST_PACKAGES

View file

@ -2,7 +2,7 @@
# with Go source code. If you know what GOPATH is then you probably
# don't need to bother with make.
.PHONY: geth all test lint fmt clean devtools help
.PHONY: geth evm all test lint fmt clean devtools help
GOBIN = ./build/bin
GO ?= latest
@ -14,6 +14,12 @@ geth:
@echo "Done building."
@echo "Run \"$(GOBIN)/geth\" to launch geth."
#? evm: Build evm.
evm:
$(GORUN) build/ci.go install ./cmd/evm
@echo "Done building."
@echo "Run \"$(GOBIN)/evm\" to launch evm."
#? all: Build all packages and executables.
all:
$(GORUN) build/ci.go install

View file

@ -162,7 +162,7 @@ accessible from the outside.
As a developer, sooner rather than later you'll want to start interacting with `geth` and the
Ethereum network via your own programs and not manually through the console. To aid
this, `geth` has built-in support for a JSON-RPC based APIs ([standard APIs](https://ethereum.github.io/execution-apis/api-documentation/)
this, `geth` has built-in support for a JSON-RPC based APIs ([standard APIs](https://ethereum.org/en/developers/docs/apis/json-rpc/)
and [`geth` specific APIs](https://geth.ethereum.org/docs/interacting-with-geth/rpc)).
These can be exposed via HTTP, WebSockets and IPC (UNIX sockets on UNIX based
platforms, and named pipes on Windows).

View file

@ -281,7 +281,7 @@ func TestBindingV2ConvertedV1Tests(t *testing.T) {
}
// Set this environment variable to regenerate the test outputs.
if os.Getenv("WRITE_TEST_FILES") != "" {
if err := os.WriteFile((fname), []byte(have), 0666); err != nil {
if err := os.WriteFile(fname, []byte(have), 0666); err != nil {
t.Fatalf("err writing expected output to file: %v\n", err)
}
}

View file

@ -90,7 +90,8 @@ var (
{{range .Calls}}
// Pack{{.Normalized.Name}} is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x{{printf "%x" .Original.ID}}.
// the contract method with ID 0x{{printf "%x" .Original.ID}}. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: {{.Original.String}}
func ({{ decapitalise $contract.Type}} *{{$contract.Type}}) Pack{{.Normalized.Name}}({{range .Normalized.Inputs}} {{.Name}} {{bindtype .Type $structs}}, {{end}}) []byte {
@ -101,6 +102,15 @@ var (
return enc
}
// TryPack{{.Normalized.Name}} is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x{{printf "%x" .Original.ID}}. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: {{.Original.String}}
func ({{ decapitalise $contract.Type}} *{{$contract.Type}}) TryPack{{.Normalized.Name}}({{range .Normalized.Inputs}} {{.Name}} {{bindtype .Type $structs}}, {{end}}) ([]byte, error) {
return {{ decapitalise $contract.Type}}.abi.Pack("{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}})
}
{{/* Unpack method is needed only when there are return args */}}
{{if .Normalized.Outputs }}
{{ if .Structured }}
@ -133,8 +143,7 @@ var (
outstruct.{{capitalise .Name}} = *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}})
{{- end }}
{{- end }}
return *outstruct, err
{{else}}
return *outstruct, nil{{else}}
if err != nil {
return {{range $i, $_ := .Normalized.Outputs}}{{if ispointertype .Type}}new({{underlyingbindtype .Type }}), {{else}}*new({{bindtype .Type $structs}}), {{end}}{{end}} err
}
@ -145,7 +154,7 @@ var (
out{{$i}} := *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}})
{{- end }}
{{- end}}
return {{range $i, $t := .Normalized.Outputs}}out{{$i}}, {{end}} err
return {{range $i, $t := .Normalized.Outputs}}out{{$i}}, {{end}} nil
{{- end}}
}
{{end}}

View file

@ -52,7 +52,8 @@ func (c *CallbackParam) Instance(backend bind.ContractBackend, addr common.Addre
}
// PackTest is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xd7a5aba2.
// the contract method with ID 0xd7a5aba2. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function test(function callback) returns()
func (callbackParam *CallbackParam) PackTest(callback [24]byte) []byte {
@ -62,3 +63,12 @@ func (callbackParam *CallbackParam) PackTest(callback [24]byte) []byte {
}
return enc
}
// TryPackTest is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xd7a5aba2. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function test(function callback) returns()
func (callbackParam *CallbackParam) TryPackTest(callback [24]byte) ([]byte, error) {
return callbackParam.abi.Pack("test", callback)
}

View file

@ -64,7 +64,8 @@ func (crowdsale *Crowdsale) PackConstructor(ifSuccessfulSendTo common.Address, f
}
// PackAmountRaised is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x7b3e5e7b.
// the contract method with ID 0x7b3e5e7b. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function amountRaised() returns(uint256)
func (crowdsale *Crowdsale) PackAmountRaised() []byte {
@ -75,6 +76,15 @@ func (crowdsale *Crowdsale) PackAmountRaised() []byte {
return enc
}
// TryPackAmountRaised is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x7b3e5e7b. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function amountRaised() returns(uint256)
func (crowdsale *Crowdsale) TryPackAmountRaised() ([]byte, error) {
return crowdsale.abi.Pack("amountRaised")
}
// UnpackAmountRaised is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x7b3e5e7b.
//
@ -85,11 +95,12 @@ func (crowdsale *Crowdsale) UnpackAmountRaised(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// PackBeneficiary is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x38af3eed.
// the contract method with ID 0x38af3eed. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function beneficiary() returns(address)
func (crowdsale *Crowdsale) PackBeneficiary() []byte {
@ -100,6 +111,15 @@ func (crowdsale *Crowdsale) PackBeneficiary() []byte {
return enc
}
// TryPackBeneficiary is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x38af3eed. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function beneficiary() returns(address)
func (crowdsale *Crowdsale) TryPackBeneficiary() ([]byte, error) {
return crowdsale.abi.Pack("beneficiary")
}
// UnpackBeneficiary is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x38af3eed.
//
@ -110,11 +130,12 @@ func (crowdsale *Crowdsale) UnpackBeneficiary(data []byte) (common.Address, erro
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
return out0, nil
}
// PackCheckGoalReached is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x01cb3b20.
// the contract method with ID 0x01cb3b20. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function checkGoalReached() returns()
func (crowdsale *Crowdsale) PackCheckGoalReached() []byte {
@ -125,8 +146,18 @@ func (crowdsale *Crowdsale) PackCheckGoalReached() []byte {
return enc
}
// TryPackCheckGoalReached is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x01cb3b20. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function checkGoalReached() returns()
func (crowdsale *Crowdsale) TryPackCheckGoalReached() ([]byte, error) {
return crowdsale.abi.Pack("checkGoalReached")
}
// PackDeadline is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x29dcb0cf.
// the contract method with ID 0x29dcb0cf. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function deadline() returns(uint256)
func (crowdsale *Crowdsale) PackDeadline() []byte {
@ -137,6 +168,15 @@ func (crowdsale *Crowdsale) PackDeadline() []byte {
return enc
}
// TryPackDeadline is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x29dcb0cf. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function deadline() returns(uint256)
func (crowdsale *Crowdsale) TryPackDeadline() ([]byte, error) {
return crowdsale.abi.Pack("deadline")
}
// UnpackDeadline is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x29dcb0cf.
//
@ -147,11 +187,12 @@ func (crowdsale *Crowdsale) UnpackDeadline(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// PackFunders is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xdc0d3dff.
// the contract method with ID 0xdc0d3dff. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function funders(uint256 ) returns(address addr, uint256 amount)
func (crowdsale *Crowdsale) PackFunders(arg0 *big.Int) []byte {
@ -162,6 +203,15 @@ func (crowdsale *Crowdsale) PackFunders(arg0 *big.Int) []byte {
return enc
}
// TryPackFunders is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xdc0d3dff. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function funders(uint256 ) returns(address addr, uint256 amount)
func (crowdsale *Crowdsale) TryPackFunders(arg0 *big.Int) ([]byte, error) {
return crowdsale.abi.Pack("funders", arg0)
}
// FundersOutput serves as a container for the return parameters of contract
// method Funders.
type FundersOutput struct {
@ -181,12 +231,12 @@ func (crowdsale *Crowdsale) UnpackFunders(data []byte) (FundersOutput, error) {
}
outstruct.Addr = *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
outstruct.Amount = abi.ConvertType(out[1], new(big.Int)).(*big.Int)
return *outstruct, err
return *outstruct, nil
}
// PackFundingGoal is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x7a3a0e84.
// the contract method with ID 0x7a3a0e84. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function fundingGoal() returns(uint256)
func (crowdsale *Crowdsale) PackFundingGoal() []byte {
@ -197,6 +247,15 @@ func (crowdsale *Crowdsale) PackFundingGoal() []byte {
return enc
}
// TryPackFundingGoal is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x7a3a0e84. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function fundingGoal() returns(uint256)
func (crowdsale *Crowdsale) TryPackFundingGoal() ([]byte, error) {
return crowdsale.abi.Pack("fundingGoal")
}
// UnpackFundingGoal is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x7a3a0e84.
//
@ -207,11 +266,12 @@ func (crowdsale *Crowdsale) UnpackFundingGoal(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// PackPrice is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xa035b1fe.
// the contract method with ID 0xa035b1fe. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function price() returns(uint256)
func (crowdsale *Crowdsale) PackPrice() []byte {
@ -222,6 +282,15 @@ func (crowdsale *Crowdsale) PackPrice() []byte {
return enc
}
// TryPackPrice is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xa035b1fe. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function price() returns(uint256)
func (crowdsale *Crowdsale) TryPackPrice() ([]byte, error) {
return crowdsale.abi.Pack("price")
}
// UnpackPrice is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0xa035b1fe.
//
@ -232,11 +301,12 @@ func (crowdsale *Crowdsale) UnpackPrice(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// PackTokenReward is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x6e66f6e9.
// the contract method with ID 0x6e66f6e9. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function tokenReward() returns(address)
func (crowdsale *Crowdsale) PackTokenReward() []byte {
@ -247,6 +317,15 @@ func (crowdsale *Crowdsale) PackTokenReward() []byte {
return enc
}
// TryPackTokenReward is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x6e66f6e9. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function tokenReward() returns(address)
func (crowdsale *Crowdsale) TryPackTokenReward() ([]byte, error) {
return crowdsale.abi.Pack("tokenReward")
}
// UnpackTokenReward is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x6e66f6e9.
//
@ -257,7 +336,7 @@ func (crowdsale *Crowdsale) UnpackTokenReward(data []byte) (common.Address, erro
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
return out0, nil
}
// CrowdsaleFundTransfer represents a FundTransfer event raised by the Crowdsale contract.

View file

@ -64,7 +64,8 @@ func (dAO *DAO) PackConstructor(minimumQuorumForProposals *big.Int, minutesForDe
}
// PackChangeMembership is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x9644fcbd.
// the contract method with ID 0x9644fcbd. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function changeMembership(address targetMember, bool canVote, string memberName) returns()
func (dAO *DAO) PackChangeMembership(targetMember common.Address, canVote bool, memberName string) []byte {
@ -75,8 +76,18 @@ func (dAO *DAO) PackChangeMembership(targetMember common.Address, canVote bool,
return enc
}
// TryPackChangeMembership is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x9644fcbd. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function changeMembership(address targetMember, bool canVote, string memberName) returns()
func (dAO *DAO) TryPackChangeMembership(targetMember common.Address, canVote bool, memberName string) ([]byte, error) {
return dAO.abi.Pack("changeMembership", targetMember, canVote, memberName)
}
// PackChangeVotingRules is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xbcca1fd3.
// the contract method with ID 0xbcca1fd3. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function changeVotingRules(uint256 minimumQuorumForProposals, uint256 minutesForDebate, int256 marginOfVotesForMajority) returns()
func (dAO *DAO) PackChangeVotingRules(minimumQuorumForProposals *big.Int, minutesForDebate *big.Int, marginOfVotesForMajority *big.Int) []byte {
@ -87,8 +98,18 @@ func (dAO *DAO) PackChangeVotingRules(minimumQuorumForProposals *big.Int, minute
return enc
}
// TryPackChangeVotingRules is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xbcca1fd3. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function changeVotingRules(uint256 minimumQuorumForProposals, uint256 minutesForDebate, int256 marginOfVotesForMajority) returns()
func (dAO *DAO) TryPackChangeVotingRules(minimumQuorumForProposals *big.Int, minutesForDebate *big.Int, marginOfVotesForMajority *big.Int) ([]byte, error) {
return dAO.abi.Pack("changeVotingRules", minimumQuorumForProposals, minutesForDebate, marginOfVotesForMajority)
}
// PackCheckProposalCode is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xeceb2945.
// the contract method with ID 0xeceb2945. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function checkProposalCode(uint256 proposalNumber, address beneficiary, uint256 etherAmount, bytes transactionBytecode) returns(bool codeChecksOut)
func (dAO *DAO) PackCheckProposalCode(proposalNumber *big.Int, beneficiary common.Address, etherAmount *big.Int, transactionBytecode []byte) []byte {
@ -99,6 +120,15 @@ func (dAO *DAO) PackCheckProposalCode(proposalNumber *big.Int, beneficiary commo
return enc
}
// TryPackCheckProposalCode is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xeceb2945. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function checkProposalCode(uint256 proposalNumber, address beneficiary, uint256 etherAmount, bytes transactionBytecode) returns(bool codeChecksOut)
func (dAO *DAO) TryPackCheckProposalCode(proposalNumber *big.Int, beneficiary common.Address, etherAmount *big.Int, transactionBytecode []byte) ([]byte, error) {
return dAO.abi.Pack("checkProposalCode", proposalNumber, beneficiary, etherAmount, transactionBytecode)
}
// UnpackCheckProposalCode is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0xeceb2945.
//
@ -109,11 +139,12 @@ func (dAO *DAO) UnpackCheckProposalCode(data []byte) (bool, error) {
return *new(bool), err
}
out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
return out0, err
return out0, nil
}
// PackDebatingPeriodInMinutes is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x69bd3436.
// the contract method with ID 0x69bd3436. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function debatingPeriodInMinutes() returns(uint256)
func (dAO *DAO) PackDebatingPeriodInMinutes() []byte {
@ -124,6 +155,15 @@ func (dAO *DAO) PackDebatingPeriodInMinutes() []byte {
return enc
}
// TryPackDebatingPeriodInMinutes is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x69bd3436. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function debatingPeriodInMinutes() returns(uint256)
func (dAO *DAO) TryPackDebatingPeriodInMinutes() ([]byte, error) {
return dAO.abi.Pack("debatingPeriodInMinutes")
}
// UnpackDebatingPeriodInMinutes is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x69bd3436.
//
@ -134,11 +174,12 @@ func (dAO *DAO) UnpackDebatingPeriodInMinutes(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// PackExecuteProposal is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x237e9492.
// the contract method with ID 0x237e9492. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function executeProposal(uint256 proposalNumber, bytes transactionBytecode) returns(int256 result)
func (dAO *DAO) PackExecuteProposal(proposalNumber *big.Int, transactionBytecode []byte) []byte {
@ -149,6 +190,15 @@ func (dAO *DAO) PackExecuteProposal(proposalNumber *big.Int, transactionBytecode
return enc
}
// TryPackExecuteProposal is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x237e9492. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function executeProposal(uint256 proposalNumber, bytes transactionBytecode) returns(int256 result)
func (dAO *DAO) TryPackExecuteProposal(proposalNumber *big.Int, transactionBytecode []byte) ([]byte, error) {
return dAO.abi.Pack("executeProposal", proposalNumber, transactionBytecode)
}
// UnpackExecuteProposal is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x237e9492.
//
@ -159,11 +209,12 @@ func (dAO *DAO) UnpackExecuteProposal(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// PackMajorityMargin is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xaa02a90f.
// the contract method with ID 0xaa02a90f. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function majorityMargin() returns(int256)
func (dAO *DAO) PackMajorityMargin() []byte {
@ -174,6 +225,15 @@ func (dAO *DAO) PackMajorityMargin() []byte {
return enc
}
// TryPackMajorityMargin is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xaa02a90f. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function majorityMargin() returns(int256)
func (dAO *DAO) TryPackMajorityMargin() ([]byte, error) {
return dAO.abi.Pack("majorityMargin")
}
// UnpackMajorityMargin is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0xaa02a90f.
//
@ -184,11 +244,12 @@ func (dAO *DAO) UnpackMajorityMargin(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// PackMemberId is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x39106821.
// the contract method with ID 0x39106821. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function memberId(address ) returns(uint256)
func (dAO *DAO) PackMemberId(arg0 common.Address) []byte {
@ -199,6 +260,15 @@ func (dAO *DAO) PackMemberId(arg0 common.Address) []byte {
return enc
}
// TryPackMemberId is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x39106821. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function memberId(address ) returns(uint256)
func (dAO *DAO) TryPackMemberId(arg0 common.Address) ([]byte, error) {
return dAO.abi.Pack("memberId", arg0)
}
// UnpackMemberId is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x39106821.
//
@ -209,11 +279,12 @@ func (dAO *DAO) UnpackMemberId(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// PackMembers is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x5daf08ca.
// the contract method with ID 0x5daf08ca. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function members(uint256 ) returns(address member, bool canVote, string name, uint256 memberSince)
func (dAO *DAO) PackMembers(arg0 *big.Int) []byte {
@ -224,6 +295,15 @@ func (dAO *DAO) PackMembers(arg0 *big.Int) []byte {
return enc
}
// TryPackMembers is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x5daf08ca. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function members(uint256 ) returns(address member, bool canVote, string name, uint256 memberSince)
func (dAO *DAO) TryPackMembers(arg0 *big.Int) ([]byte, error) {
return dAO.abi.Pack("members", arg0)
}
// MembersOutput serves as a container for the return parameters of contract
// method Members.
type MembersOutput struct {
@ -247,12 +327,12 @@ func (dAO *DAO) UnpackMembers(data []byte) (MembersOutput, error) {
outstruct.CanVote = *abi.ConvertType(out[1], new(bool)).(*bool)
outstruct.Name = *abi.ConvertType(out[2], new(string)).(*string)
outstruct.MemberSince = abi.ConvertType(out[3], new(big.Int)).(*big.Int)
return *outstruct, err
return *outstruct, nil
}
// PackMinimumQuorum is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x8160f0b5.
// the contract method with ID 0x8160f0b5. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function minimumQuorum() returns(uint256)
func (dAO *DAO) PackMinimumQuorum() []byte {
@ -263,6 +343,15 @@ func (dAO *DAO) PackMinimumQuorum() []byte {
return enc
}
// TryPackMinimumQuorum is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x8160f0b5. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function minimumQuorum() returns(uint256)
func (dAO *DAO) TryPackMinimumQuorum() ([]byte, error) {
return dAO.abi.Pack("minimumQuorum")
}
// UnpackMinimumQuorum is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x8160f0b5.
//
@ -273,11 +362,12 @@ func (dAO *DAO) UnpackMinimumQuorum(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// PackNewProposal is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xb1050da5.
// the contract method with ID 0xb1050da5. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function newProposal(address beneficiary, uint256 etherAmount, string JobDescription, bytes transactionBytecode) returns(uint256 proposalID)
func (dAO *DAO) PackNewProposal(beneficiary common.Address, etherAmount *big.Int, jobDescription string, transactionBytecode []byte) []byte {
@ -288,6 +378,15 @@ func (dAO *DAO) PackNewProposal(beneficiary common.Address, etherAmount *big.Int
return enc
}
// TryPackNewProposal is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xb1050da5. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function newProposal(address beneficiary, uint256 etherAmount, string JobDescription, bytes transactionBytecode) returns(uint256 proposalID)
func (dAO *DAO) TryPackNewProposal(beneficiary common.Address, etherAmount *big.Int, jobDescription string, transactionBytecode []byte) ([]byte, error) {
return dAO.abi.Pack("newProposal", beneficiary, etherAmount, jobDescription, transactionBytecode)
}
// UnpackNewProposal is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0xb1050da5.
//
@ -298,11 +397,12 @@ func (dAO *DAO) UnpackNewProposal(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// PackNumProposals is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x400e3949.
// the contract method with ID 0x400e3949. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function numProposals() returns(uint256)
func (dAO *DAO) PackNumProposals() []byte {
@ -313,6 +413,15 @@ func (dAO *DAO) PackNumProposals() []byte {
return enc
}
// TryPackNumProposals is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x400e3949. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function numProposals() returns(uint256)
func (dAO *DAO) TryPackNumProposals() ([]byte, error) {
return dAO.abi.Pack("numProposals")
}
// UnpackNumProposals is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x400e3949.
//
@ -323,11 +432,12 @@ func (dAO *DAO) UnpackNumProposals(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// PackOwner is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x8da5cb5b.
// the contract method with ID 0x8da5cb5b. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function owner() returns(address)
func (dAO *DAO) PackOwner() []byte {
@ -338,6 +448,15 @@ func (dAO *DAO) PackOwner() []byte {
return enc
}
// TryPackOwner is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x8da5cb5b. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function owner() returns(address)
func (dAO *DAO) TryPackOwner() ([]byte, error) {
return dAO.abi.Pack("owner")
}
// UnpackOwner is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x8da5cb5b.
//
@ -348,11 +467,12 @@ func (dAO *DAO) UnpackOwner(data []byte) (common.Address, error) {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
return out0, nil
}
// PackProposals is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x013cf08b.
// the contract method with ID 0x013cf08b. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function proposals(uint256 ) returns(address recipient, uint256 amount, string description, uint256 votingDeadline, bool executed, bool proposalPassed, uint256 numberOfVotes, int256 currentResult, bytes32 proposalHash)
func (dAO *DAO) PackProposals(arg0 *big.Int) []byte {
@ -363,6 +483,15 @@ func (dAO *DAO) PackProposals(arg0 *big.Int) []byte {
return enc
}
// TryPackProposals is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x013cf08b. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function proposals(uint256 ) returns(address recipient, uint256 amount, string description, uint256 votingDeadline, bool executed, bool proposalPassed, uint256 numberOfVotes, int256 currentResult, bytes32 proposalHash)
func (dAO *DAO) TryPackProposals(arg0 *big.Int) ([]byte, error) {
return dAO.abi.Pack("proposals", arg0)
}
// ProposalsOutput serves as a container for the return parameters of contract
// method Proposals.
type ProposalsOutput struct {
@ -396,12 +525,12 @@ func (dAO *DAO) UnpackProposals(data []byte) (ProposalsOutput, error) {
outstruct.NumberOfVotes = abi.ConvertType(out[6], new(big.Int)).(*big.Int)
outstruct.CurrentResult = abi.ConvertType(out[7], new(big.Int)).(*big.Int)
outstruct.ProposalHash = *abi.ConvertType(out[8], new([32]byte)).(*[32]byte)
return *outstruct, err
return *outstruct, nil
}
// PackTransferOwnership is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xf2fde38b.
// the contract method with ID 0xf2fde38b. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function transferOwnership(address newOwner) returns()
func (dAO *DAO) PackTransferOwnership(newOwner common.Address) []byte {
@ -412,8 +541,18 @@ func (dAO *DAO) PackTransferOwnership(newOwner common.Address) []byte {
return enc
}
// TryPackTransferOwnership is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xf2fde38b. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function transferOwnership(address newOwner) returns()
func (dAO *DAO) TryPackTransferOwnership(newOwner common.Address) ([]byte, error) {
return dAO.abi.Pack("transferOwnership", newOwner)
}
// PackVote is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xd3c0715b.
// the contract method with ID 0xd3c0715b. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function vote(uint256 proposalNumber, bool supportsProposal, string justificationText) returns(uint256 voteID)
func (dAO *DAO) PackVote(proposalNumber *big.Int, supportsProposal bool, justificationText string) []byte {
@ -424,6 +563,15 @@ func (dAO *DAO) PackVote(proposalNumber *big.Int, supportsProposal bool, justifi
return enc
}
// TryPackVote is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xd3c0715b. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function vote(uint256 proposalNumber, bool supportsProposal, string justificationText) returns(uint256 voteID)
func (dAO *DAO) TryPackVote(proposalNumber *big.Int, supportsProposal bool, justificationText string) ([]byte, error) {
return dAO.abi.Pack("vote", proposalNumber, supportsProposal, justificationText)
}
// UnpackVote is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0xd3c0715b.
//
@ -434,7 +582,7 @@ func (dAO *DAO) UnpackVote(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// DAOChangeOfRules represents a ChangeOfRules event raised by the DAO contract.

View file

@ -52,7 +52,8 @@ func (c *DeeplyNestedArray) Instance(backend bind.ContractBackend, addr common.A
}
// PackDeepUint64Array is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x98ed1856.
// the contract method with ID 0x98ed1856. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function deepUint64Array(uint256 , uint256 , uint256 ) view returns(uint64)
func (deeplyNestedArray *DeeplyNestedArray) PackDeepUint64Array(arg0 *big.Int, arg1 *big.Int, arg2 *big.Int) []byte {
@ -63,6 +64,15 @@ func (deeplyNestedArray *DeeplyNestedArray) PackDeepUint64Array(arg0 *big.Int, a
return enc
}
// TryPackDeepUint64Array is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x98ed1856. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function deepUint64Array(uint256 , uint256 , uint256 ) view returns(uint64)
func (deeplyNestedArray *DeeplyNestedArray) TryPackDeepUint64Array(arg0 *big.Int, arg1 *big.Int, arg2 *big.Int) ([]byte, error) {
return deeplyNestedArray.abi.Pack("deepUint64Array", arg0, arg1, arg2)
}
// UnpackDeepUint64Array is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x98ed1856.
//
@ -73,11 +83,12 @@ func (deeplyNestedArray *DeeplyNestedArray) UnpackDeepUint64Array(data []byte) (
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
return out0, nil
}
// PackRetrieveDeepArray is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x8ed4573a.
// the contract method with ID 0x8ed4573a. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function retrieveDeepArray() view returns(uint64[3][4][5])
func (deeplyNestedArray *DeeplyNestedArray) PackRetrieveDeepArray() []byte {
@ -88,6 +99,15 @@ func (deeplyNestedArray *DeeplyNestedArray) PackRetrieveDeepArray() []byte {
return enc
}
// TryPackRetrieveDeepArray is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x8ed4573a. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function retrieveDeepArray() view returns(uint64[3][4][5])
func (deeplyNestedArray *DeeplyNestedArray) TryPackRetrieveDeepArray() ([]byte, error) {
return deeplyNestedArray.abi.Pack("retrieveDeepArray")
}
// UnpackRetrieveDeepArray is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x8ed4573a.
//
@ -98,11 +118,12 @@ func (deeplyNestedArray *DeeplyNestedArray) UnpackRetrieveDeepArray(data []byte)
return *new([5][4][3]uint64), err
}
out0 := *abi.ConvertType(out[0], new([5][4][3]uint64)).(*[5][4][3]uint64)
return out0, err
return out0, nil
}
// PackStoreDeepUintArray is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x34424855.
// the contract method with ID 0x34424855. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function storeDeepUintArray(uint64[3][4][5] arr) returns()
func (deeplyNestedArray *DeeplyNestedArray) PackStoreDeepUintArray(arr [5][4][3]uint64) []byte {
@ -112,3 +133,12 @@ func (deeplyNestedArray *DeeplyNestedArray) PackStoreDeepUintArray(arr [5][4][3]
}
return enc
}
// TryPackStoreDeepUintArray is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x34424855. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function storeDeepUintArray(uint64[3][4][5] arr) returns()
func (deeplyNestedArray *DeeplyNestedArray) TryPackStoreDeepUintArray(arr [5][4][3]uint64) ([]byte, error) {
return deeplyNestedArray.abi.Pack("storeDeepUintArray", arr)
}

View file

@ -52,7 +52,8 @@ func (c *Getter) Instance(backend bind.ContractBackend, addr common.Address) *bi
}
// PackGetter is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x993a04b7.
// the contract method with ID 0x993a04b7. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function getter() returns(string, int256, bytes32)
func (getter *Getter) PackGetter() []byte {
@ -63,6 +64,15 @@ func (getter *Getter) PackGetter() []byte {
return enc
}
// TryPackGetter is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x993a04b7. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function getter() returns(string, int256, bytes32)
func (getter *Getter) TryPackGetter() ([]byte, error) {
return getter.abi.Pack("getter")
}
// GetterOutput serves as a container for the return parameters of contract
// method Getter.
type GetterOutput struct {
@ -84,6 +94,5 @@ func (getter *Getter) UnpackGetter(data []byte) (GetterOutput, error) {
outstruct.Arg0 = *abi.ConvertType(out[0], new(string)).(*string)
outstruct.Arg1 = abi.ConvertType(out[1], new(big.Int)).(*big.Int)
outstruct.Arg2 = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte)
return *outstruct, err
return *outstruct, nil
}

View file

@ -52,7 +52,8 @@ func (c *IdentifierCollision) Instance(backend bind.ContractBackend, addr common
}
// PackMyVar is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x4ef1f0ad.
// the contract method with ID 0x4ef1f0ad. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function MyVar() view returns(uint256)
func (identifierCollision *IdentifierCollision) PackMyVar() []byte {
@ -63,6 +64,15 @@ func (identifierCollision *IdentifierCollision) PackMyVar() []byte {
return enc
}
// TryPackMyVar is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x4ef1f0ad. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function MyVar() view returns(uint256)
func (identifierCollision *IdentifierCollision) TryPackMyVar() ([]byte, error) {
return identifierCollision.abi.Pack("MyVar")
}
// UnpackMyVar is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x4ef1f0ad.
//
@ -73,11 +83,12 @@ func (identifierCollision *IdentifierCollision) UnpackMyVar(data []byte) (*big.I
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// PackPubVar is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x01ad4d87.
// the contract method with ID 0x01ad4d87. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function _myVar() view returns(uint256)
func (identifierCollision *IdentifierCollision) PackPubVar() []byte {
@ -88,6 +99,15 @@ func (identifierCollision *IdentifierCollision) PackPubVar() []byte {
return enc
}
// TryPackPubVar is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x01ad4d87. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function _myVar() view returns(uint256)
func (identifierCollision *IdentifierCollision) TryPackPubVar() ([]byte, error) {
return identifierCollision.abi.Pack("_myVar")
}
// UnpackPubVar is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x01ad4d87.
//
@ -98,5 +118,5 @@ func (identifierCollision *IdentifierCollision) UnpackPubVar(data []byte) (*big.
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}

View file

@ -51,7 +51,8 @@ func (c *InputChecker) Instance(backend bind.ContractBackend, addr common.Addres
}
// PackAnonInput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x3e708e82.
// the contract method with ID 0x3e708e82. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function anonInput(string ) returns()
func (inputChecker *InputChecker) PackAnonInput(arg0 string) []byte {
@ -62,8 +63,18 @@ func (inputChecker *InputChecker) PackAnonInput(arg0 string) []byte {
return enc
}
// TryPackAnonInput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x3e708e82. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function anonInput(string ) returns()
func (inputChecker *InputChecker) TryPackAnonInput(arg0 string) ([]byte, error) {
return inputChecker.abi.Pack("anonInput", arg0)
}
// PackAnonInputs is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x28160527.
// the contract method with ID 0x28160527. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function anonInputs(string , string ) returns()
func (inputChecker *InputChecker) PackAnonInputs(arg0 string, arg1 string) []byte {
@ -74,8 +85,18 @@ func (inputChecker *InputChecker) PackAnonInputs(arg0 string, arg1 string) []byt
return enc
}
// TryPackAnonInputs is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x28160527. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function anonInputs(string , string ) returns()
func (inputChecker *InputChecker) TryPackAnonInputs(arg0 string, arg1 string) ([]byte, error) {
return inputChecker.abi.Pack("anonInputs", arg0, arg1)
}
// PackMixedInputs is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xc689ebdc.
// the contract method with ID 0xc689ebdc. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function mixedInputs(string , string str) returns()
func (inputChecker *InputChecker) PackMixedInputs(arg0 string, str string) []byte {
@ -86,8 +107,18 @@ func (inputChecker *InputChecker) PackMixedInputs(arg0 string, str string) []byt
return enc
}
// TryPackMixedInputs is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xc689ebdc. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function mixedInputs(string , string str) returns()
func (inputChecker *InputChecker) TryPackMixedInputs(arg0 string, str string) ([]byte, error) {
return inputChecker.abi.Pack("mixedInputs", arg0, str)
}
// PackNamedInput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x0d402005.
// the contract method with ID 0x0d402005. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function namedInput(string str) returns()
func (inputChecker *InputChecker) PackNamedInput(str string) []byte {
@ -98,8 +129,18 @@ func (inputChecker *InputChecker) PackNamedInput(str string) []byte {
return enc
}
// TryPackNamedInput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x0d402005. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function namedInput(string str) returns()
func (inputChecker *InputChecker) TryPackNamedInput(str string) ([]byte, error) {
return inputChecker.abi.Pack("namedInput", str)
}
// PackNamedInputs is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x63c796ed.
// the contract method with ID 0x63c796ed. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function namedInputs(string str1, string str2) returns()
func (inputChecker *InputChecker) PackNamedInputs(str1 string, str2 string) []byte {
@ -110,8 +151,18 @@ func (inputChecker *InputChecker) PackNamedInputs(str1 string, str2 string) []by
return enc
}
// TryPackNamedInputs is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x63c796ed. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function namedInputs(string str1, string str2) returns()
func (inputChecker *InputChecker) TryPackNamedInputs(str1 string, str2 string) ([]byte, error) {
return inputChecker.abi.Pack("namedInputs", str1, str2)
}
// PackNoInput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x53539029.
// the contract method with ID 0x53539029. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function noInput() returns()
func (inputChecker *InputChecker) PackNoInput() []byte {
@ -121,3 +172,12 @@ func (inputChecker *InputChecker) PackNoInput() []byte {
}
return enc
}
// TryPackNoInput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x53539029. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function noInput() returns()
func (inputChecker *InputChecker) TryPackNoInput() ([]byte, error) {
return inputChecker.abi.Pack("noInput")
}

View file

@ -64,7 +64,8 @@ func (interactor *Interactor) PackConstructor(str string) []byte {
}
// PackDeployString is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x6874e809.
// the contract method with ID 0x6874e809. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function deployString() returns(string)
func (interactor *Interactor) PackDeployString() []byte {
@ -75,6 +76,15 @@ func (interactor *Interactor) PackDeployString() []byte {
return enc
}
// TryPackDeployString is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x6874e809. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function deployString() returns(string)
func (interactor *Interactor) TryPackDeployString() ([]byte, error) {
return interactor.abi.Pack("deployString")
}
// UnpackDeployString is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x6874e809.
//
@ -85,11 +95,12 @@ func (interactor *Interactor) UnpackDeployString(data []byte) (string, error) {
return *new(string), err
}
out0 := *abi.ConvertType(out[0], new(string)).(*string)
return out0, err
return out0, nil
}
// PackTransact is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xd736c513.
// the contract method with ID 0xd736c513. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function transact(string str) returns()
func (interactor *Interactor) PackTransact(str string) []byte {
@ -100,8 +111,18 @@ func (interactor *Interactor) PackTransact(str string) []byte {
return enc
}
// TryPackTransact is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xd736c513. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function transact(string str) returns()
func (interactor *Interactor) TryPackTransact(str string) ([]byte, error) {
return interactor.abi.Pack("transact", str)
}
// PackTransactString is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x0d86a0e1.
// the contract method with ID 0x0d86a0e1. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function transactString() returns(string)
func (interactor *Interactor) PackTransactString() []byte {
@ -112,6 +133,15 @@ func (interactor *Interactor) PackTransactString() []byte {
return enc
}
// TryPackTransactString is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x0d86a0e1. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function transactString() returns(string)
func (interactor *Interactor) TryPackTransactString() ([]byte, error) {
return interactor.abi.Pack("transactString")
}
// UnpackTransactString is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x0d86a0e1.
//
@ -122,5 +152,5 @@ func (interactor *Interactor) UnpackTransactString(data []byte) (string, error)
return *new(string), err
}
out0 := *abi.ConvertType(out[0], new(string)).(*string)
return out0, err
return out0, nil
}

View file

@ -58,7 +58,8 @@ func (c *NameConflict) Instance(backend bind.ContractBackend, addr common.Addres
}
// PackAddRequest is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xcce7b048.
// the contract method with ID 0xcce7b048. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function addRequest((bytes,bytes) req) pure returns()
func (nameConflict *NameConflict) PackAddRequest(req Oraclerequest) []byte {
@ -69,8 +70,18 @@ func (nameConflict *NameConflict) PackAddRequest(req Oraclerequest) []byte {
return enc
}
// TryPackAddRequest is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xcce7b048. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function addRequest((bytes,bytes) req) pure returns()
func (nameConflict *NameConflict) TryPackAddRequest(req Oraclerequest) ([]byte, error) {
return nameConflict.abi.Pack("addRequest", req)
}
// PackGetRequest is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xc2bb515f.
// the contract method with ID 0xc2bb515f. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function getRequest() pure returns((bytes,bytes))
func (nameConflict *NameConflict) PackGetRequest() []byte {
@ -81,6 +92,15 @@ func (nameConflict *NameConflict) PackGetRequest() []byte {
return enc
}
// TryPackGetRequest is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xc2bb515f. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function getRequest() pure returns((bytes,bytes))
func (nameConflict *NameConflict) TryPackGetRequest() ([]byte, error) {
return nameConflict.abi.Pack("getRequest")
}
// UnpackGetRequest is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0xc2bb515f.
//
@ -91,7 +111,7 @@ func (nameConflict *NameConflict) UnpackGetRequest(data []byte) (Oraclerequest,
return *new(Oraclerequest), err
}
out0 := *abi.ConvertType(out[0], new(Oraclerequest)).(*Oraclerequest)
return out0, err
return out0, nil
}
// NameConflictLog represents a log event raised by the NameConflict contract.

View file

@ -52,7 +52,8 @@ func (c *NumericMethodName) Instance(backend bind.ContractBackend, addr common.A
}
// PackE1test is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xffa02795.
// the contract method with ID 0xffa02795. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function _1test() pure returns()
func (numericMethodName *NumericMethodName) PackE1test() []byte {
@ -63,8 +64,18 @@ func (numericMethodName *NumericMethodName) PackE1test() []byte {
return enc
}
// TryPackE1test is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xffa02795. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function _1test() pure returns()
func (numericMethodName *NumericMethodName) TryPackE1test() ([]byte, error) {
return numericMethodName.abi.Pack("_1test")
}
// PackE1test0 is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xd02767c7.
// the contract method with ID 0xd02767c7. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function __1test() pure returns()
func (numericMethodName *NumericMethodName) PackE1test0() []byte {
@ -75,8 +86,18 @@ func (numericMethodName *NumericMethodName) PackE1test0() []byte {
return enc
}
// TryPackE1test0 is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xd02767c7. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function __1test() pure returns()
func (numericMethodName *NumericMethodName) TryPackE1test0() ([]byte, error) {
return numericMethodName.abi.Pack("__1test")
}
// PackE2test is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x9d993132.
// the contract method with ID 0x9d993132. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function __2test() pure returns()
func (numericMethodName *NumericMethodName) PackE2test() []byte {
@ -87,6 +108,15 @@ func (numericMethodName *NumericMethodName) PackE2test() []byte {
return enc
}
// TryPackE2test is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x9d993132. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function __2test() pure returns()
func (numericMethodName *NumericMethodName) TryPackE2test() ([]byte, error) {
return numericMethodName.abi.Pack("__2test")
}
// NumericMethodNameE1TestEvent represents a _1TestEvent event raised by the NumericMethodName contract.
type NumericMethodNameE1TestEvent struct {
Param common.Address

View file

@ -51,7 +51,8 @@ func (c *OutputChecker) Instance(backend bind.ContractBackend, addr common.Addre
}
// PackAnonOutput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x008bda05.
// the contract method with ID 0x008bda05. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function anonOutput() returns(string)
func (outputChecker *OutputChecker) PackAnonOutput() []byte {
@ -62,6 +63,15 @@ func (outputChecker *OutputChecker) PackAnonOutput() []byte {
return enc
}
// TryPackAnonOutput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x008bda05. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function anonOutput() returns(string)
func (outputChecker *OutputChecker) TryPackAnonOutput() ([]byte, error) {
return outputChecker.abi.Pack("anonOutput")
}
// UnpackAnonOutput is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x008bda05.
//
@ -72,11 +82,12 @@ func (outputChecker *OutputChecker) UnpackAnonOutput(data []byte) (string, error
return *new(string), err
}
out0 := *abi.ConvertType(out[0], new(string)).(*string)
return out0, err
return out0, nil
}
// PackAnonOutputs is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x3c401115.
// the contract method with ID 0x3c401115. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function anonOutputs() returns(string, string)
func (outputChecker *OutputChecker) PackAnonOutputs() []byte {
@ -87,6 +98,15 @@ func (outputChecker *OutputChecker) PackAnonOutputs() []byte {
return enc
}
// TryPackAnonOutputs is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x3c401115. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function anonOutputs() returns(string, string)
func (outputChecker *OutputChecker) TryPackAnonOutputs() ([]byte, error) {
return outputChecker.abi.Pack("anonOutputs")
}
// AnonOutputsOutput serves as a container for the return parameters of contract
// method AnonOutputs.
type AnonOutputsOutput struct {
@ -106,12 +126,12 @@ func (outputChecker *OutputChecker) UnpackAnonOutputs(data []byte) (AnonOutputsO
}
outstruct.Arg0 = *abi.ConvertType(out[0], new(string)).(*string)
outstruct.Arg1 = *abi.ConvertType(out[1], new(string)).(*string)
return *outstruct, err
return *outstruct, nil
}
// PackCollidingOutputs is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xeccbc1ee.
// the contract method with ID 0xeccbc1ee. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function collidingOutputs() returns(string str, string Str)
func (outputChecker *OutputChecker) PackCollidingOutputs() []byte {
@ -122,6 +142,15 @@ func (outputChecker *OutputChecker) PackCollidingOutputs() []byte {
return enc
}
// TryPackCollidingOutputs is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xeccbc1ee. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function collidingOutputs() returns(string str, string Str)
func (outputChecker *OutputChecker) TryPackCollidingOutputs() ([]byte, error) {
return outputChecker.abi.Pack("collidingOutputs")
}
// CollidingOutputsOutput serves as a container for the return parameters of contract
// method CollidingOutputs.
type CollidingOutputsOutput struct {
@ -141,12 +170,12 @@ func (outputChecker *OutputChecker) UnpackCollidingOutputs(data []byte) (Collidi
}
outstruct.Str = *abi.ConvertType(out[0], new(string)).(*string)
outstruct.Str0 = *abi.ConvertType(out[1], new(string)).(*string)
return *outstruct, err
return *outstruct, nil
}
// PackMixedOutputs is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x21b77b44.
// the contract method with ID 0x21b77b44. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function mixedOutputs() returns(string, string str)
func (outputChecker *OutputChecker) PackMixedOutputs() []byte {
@ -157,6 +186,15 @@ func (outputChecker *OutputChecker) PackMixedOutputs() []byte {
return enc
}
// TryPackMixedOutputs is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x21b77b44. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function mixedOutputs() returns(string, string str)
func (outputChecker *OutputChecker) TryPackMixedOutputs() ([]byte, error) {
return outputChecker.abi.Pack("mixedOutputs")
}
// MixedOutputsOutput serves as a container for the return parameters of contract
// method MixedOutputs.
type MixedOutputsOutput struct {
@ -176,12 +214,12 @@ func (outputChecker *OutputChecker) UnpackMixedOutputs(data []byte) (MixedOutput
}
outstruct.Arg0 = *abi.ConvertType(out[0], new(string)).(*string)
outstruct.Str = *abi.ConvertType(out[1], new(string)).(*string)
return *outstruct, err
return *outstruct, nil
}
// PackNamedOutput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x5e632bd5.
// the contract method with ID 0x5e632bd5. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function namedOutput() returns(string str)
func (outputChecker *OutputChecker) PackNamedOutput() []byte {
@ -192,6 +230,15 @@ func (outputChecker *OutputChecker) PackNamedOutput() []byte {
return enc
}
// TryPackNamedOutput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x5e632bd5. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function namedOutput() returns(string str)
func (outputChecker *OutputChecker) TryPackNamedOutput() ([]byte, error) {
return outputChecker.abi.Pack("namedOutput")
}
// UnpackNamedOutput is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x5e632bd5.
//
@ -202,11 +249,12 @@ func (outputChecker *OutputChecker) UnpackNamedOutput(data []byte) (string, erro
return *new(string), err
}
out0 := *abi.ConvertType(out[0], new(string)).(*string)
return out0, err
return out0, nil
}
// PackNamedOutputs is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x7970a189.
// the contract method with ID 0x7970a189. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function namedOutputs() returns(string str1, string str2)
func (outputChecker *OutputChecker) PackNamedOutputs() []byte {
@ -217,6 +265,15 @@ func (outputChecker *OutputChecker) PackNamedOutputs() []byte {
return enc
}
// TryPackNamedOutputs is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x7970a189. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function namedOutputs() returns(string str1, string str2)
func (outputChecker *OutputChecker) TryPackNamedOutputs() ([]byte, error) {
return outputChecker.abi.Pack("namedOutputs")
}
// NamedOutputsOutput serves as a container for the return parameters of contract
// method NamedOutputs.
type NamedOutputsOutput struct {
@ -236,12 +293,12 @@ func (outputChecker *OutputChecker) UnpackNamedOutputs(data []byte) (NamedOutput
}
outstruct.Str1 = *abi.ConvertType(out[0], new(string)).(*string)
outstruct.Str2 = *abi.ConvertType(out[1], new(string)).(*string)
return *outstruct, err
return *outstruct, nil
}
// PackNoOutput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x625f0306.
// the contract method with ID 0x625f0306. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function noOutput() returns()
func (outputChecker *OutputChecker) PackNoOutput() []byte {
@ -251,3 +308,12 @@ func (outputChecker *OutputChecker) PackNoOutput() []byte {
}
return enc
}
// TryPackNoOutput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x625f0306. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function noOutput() returns()
func (outputChecker *OutputChecker) TryPackNoOutput() ([]byte, error) {
return outputChecker.abi.Pack("noOutput")
}

View file

@ -52,7 +52,8 @@ func (c *Overload) Instance(backend bind.ContractBackend, addr common.Address) *
}
// PackFoo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x04bc52f8.
// the contract method with ID 0x04bc52f8. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function foo(uint256 i, uint256 j) returns()
func (overload *Overload) PackFoo(i *big.Int, j *big.Int) []byte {
@ -63,8 +64,18 @@ func (overload *Overload) PackFoo(i *big.Int, j *big.Int) []byte {
return enc
}
// TryPackFoo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x04bc52f8. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function foo(uint256 i, uint256 j) returns()
func (overload *Overload) TryPackFoo(i *big.Int, j *big.Int) ([]byte, error) {
return overload.abi.Pack("foo", i, j)
}
// PackFoo0 is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2fbebd38.
// the contract method with ID 0x2fbebd38. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function foo(uint256 i) returns()
func (overload *Overload) PackFoo0(i *big.Int) []byte {
@ -75,6 +86,15 @@ func (overload *Overload) PackFoo0(i *big.Int) []byte {
return enc
}
// TryPackFoo0 is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2fbebd38. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function foo(uint256 i) returns()
func (overload *Overload) TryPackFoo0(i *big.Int) ([]byte, error) {
return overload.abi.Pack("foo0", i)
}
// OverloadBar represents a bar event raised by the Overload contract.
type OverloadBar struct {
I *big.Int

View file

@ -52,7 +52,8 @@ func (c *RangeKeyword) Instance(backend bind.ContractBackend, addr common.Addres
}
// PackFunctionWithKeywordParameter is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x527a119f.
// the contract method with ID 0x527a119f. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function functionWithKeywordParameter(uint256 range) pure returns()
func (rangeKeyword *RangeKeyword) PackFunctionWithKeywordParameter(arg0 *big.Int) []byte {
@ -62,3 +63,12 @@ func (rangeKeyword *RangeKeyword) PackFunctionWithKeywordParameter(arg0 *big.Int
}
return enc
}
// TryPackFunctionWithKeywordParameter is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x527a119f. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function functionWithKeywordParameter(uint256 range) pure returns()
func (rangeKeyword *RangeKeyword) TryPackFunctionWithKeywordParameter(arg0 *big.Int) ([]byte, error) {
return rangeKeyword.abi.Pack("functionWithKeywordParameter", arg0)
}

View file

@ -52,7 +52,8 @@ func (c *Slicer) Instance(backend bind.ContractBackend, addr common.Address) *bi
}
// PackEchoAddresses is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xbe1127a3.
// the contract method with ID 0xbe1127a3. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function echoAddresses(address[] input) returns(address[] output)
func (slicer *Slicer) PackEchoAddresses(input []common.Address) []byte {
@ -63,6 +64,15 @@ func (slicer *Slicer) PackEchoAddresses(input []common.Address) []byte {
return enc
}
// TryPackEchoAddresses is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xbe1127a3. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function echoAddresses(address[] input) returns(address[] output)
func (slicer *Slicer) TryPackEchoAddresses(input []common.Address) ([]byte, error) {
return slicer.abi.Pack("echoAddresses", input)
}
// UnpackEchoAddresses is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0xbe1127a3.
//
@ -73,11 +83,12 @@ func (slicer *Slicer) UnpackEchoAddresses(data []byte) ([]common.Address, error)
return *new([]common.Address), err
}
out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address)
return out0, err
return out0, nil
}
// PackEchoBools is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xf637e589.
// the contract method with ID 0xf637e589. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function echoBools(bool[] input) returns(bool[] output)
func (slicer *Slicer) PackEchoBools(input []bool) []byte {
@ -88,6 +99,15 @@ func (slicer *Slicer) PackEchoBools(input []bool) []byte {
return enc
}
// TryPackEchoBools is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xf637e589. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function echoBools(bool[] input) returns(bool[] output)
func (slicer *Slicer) TryPackEchoBools(input []bool) ([]byte, error) {
return slicer.abi.Pack("echoBools", input)
}
// UnpackEchoBools is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0xf637e589.
//
@ -98,11 +118,12 @@ func (slicer *Slicer) UnpackEchoBools(data []byte) ([]bool, error) {
return *new([]bool), err
}
out0 := *abi.ConvertType(out[0], new([]bool)).(*[]bool)
return out0, err
return out0, nil
}
// PackEchoFancyInts is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xd88becc0.
// the contract method with ID 0xd88becc0. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function echoFancyInts(uint24[23] input) returns(uint24[23] output)
func (slicer *Slicer) PackEchoFancyInts(input [23]*big.Int) []byte {
@ -113,6 +134,15 @@ func (slicer *Slicer) PackEchoFancyInts(input [23]*big.Int) []byte {
return enc
}
// TryPackEchoFancyInts is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xd88becc0. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function echoFancyInts(uint24[23] input) returns(uint24[23] output)
func (slicer *Slicer) TryPackEchoFancyInts(input [23]*big.Int) ([]byte, error) {
return slicer.abi.Pack("echoFancyInts", input)
}
// UnpackEchoFancyInts is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0xd88becc0.
//
@ -123,11 +153,12 @@ func (slicer *Slicer) UnpackEchoFancyInts(data []byte) ([23]*big.Int, error) {
return *new([23]*big.Int), err
}
out0 := *abi.ConvertType(out[0], new([23]*big.Int)).(*[23]*big.Int)
return out0, err
return out0, nil
}
// PackEchoInts is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xe15a3db7.
// the contract method with ID 0xe15a3db7. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function echoInts(int256[] input) returns(int256[] output)
func (slicer *Slicer) PackEchoInts(input []*big.Int) []byte {
@ -138,6 +169,15 @@ func (slicer *Slicer) PackEchoInts(input []*big.Int) []byte {
return enc
}
// TryPackEchoInts is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xe15a3db7. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function echoInts(int256[] input) returns(int256[] output)
func (slicer *Slicer) TryPackEchoInts(input []*big.Int) ([]byte, error) {
return slicer.abi.Pack("echoInts", input)
}
// UnpackEchoInts is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0xe15a3db7.
//
@ -148,5 +188,5 @@ func (slicer *Slicer) UnpackEchoInts(data []byte) ([]*big.Int, error) {
return *new([]*big.Int), err
}
out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int)
return out0, err
return out0, nil
}

View file

@ -57,7 +57,8 @@ func (c *Structs) Instance(backend bind.ContractBackend, addr common.Address) *b
}
// PackF is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x28811f59.
// the contract method with ID 0x28811f59. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function F() view returns((bytes32)[] a, uint256[] c, bool[] d)
func (structs *Structs) PackF() []byte {
@ -68,6 +69,15 @@ func (structs *Structs) PackF() []byte {
return enc
}
// TryPackF is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x28811f59. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function F() view returns((bytes32)[] a, uint256[] c, bool[] d)
func (structs *Structs) TryPackF() ([]byte, error) {
return structs.abi.Pack("F")
}
// FOutput serves as a container for the return parameters of contract
// method F.
type FOutput struct {
@ -89,12 +99,12 @@ func (structs *Structs) UnpackF(data []byte) (FOutput, error) {
outstruct.A = *abi.ConvertType(out[0], new([]Struct0)).(*[]Struct0)
outstruct.C = *abi.ConvertType(out[1], new([]*big.Int)).(*[]*big.Int)
outstruct.D = *abi.ConvertType(out[2], new([]bool)).(*[]bool)
return *outstruct, err
return *outstruct, nil
}
// PackG is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x6fecb623.
// the contract method with ID 0x6fecb623. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function G() view returns((bytes32)[] a)
func (structs *Structs) PackG() []byte {
@ -105,6 +115,15 @@ func (structs *Structs) PackG() []byte {
return enc
}
// TryPackG is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x6fecb623. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function G() view returns((bytes32)[] a)
func (structs *Structs) TryPackG() ([]byte, error) {
return structs.abi.Pack("G")
}
// UnpackG is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x6fecb623.
//
@ -115,5 +134,5 @@ func (structs *Structs) UnpackG(data []byte) ([]Struct0, error) {
return *new([]Struct0), err
}
out0 := *abi.ConvertType(out[0], new([]Struct0)).(*[]Struct0)
return out0, err
return out0, nil
}

View file

@ -64,7 +64,8 @@ func (token *Token) PackConstructor(initialSupply *big.Int, tokenName string, de
}
// PackAllowance is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xdd62ed3e.
// the contract method with ID 0xdd62ed3e. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function allowance(address , address ) returns(uint256)
func (token *Token) PackAllowance(arg0 common.Address, arg1 common.Address) []byte {
@ -75,6 +76,15 @@ func (token *Token) PackAllowance(arg0 common.Address, arg1 common.Address) []by
return enc
}
// TryPackAllowance is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xdd62ed3e. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function allowance(address , address ) returns(uint256)
func (token *Token) TryPackAllowance(arg0 common.Address, arg1 common.Address) ([]byte, error) {
return token.abi.Pack("allowance", arg0, arg1)
}
// UnpackAllowance is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0xdd62ed3e.
//
@ -85,11 +95,12 @@ func (token *Token) UnpackAllowance(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// PackApproveAndCall is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xcae9ca51.
// the contract method with ID 0xcae9ca51. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns(bool success)
func (token *Token) PackApproveAndCall(spender common.Address, value *big.Int, extraData []byte) []byte {
@ -100,6 +111,15 @@ func (token *Token) PackApproveAndCall(spender common.Address, value *big.Int, e
return enc
}
// TryPackApproveAndCall is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xcae9ca51. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns(bool success)
func (token *Token) TryPackApproveAndCall(spender common.Address, value *big.Int, extraData []byte) ([]byte, error) {
return token.abi.Pack("approveAndCall", spender, value, extraData)
}
// UnpackApproveAndCall is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0xcae9ca51.
//
@ -110,11 +130,12 @@ func (token *Token) UnpackApproveAndCall(data []byte) (bool, error) {
return *new(bool), err
}
out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
return out0, err
return out0, nil
}
// PackBalanceOf is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x70a08231.
// the contract method with ID 0x70a08231. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function balanceOf(address ) returns(uint256)
func (token *Token) PackBalanceOf(arg0 common.Address) []byte {
@ -125,6 +146,15 @@ func (token *Token) PackBalanceOf(arg0 common.Address) []byte {
return enc
}
// TryPackBalanceOf is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x70a08231. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function balanceOf(address ) returns(uint256)
func (token *Token) TryPackBalanceOf(arg0 common.Address) ([]byte, error) {
return token.abi.Pack("balanceOf", arg0)
}
// UnpackBalanceOf is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x70a08231.
//
@ -135,11 +165,12 @@ func (token *Token) UnpackBalanceOf(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// PackDecimals is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x313ce567.
// the contract method with ID 0x313ce567. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function decimals() returns(uint8)
func (token *Token) PackDecimals() []byte {
@ -150,6 +181,15 @@ func (token *Token) PackDecimals() []byte {
return enc
}
// TryPackDecimals is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x313ce567. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function decimals() returns(uint8)
func (token *Token) TryPackDecimals() ([]byte, error) {
return token.abi.Pack("decimals")
}
// UnpackDecimals is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x313ce567.
//
@ -160,11 +200,12 @@ func (token *Token) UnpackDecimals(data []byte) (uint8, error) {
return *new(uint8), err
}
out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
return out0, err
return out0, nil
}
// PackName is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x06fdde03.
// the contract method with ID 0x06fdde03. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function name() returns(string)
func (token *Token) PackName() []byte {
@ -175,6 +216,15 @@ func (token *Token) PackName() []byte {
return enc
}
// TryPackName is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x06fdde03. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function name() returns(string)
func (token *Token) TryPackName() ([]byte, error) {
return token.abi.Pack("name")
}
// UnpackName is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x06fdde03.
//
@ -185,11 +235,12 @@ func (token *Token) UnpackName(data []byte) (string, error) {
return *new(string), err
}
out0 := *abi.ConvertType(out[0], new(string)).(*string)
return out0, err
return out0, nil
}
// PackSpentAllowance is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xdc3080f2.
// the contract method with ID 0xdc3080f2. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function spentAllowance(address , address ) returns(uint256)
func (token *Token) PackSpentAllowance(arg0 common.Address, arg1 common.Address) []byte {
@ -200,6 +251,15 @@ func (token *Token) PackSpentAllowance(arg0 common.Address, arg1 common.Address)
return enc
}
// TryPackSpentAllowance is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xdc3080f2. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function spentAllowance(address , address ) returns(uint256)
func (token *Token) TryPackSpentAllowance(arg0 common.Address, arg1 common.Address) ([]byte, error) {
return token.abi.Pack("spentAllowance", arg0, arg1)
}
// UnpackSpentAllowance is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0xdc3080f2.
//
@ -210,11 +270,12 @@ func (token *Token) UnpackSpentAllowance(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// PackSymbol is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x95d89b41.
// the contract method with ID 0x95d89b41. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function symbol() returns(string)
func (token *Token) PackSymbol() []byte {
@ -225,6 +286,15 @@ func (token *Token) PackSymbol() []byte {
return enc
}
// TryPackSymbol is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x95d89b41. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function symbol() returns(string)
func (token *Token) TryPackSymbol() ([]byte, error) {
return token.abi.Pack("symbol")
}
// UnpackSymbol is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x95d89b41.
//
@ -235,11 +305,12 @@ func (token *Token) UnpackSymbol(data []byte) (string, error) {
return *new(string), err
}
out0 := *abi.ConvertType(out[0], new(string)).(*string)
return out0, err
return out0, nil
}
// PackTransfer is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xa9059cbb.
// the contract method with ID 0xa9059cbb. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function transfer(address _to, uint256 _value) returns()
func (token *Token) PackTransfer(to common.Address, value *big.Int) []byte {
@ -250,8 +321,18 @@ func (token *Token) PackTransfer(to common.Address, value *big.Int) []byte {
return enc
}
// TryPackTransfer is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xa9059cbb. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function transfer(address _to, uint256 _value) returns()
func (token *Token) TryPackTransfer(to common.Address, value *big.Int) ([]byte, error) {
return token.abi.Pack("transfer", to, value)
}
// PackTransferFrom is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x23b872dd.
// the contract method with ID 0x23b872dd. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function transferFrom(address _from, address _to, uint256 _value) returns(bool success)
func (token *Token) PackTransferFrom(from common.Address, to common.Address, value *big.Int) []byte {
@ -262,6 +343,15 @@ func (token *Token) PackTransferFrom(from common.Address, to common.Address, val
return enc
}
// TryPackTransferFrom is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x23b872dd. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function transferFrom(address _from, address _to, uint256 _value) returns(bool success)
func (token *Token) TryPackTransferFrom(from common.Address, to common.Address, value *big.Int) ([]byte, error) {
return token.abi.Pack("transferFrom", from, to, value)
}
// UnpackTransferFrom is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x23b872dd.
//
@ -272,7 +362,7 @@ func (token *Token) UnpackTransferFrom(data []byte) (bool, error) {
return *new(bool), err
}
out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
return out0, err
return out0, nil
}
// TokenTransfer represents a Transfer event raised by the Token contract.

View file

@ -77,7 +77,8 @@ func (c *Tuple) Instance(backend bind.ContractBackend, addr common.Address) *bin
}
// PackFunc1 is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x443c79b4.
// the contract method with ID 0x443c79b4. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function func1((uint256,uint256[],(uint256,uint256)[]) a, (uint256,uint256)[2][] b, (uint256,uint256)[][2] c, (uint256,uint256[],(uint256,uint256)[])[] d, uint256[] e) pure returns((uint256,uint256[],(uint256,uint256)[]), (uint256,uint256)[2][], (uint256,uint256)[][2], (uint256,uint256[],(uint256,uint256)[])[], uint256[])
func (tuple *Tuple) PackFunc1(a TupleS, b [][2]TupleT, c [2][]TupleT, d []TupleS, e []*big.Int) []byte {
@ -88,6 +89,15 @@ func (tuple *Tuple) PackFunc1(a TupleS, b [][2]TupleT, c [2][]TupleT, d []TupleS
return enc
}
// TryPackFunc1 is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x443c79b4. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function func1((uint256,uint256[],(uint256,uint256)[]) a, (uint256,uint256)[2][] b, (uint256,uint256)[][2] c, (uint256,uint256[],(uint256,uint256)[])[] d, uint256[] e) pure returns((uint256,uint256[],(uint256,uint256)[]), (uint256,uint256)[2][], (uint256,uint256)[][2], (uint256,uint256[],(uint256,uint256)[])[], uint256[])
func (tuple *Tuple) TryPackFunc1(a TupleS, b [][2]TupleT, c [2][]TupleT, d []TupleS, e []*big.Int) ([]byte, error) {
return tuple.abi.Pack("func1", a, b, c, d, e)
}
// Func1Output serves as a container for the return parameters of contract
// method Func1.
type Func1Output struct {
@ -113,12 +123,12 @@ func (tuple *Tuple) UnpackFunc1(data []byte) (Func1Output, error) {
outstruct.Arg2 = *abi.ConvertType(out[2], new([2][]TupleT)).(*[2][]TupleT)
outstruct.Arg3 = *abi.ConvertType(out[3], new([]TupleS)).(*[]TupleS)
outstruct.Arg4 = *abi.ConvertType(out[4], new([]*big.Int)).(*[]*big.Int)
return *outstruct, err
return *outstruct, nil
}
// PackFunc2 is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xd0062cdd.
// the contract method with ID 0xd0062cdd. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function func2((uint256,uint256[],(uint256,uint256)[]) a, (uint256,uint256)[2][] b, (uint256,uint256)[][2] c, (uint256,uint256[],(uint256,uint256)[])[] d, uint256[] e) returns()
func (tuple *Tuple) PackFunc2(a TupleS, b [][2]TupleT, c [2][]TupleT, d []TupleS, e []*big.Int) []byte {
@ -129,8 +139,18 @@ func (tuple *Tuple) PackFunc2(a TupleS, b [][2]TupleT, c [2][]TupleT, d []TupleS
return enc
}
// TryPackFunc2 is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xd0062cdd. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function func2((uint256,uint256[],(uint256,uint256)[]) a, (uint256,uint256)[2][] b, (uint256,uint256)[][2] c, (uint256,uint256[],(uint256,uint256)[])[] d, uint256[] e) returns()
func (tuple *Tuple) TryPackFunc2(a TupleS, b [][2]TupleT, c [2][]TupleT, d []TupleS, e []*big.Int) ([]byte, error) {
return tuple.abi.Pack("func2", a, b, c, d, e)
}
// PackFunc3 is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xe4d9a43b.
// the contract method with ID 0xe4d9a43b. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function func3((uint16,uint16)[] ) pure returns()
func (tuple *Tuple) PackFunc3(arg0 []TupleQ) []byte {
@ -141,6 +161,15 @@ func (tuple *Tuple) PackFunc3(arg0 []TupleQ) []byte {
return enc
}
// TryPackFunc3 is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xe4d9a43b. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function func3((uint16,uint16)[] ) pure returns()
func (tuple *Tuple) TryPackFunc3(arg0 []TupleQ) ([]byte, error) {
return tuple.abi.Pack("func3", arg0)
}
// TupleTupleEvent represents a TupleEvent event raised by the Tuple contract.
type TupleTupleEvent struct {
A TupleS

View file

@ -52,7 +52,8 @@ func (c *Tupler) Instance(backend bind.ContractBackend, addr common.Address) *bi
}
// PackTuple is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x3175aae2.
// the contract method with ID 0x3175aae2. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function tuple() returns(string a, int256 b, bytes32 c)
func (tupler *Tupler) PackTuple() []byte {
@ -63,6 +64,15 @@ func (tupler *Tupler) PackTuple() []byte {
return enc
}
// TryPackTuple is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x3175aae2. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function tuple() returns(string a, int256 b, bytes32 c)
func (tupler *Tupler) TryPackTuple() ([]byte, error) {
return tupler.abi.Pack("tuple")
}
// TupleOutput serves as a container for the return parameters of contract
// method Tuple.
type TupleOutput struct {
@ -84,6 +94,5 @@ func (tupler *Tupler) UnpackTuple(data []byte) (TupleOutput, error) {
outstruct.A = *abi.ConvertType(out[0], new(string)).(*string)
outstruct.B = abi.ConvertType(out[1], new(big.Int)).(*big.Int)
outstruct.C = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte)
return *outstruct, err
return *outstruct, nil
}

View file

@ -52,7 +52,8 @@ func (c *Underscorer) Instance(backend bind.ContractBackend, addr common.Address
}
// PackAllPurelyUnderscoredOutput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xb564b34d.
// the contract method with ID 0xb564b34d. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function AllPurelyUnderscoredOutput() view returns(int256 _, int256 __)
func (underscorer *Underscorer) PackAllPurelyUnderscoredOutput() []byte {
@ -63,6 +64,15 @@ func (underscorer *Underscorer) PackAllPurelyUnderscoredOutput() []byte {
return enc
}
// TryPackAllPurelyUnderscoredOutput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xb564b34d. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function AllPurelyUnderscoredOutput() view returns(int256 _, int256 __)
func (underscorer *Underscorer) TryPackAllPurelyUnderscoredOutput() ([]byte, error) {
return underscorer.abi.Pack("AllPurelyUnderscoredOutput")
}
// AllPurelyUnderscoredOutputOutput serves as a container for the return parameters of contract
// method AllPurelyUnderscoredOutput.
type AllPurelyUnderscoredOutputOutput struct {
@ -82,12 +92,12 @@ func (underscorer *Underscorer) UnpackAllPurelyUnderscoredOutput(data []byte) (A
}
outstruct.Arg0 = abi.ConvertType(out[0], new(big.Int)).(*big.Int)
outstruct.Arg1 = abi.ConvertType(out[1], new(big.Int)).(*big.Int)
return *outstruct, err
return *outstruct, nil
}
// PackLowerLowerCollision is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xe409ca45.
// the contract method with ID 0xe409ca45. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function LowerLowerCollision() view returns(int256 _res, int256 res)
func (underscorer *Underscorer) PackLowerLowerCollision() []byte {
@ -98,6 +108,15 @@ func (underscorer *Underscorer) PackLowerLowerCollision() []byte {
return enc
}
// TryPackLowerLowerCollision is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xe409ca45. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function LowerLowerCollision() view returns(int256 _res, int256 res)
func (underscorer *Underscorer) TryPackLowerLowerCollision() ([]byte, error) {
return underscorer.abi.Pack("LowerLowerCollision")
}
// LowerLowerCollisionOutput serves as a container for the return parameters of contract
// method LowerLowerCollision.
type LowerLowerCollisionOutput struct {
@ -117,12 +136,12 @@ func (underscorer *Underscorer) UnpackLowerLowerCollision(data []byte) (LowerLow
}
outstruct.Res = abi.ConvertType(out[0], new(big.Int)).(*big.Int)
outstruct.Res0 = abi.ConvertType(out[1], new(big.Int)).(*big.Int)
return *outstruct, err
return *outstruct, nil
}
// PackLowerUpperCollision is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x03a59213.
// the contract method with ID 0x03a59213. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function LowerUpperCollision() view returns(int256 _res, int256 Res)
func (underscorer *Underscorer) PackLowerUpperCollision() []byte {
@ -133,6 +152,15 @@ func (underscorer *Underscorer) PackLowerUpperCollision() []byte {
return enc
}
// TryPackLowerUpperCollision is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x03a59213. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function LowerUpperCollision() view returns(int256 _res, int256 Res)
func (underscorer *Underscorer) TryPackLowerUpperCollision() ([]byte, error) {
return underscorer.abi.Pack("LowerUpperCollision")
}
// LowerUpperCollisionOutput serves as a container for the return parameters of contract
// method LowerUpperCollision.
type LowerUpperCollisionOutput struct {
@ -152,12 +180,12 @@ func (underscorer *Underscorer) UnpackLowerUpperCollision(data []byte) (LowerUpp
}
outstruct.Res = abi.ConvertType(out[0], new(big.Int)).(*big.Int)
outstruct.Res0 = abi.ConvertType(out[1], new(big.Int)).(*big.Int)
return *outstruct, err
return *outstruct, nil
}
// PackPurelyUnderscoredOutput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x9df48485.
// the contract method with ID 0x9df48485. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function PurelyUnderscoredOutput() view returns(int256 _, int256 res)
func (underscorer *Underscorer) PackPurelyUnderscoredOutput() []byte {
@ -168,6 +196,15 @@ func (underscorer *Underscorer) PackPurelyUnderscoredOutput() []byte {
return enc
}
// TryPackPurelyUnderscoredOutput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x9df48485. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function PurelyUnderscoredOutput() view returns(int256 _, int256 res)
func (underscorer *Underscorer) TryPackPurelyUnderscoredOutput() ([]byte, error) {
return underscorer.abi.Pack("PurelyUnderscoredOutput")
}
// PurelyUnderscoredOutputOutput serves as a container for the return parameters of contract
// method PurelyUnderscoredOutput.
type PurelyUnderscoredOutputOutput struct {
@ -187,12 +224,12 @@ func (underscorer *Underscorer) UnpackPurelyUnderscoredOutput(data []byte) (Pure
}
outstruct.Arg0 = abi.ConvertType(out[0], new(big.Int)).(*big.Int)
outstruct.Res = abi.ConvertType(out[1], new(big.Int)).(*big.Int)
return *outstruct, err
return *outstruct, nil
}
// PackUnderscoredOutput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x67e6633d.
// the contract method with ID 0x67e6633d. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function UnderscoredOutput() view returns(int256 _int, string _string)
func (underscorer *Underscorer) PackUnderscoredOutput() []byte {
@ -203,6 +240,15 @@ func (underscorer *Underscorer) PackUnderscoredOutput() []byte {
return enc
}
// TryPackUnderscoredOutput is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x67e6633d. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function UnderscoredOutput() view returns(int256 _int, string _string)
func (underscorer *Underscorer) TryPackUnderscoredOutput() ([]byte, error) {
return underscorer.abi.Pack("UnderscoredOutput")
}
// UnderscoredOutputOutput serves as a container for the return parameters of contract
// method UnderscoredOutput.
type UnderscoredOutputOutput struct {
@ -222,12 +268,12 @@ func (underscorer *Underscorer) UnpackUnderscoredOutput(data []byte) (Underscore
}
outstruct.Int = abi.ConvertType(out[0], new(big.Int)).(*big.Int)
outstruct.String = *abi.ConvertType(out[1], new(string)).(*string)
return *outstruct, err
return *outstruct, nil
}
// PackUpperLowerCollision is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xaf7486ab.
// the contract method with ID 0xaf7486ab. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function UpperLowerCollision() view returns(int256 _Res, int256 res)
func (underscorer *Underscorer) PackUpperLowerCollision() []byte {
@ -238,6 +284,15 @@ func (underscorer *Underscorer) PackUpperLowerCollision() []byte {
return enc
}
// TryPackUpperLowerCollision is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xaf7486ab. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function UpperLowerCollision() view returns(int256 _Res, int256 res)
func (underscorer *Underscorer) TryPackUpperLowerCollision() ([]byte, error) {
return underscorer.abi.Pack("UpperLowerCollision")
}
// UpperLowerCollisionOutput serves as a container for the return parameters of contract
// method UpperLowerCollision.
type UpperLowerCollisionOutput struct {
@ -257,12 +312,12 @@ func (underscorer *Underscorer) UnpackUpperLowerCollision(data []byte) (UpperLow
}
outstruct.Res = abi.ConvertType(out[0], new(big.Int)).(*big.Int)
outstruct.Res0 = abi.ConvertType(out[1], new(big.Int)).(*big.Int)
return *outstruct, err
return *outstruct, nil
}
// PackUpperUpperCollision is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xe02ab24d.
// the contract method with ID 0xe02ab24d. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function UpperUpperCollision() view returns(int256 _Res, int256 Res)
func (underscorer *Underscorer) PackUpperUpperCollision() []byte {
@ -273,6 +328,15 @@ func (underscorer *Underscorer) PackUpperUpperCollision() []byte {
return enc
}
// TryPackUpperUpperCollision is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xe02ab24d. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function UpperUpperCollision() view returns(int256 _Res, int256 Res)
func (underscorer *Underscorer) TryPackUpperUpperCollision() ([]byte, error) {
return underscorer.abi.Pack("UpperUpperCollision")
}
// UpperUpperCollisionOutput serves as a container for the return parameters of contract
// method UpperUpperCollision.
type UpperUpperCollisionOutput struct {
@ -292,12 +356,12 @@ func (underscorer *Underscorer) UnpackUpperUpperCollision(data []byte) (UpperUpp
}
outstruct.Res = abi.ConvertType(out[0], new(big.Int)).(*big.Int)
outstruct.Res0 = abi.ConvertType(out[1], new(big.Int)).(*big.Int)
return *outstruct, err
return *outstruct, nil
}
// PackUnderScoredFunc is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x46546dbe.
// the contract method with ID 0x46546dbe. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function _under_scored_func() view returns(int256 _int)
func (underscorer *Underscorer) PackUnderScoredFunc() []byte {
@ -308,6 +372,15 @@ func (underscorer *Underscorer) PackUnderScoredFunc() []byte {
return enc
}
// TryPackUnderScoredFunc is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x46546dbe. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function _under_scored_func() view returns(int256 _int)
func (underscorer *Underscorer) TryPackUnderScoredFunc() ([]byte, error) {
return underscorer.abi.Pack("_under_scored_func")
}
// UnpackUnderScoredFunc is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x46546dbe.
//
@ -318,5 +391,5 @@ func (underscorer *Underscorer) UnpackUnderScoredFunc(data []byte) (*big.Int, er
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}

View file

@ -59,7 +59,8 @@ func (c *DB) Instance(backend bind.ContractBackend, addr common.Address) *bind.B
}
// PackGet is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x9507d39a.
// the contract method with ID 0x9507d39a. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function get(uint256 k) returns(uint256)
func (dB *DB) PackGet(k *big.Int) []byte {
@ -70,6 +71,15 @@ func (dB *DB) PackGet(k *big.Int) []byte {
return enc
}
// TryPackGet is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x9507d39a. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function get(uint256 k) returns(uint256)
func (dB *DB) TryPackGet(k *big.Int) ([]byte, error) {
return dB.abi.Pack("get", k)
}
// UnpackGet is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x9507d39a.
//
@ -80,11 +90,12 @@ func (dB *DB) UnpackGet(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// PackGetNamedStatParams is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xe369ba3b.
// the contract method with ID 0xe369ba3b. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function getNamedStatParams() view returns(uint256 gets, uint256 inserts, uint256 mods)
func (dB *DB) PackGetNamedStatParams() []byte {
@ -95,6 +106,15 @@ func (dB *DB) PackGetNamedStatParams() []byte {
return enc
}
// TryPackGetNamedStatParams is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xe369ba3b. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function getNamedStatParams() view returns(uint256 gets, uint256 inserts, uint256 mods)
func (dB *DB) TryPackGetNamedStatParams() ([]byte, error) {
return dB.abi.Pack("getNamedStatParams")
}
// GetNamedStatParamsOutput serves as a container for the return parameters of contract
// method GetNamedStatParams.
type GetNamedStatParamsOutput struct {
@ -116,12 +136,12 @@ func (dB *DB) UnpackGetNamedStatParams(data []byte) (GetNamedStatParamsOutput, e
outstruct.Gets = abi.ConvertType(out[0], new(big.Int)).(*big.Int)
outstruct.Inserts = abi.ConvertType(out[1], new(big.Int)).(*big.Int)
outstruct.Mods = abi.ConvertType(out[2], new(big.Int)).(*big.Int)
return *outstruct, err
return *outstruct, nil
}
// PackGetStatParams is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x6fcb9c70.
// the contract method with ID 0x6fcb9c70. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function getStatParams() view returns(uint256, uint256, uint256)
func (dB *DB) PackGetStatParams() []byte {
@ -132,6 +152,15 @@ func (dB *DB) PackGetStatParams() []byte {
return enc
}
// TryPackGetStatParams is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x6fcb9c70. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function getStatParams() view returns(uint256, uint256, uint256)
func (dB *DB) TryPackGetStatParams() ([]byte, error) {
return dB.abi.Pack("getStatParams")
}
// GetStatParamsOutput serves as a container for the return parameters of contract
// method GetStatParams.
type GetStatParamsOutput struct {
@ -153,12 +182,12 @@ func (dB *DB) UnpackGetStatParams(data []byte) (GetStatParamsOutput, error) {
outstruct.Arg0 = abi.ConvertType(out[0], new(big.Int)).(*big.Int)
outstruct.Arg1 = abi.ConvertType(out[1], new(big.Int)).(*big.Int)
outstruct.Arg2 = abi.ConvertType(out[2], new(big.Int)).(*big.Int)
return *outstruct, err
return *outstruct, nil
}
// PackGetStatsStruct is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xee8161e0.
// the contract method with ID 0xee8161e0. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function getStatsStruct() view returns((uint256,uint256,uint256))
func (dB *DB) PackGetStatsStruct() []byte {
@ -169,6 +198,15 @@ func (dB *DB) PackGetStatsStruct() []byte {
return enc
}
// TryPackGetStatsStruct is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xee8161e0. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function getStatsStruct() view returns((uint256,uint256,uint256))
func (dB *DB) TryPackGetStatsStruct() ([]byte, error) {
return dB.abi.Pack("getStatsStruct")
}
// UnpackGetStatsStruct is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0xee8161e0.
//
@ -179,11 +217,12 @@ func (dB *DB) UnpackGetStatsStruct(data []byte) (DBStats, error) {
return *new(DBStats), err
}
out0 := *abi.ConvertType(out[0], new(DBStats)).(*DBStats)
return out0, err
return out0, nil
}
// PackInsert is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x1d834a1b.
// the contract method with ID 0x1d834a1b. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function insert(uint256 k, uint256 v) returns(uint256)
func (dB *DB) PackInsert(k *big.Int, v *big.Int) []byte {
@ -194,6 +233,15 @@ func (dB *DB) PackInsert(k *big.Int, v *big.Int) []byte {
return enc
}
// TryPackInsert is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x1d834a1b. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function insert(uint256 k, uint256 v) returns(uint256)
func (dB *DB) TryPackInsert(k *big.Int, v *big.Int) ([]byte, error) {
return dB.abi.Pack("insert", k, v)
}
// UnpackInsert is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x1d834a1b.
//
@ -204,7 +252,7 @@ func (dB *DB) UnpackInsert(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// DBInsert represents a Insert event raised by the DB contract.

View file

@ -52,7 +52,8 @@ func (c *C) Instance(backend bind.ContractBackend, addr common.Address) *bind.Bo
}
// PackEmitMulti is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xcb493749.
// the contract method with ID 0xcb493749. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function EmitMulti() returns()
func (c *C) PackEmitMulti() []byte {
@ -63,8 +64,18 @@ func (c *C) PackEmitMulti() []byte {
return enc
}
// TryPackEmitMulti is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xcb493749. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function EmitMulti() returns()
func (c *C) TryPackEmitMulti() ([]byte, error) {
return c.abi.Pack("EmitMulti")
}
// PackEmitOne is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xe8e49a71.
// the contract method with ID 0xe8e49a71. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function EmitOne() returns()
func (c *C) PackEmitOne() []byte {
@ -75,6 +86,15 @@ func (c *C) PackEmitOne() []byte {
return enc
}
// TryPackEmitOne is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xe8e49a71. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function EmitOne() returns()
func (c *C) TryPackEmitOne() ([]byte, error) {
return c.abi.Pack("EmitOne")
}
// CBasic1 represents a basic1 event raised by the C contract.
type CBasic1 struct {
Id *big.Int

View file

@ -68,7 +68,8 @@ func (c1 *C1) PackConstructor(v1 *big.Int, v2 *big.Int) []byte {
}
// PackDo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2ad11272.
// the contract method with ID 0x2ad11272. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function Do(uint256 val) pure returns(uint256 res)
func (c1 *C1) PackDo(val *big.Int) []byte {
@ -79,6 +80,15 @@ func (c1 *C1) PackDo(val *big.Int) []byte {
return enc
}
// TryPackDo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2ad11272. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function Do(uint256 val) pure returns(uint256 res)
func (c1 *C1) TryPackDo(val *big.Int) ([]byte, error) {
return c1.abi.Pack("Do", val)
}
// UnpackDo is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x2ad11272.
//
@ -89,7 +99,7 @@ func (c1 *C1) UnpackDo(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// C2MetaData contains all meta data concerning the C2 contract.
@ -136,7 +146,8 @@ func (c2 *C2) PackConstructor(v1 *big.Int, v2 *big.Int) []byte {
}
// PackDo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2ad11272.
// the contract method with ID 0x2ad11272. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function Do(uint256 val) pure returns(uint256 res)
func (c2 *C2) PackDo(val *big.Int) []byte {
@ -147,6 +158,15 @@ func (c2 *C2) PackDo(val *big.Int) []byte {
return enc
}
// TryPackDo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2ad11272. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function Do(uint256 val) pure returns(uint256 res)
func (c2 *C2) TryPackDo(val *big.Int) ([]byte, error) {
return c2.abi.Pack("Do", val)
}
// UnpackDo is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x2ad11272.
//
@ -157,7 +177,7 @@ func (c2 *C2) UnpackDo(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// L1MetaData contains all meta data concerning the L1 contract.
@ -188,7 +208,8 @@ func (c *L1) Instance(backend bind.ContractBackend, addr common.Address) *bind.B
}
// PackDo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2ad11272.
// the contract method with ID 0x2ad11272. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function Do(uint256 val) pure returns(uint256)
func (l1 *L1) PackDo(val *big.Int) []byte {
@ -199,6 +220,15 @@ func (l1 *L1) PackDo(val *big.Int) []byte {
return enc
}
// TryPackDo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2ad11272. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function Do(uint256 val) pure returns(uint256)
func (l1 *L1) TryPackDo(val *big.Int) ([]byte, error) {
return l1.abi.Pack("Do", val)
}
// UnpackDo is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x2ad11272.
//
@ -209,7 +239,7 @@ func (l1 *L1) UnpackDo(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// L2MetaData contains all meta data concerning the L2 contract.
@ -243,7 +273,8 @@ func (c *L2) Instance(backend bind.ContractBackend, addr common.Address) *bind.B
}
// PackDo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2ad11272.
// the contract method with ID 0x2ad11272. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function Do(uint256 val) pure returns(uint256)
func (l2 *L2) PackDo(val *big.Int) []byte {
@ -254,6 +285,15 @@ func (l2 *L2) PackDo(val *big.Int) []byte {
return enc
}
// TryPackDo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2ad11272. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function Do(uint256 val) pure returns(uint256)
func (l2 *L2) TryPackDo(val *big.Int) ([]byte, error) {
return l2.abi.Pack("Do", val)
}
// UnpackDo is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x2ad11272.
//
@ -264,7 +304,7 @@ func (l2 *L2) UnpackDo(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// L2bMetaData contains all meta data concerning the L2b contract.
@ -298,7 +338,8 @@ func (c *L2b) Instance(backend bind.ContractBackend, addr common.Address) *bind.
}
// PackDo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2ad11272.
// the contract method with ID 0x2ad11272. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function Do(uint256 val) pure returns(uint256)
func (l2b *L2b) PackDo(val *big.Int) []byte {
@ -309,6 +350,15 @@ func (l2b *L2b) PackDo(val *big.Int) []byte {
return enc
}
// TryPackDo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2ad11272. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function Do(uint256 val) pure returns(uint256)
func (l2b *L2b) TryPackDo(val *big.Int) ([]byte, error) {
return l2b.abi.Pack("Do", val)
}
// UnpackDo is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x2ad11272.
//
@ -319,7 +369,7 @@ func (l2b *L2b) UnpackDo(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// L3MetaData contains all meta data concerning the L3 contract.
@ -350,7 +400,8 @@ func (c *L3) Instance(backend bind.ContractBackend, addr common.Address) *bind.B
}
// PackDo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2ad11272.
// the contract method with ID 0x2ad11272. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function Do(uint256 val) pure returns(uint256)
func (l3 *L3) PackDo(val *big.Int) []byte {
@ -361,6 +412,15 @@ func (l3 *L3) PackDo(val *big.Int) []byte {
return enc
}
// TryPackDo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2ad11272. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function Do(uint256 val) pure returns(uint256)
func (l3 *L3) TryPackDo(val *big.Int) ([]byte, error) {
return l3.abi.Pack("Do", val)
}
// UnpackDo is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x2ad11272.
//
@ -371,7 +431,7 @@ func (l3 *L3) UnpackDo(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// L4MetaData contains all meta data concerning the L4 contract.
@ -406,7 +466,8 @@ func (c *L4) Instance(backend bind.ContractBackend, addr common.Address) *bind.B
}
// PackDo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2ad11272.
// the contract method with ID 0x2ad11272. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function Do(uint256 val) pure returns(uint256)
func (l4 *L4) PackDo(val *big.Int) []byte {
@ -417,6 +478,15 @@ func (l4 *L4) PackDo(val *big.Int) []byte {
return enc
}
// TryPackDo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2ad11272. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function Do(uint256 val) pure returns(uint256)
func (l4 *L4) TryPackDo(val *big.Int) ([]byte, error) {
return l4.abi.Pack("Do", val)
}
// UnpackDo is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x2ad11272.
//
@ -427,7 +497,7 @@ func (l4 *L4) UnpackDo(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}
// L4bMetaData contains all meta data concerning the L4b contract.
@ -461,7 +531,8 @@ func (c *L4b) Instance(backend bind.ContractBackend, addr common.Address) *bind.
}
// PackDo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2ad11272.
// the contract method with ID 0x2ad11272. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function Do(uint256 val) pure returns(uint256)
func (l4b *L4b) PackDo(val *big.Int) []byte {
@ -472,6 +543,15 @@ func (l4b *L4b) PackDo(val *big.Int) []byte {
return enc
}
// TryPackDo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0x2ad11272. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function Do(uint256 val) pure returns(uint256)
func (l4b *L4b) TryPackDo(val *big.Int) ([]byte, error) {
return l4b.abi.Pack("Do", val)
}
// UnpackDo is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0x2ad11272.
//
@ -482,5 +562,5 @@ func (l4b *L4b) UnpackDo(data []byte) (*big.Int, error) {
return new(big.Int), err
}
out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int)
return out0, err
return out0, nil
}

View file

@ -52,7 +52,8 @@ func (c *C) Instance(backend bind.ContractBackend, addr common.Address) *bind.Bo
}
// PackBar is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xb0a378b0.
// the contract method with ID 0xb0a378b0. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function Bar() pure returns()
func (c *C) PackBar() []byte {
@ -63,8 +64,18 @@ func (c *C) PackBar() []byte {
return enc
}
// TryPackBar is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xb0a378b0. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function Bar() pure returns()
func (c *C) TryPackBar() ([]byte, error) {
return c.abi.Pack("Bar")
}
// PackFoo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xbfb4ebcf.
// the contract method with ID 0xbfb4ebcf. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function Foo() pure returns()
func (c *C) PackFoo() []byte {
@ -75,6 +86,15 @@ func (c *C) PackFoo() []byte {
return enc
}
// TryPackFoo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xbfb4ebcf. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function Foo() pure returns()
func (c *C) TryPackFoo() ([]byte, error) {
return c.abi.Pack("Foo")
}
// UnpackError attempts to decode the provided error data using user-defined
// error definitions.
func (c *C) UnpackError(raw []byte) (any, error) {
@ -169,7 +189,8 @@ func (c *C2) Instance(backend bind.ContractBackend, addr common.Address) *bind.B
}
// PackFoo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xbfb4ebcf.
// the contract method with ID 0xbfb4ebcf. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function Foo() pure returns()
func (c2 *C2) PackFoo() []byte {
@ -180,6 +201,15 @@ func (c2 *C2) PackFoo() []byte {
return enc
}
// TryPackFoo is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xbfb4ebcf. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function Foo() pure returns()
func (c2 *C2) TryPackFoo() ([]byte, error) {
return c2.abi.Pack("Foo")
}
// UnpackError attempts to decode the provided error data using user-defined
// error definitions.
func (c2 *C2) UnpackError(raw []byte) (any, error) {

View file

@ -52,7 +52,8 @@ func (c *MyContract) Instance(backend bind.ContractBackend, addr common.Address)
}
// PackGetNums is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xbd6d1007.
// the contract method with ID 0xbd6d1007. This method will panic if any
// invalid/nil inputs are passed.
//
// Solidity: function GetNums() pure returns(uint256[5])
func (myContract *MyContract) PackGetNums() []byte {
@ -63,6 +64,15 @@ func (myContract *MyContract) PackGetNums() []byte {
return enc
}
// TryPackGetNums is the Go binding used to pack the parameters required for calling
// the contract method with ID 0xbd6d1007. This method will return an error
// if any inputs are invalid/nil.
//
// Solidity: function GetNums() pure returns(uint256[5])
func (myContract *MyContract) TryPackGetNums() ([]byte, error) {
return myContract.abi.Pack("GetNums")
}
// UnpackGetNums is the Go binding that unpacks the parameters returned
// from invoking the contract method with ID 0xbd6d1007.
//
@ -73,5 +83,5 @@ func (myContract *MyContract) UnpackGetNums(data []byte) ([5]*big.Int, error) {
return *new([5]*big.Int), err
}
out0 := *abi.ConvertType(out[0], new([5]*big.Int)).(*[5]*big.Int)
return out0, err
return out0, nil
}

View file

@ -32,6 +32,7 @@ var (
errBadInt16 = errors.New("abi: improperly encoded int16 value")
errBadInt32 = errors.New("abi: improperly encoded int32 value")
errBadInt64 = errors.New("abi: improperly encoded int64 value")
errInvalidSign = errors.New("abi: negatively-signed value cannot be packed into uint parameter")
)
// formatSliceString formats the reflection kind with the given slice size

View file

@ -37,7 +37,16 @@ func packBytesSlice(bytes []byte, l int) []byte {
// t.
func packElement(t Type, reflectValue reflect.Value) ([]byte, error) {
switch t.T {
case IntTy, UintTy:
case UintTy:
// make sure to not pack a negative value into a uint type.
if reflectValue.Kind() == reflect.Ptr {
val := new(big.Int).Set(reflectValue.Interface().(*big.Int))
if val.Sign() == -1 {
return nil, errInvalidSign
}
}
return packNum(reflectValue), nil
case IntTy:
return packNum(reflectValue), nil
case StringTy:
return packBytesSlice([]byte(reflectValue.String()), reflectValue.Len()), nil

View file

@ -177,6 +177,11 @@ func TestMethodPack(t *testing.T) {
if !bytes.Equal(packed, sig) {
t.Errorf("expected %x got %x", sig, packed)
}
// test that we can't pack a negative value for a parameter that is specified as a uint
if _, err := abi.Pack("send", big.NewInt(-1)); err == nil {
t.Fatal("expected error when trying to pack negative big.Int into uint256 value")
}
}
func TestPackNumber(t *testing.T) {

View file

@ -1014,128 +1014,134 @@ func TestPackAndUnpackIncompatibleNumber(t *testing.T) {
cases := []struct {
decodeType string
inputValue *big.Int
err error
unpackErr error
packErr error
expectValue interface{}
}{
{
decodeType: "uint8",
inputValue: big.NewInt(math.MaxUint8 + 1),
err: errBadUint8,
unpackErr: errBadUint8,
},
{
decodeType: "uint8",
inputValue: big.NewInt(math.MaxUint8),
err: nil,
unpackErr: nil,
expectValue: uint8(math.MaxUint8),
},
{
decodeType: "uint16",
inputValue: big.NewInt(math.MaxUint16 + 1),
err: errBadUint16,
unpackErr: errBadUint16,
},
{
decodeType: "uint16",
inputValue: big.NewInt(math.MaxUint16),
err: nil,
unpackErr: nil,
expectValue: uint16(math.MaxUint16),
},
{
decodeType: "uint32",
inputValue: big.NewInt(math.MaxUint32 + 1),
err: errBadUint32,
unpackErr: errBadUint32,
},
{
decodeType: "uint32",
inputValue: big.NewInt(math.MaxUint32),
err: nil,
unpackErr: nil,
expectValue: uint32(math.MaxUint32),
},
{
decodeType: "uint64",
inputValue: maxU64Plus1,
err: errBadUint64,
unpackErr: errBadUint64,
},
{
decodeType: "uint64",
inputValue: maxU64,
err: nil,
unpackErr: nil,
expectValue: uint64(math.MaxUint64),
},
{
decodeType: "uint256",
inputValue: maxU64Plus1,
err: nil,
unpackErr: nil,
expectValue: maxU64Plus1,
},
{
decodeType: "int8",
inputValue: big.NewInt(math.MaxInt8 + 1),
err: errBadInt8,
unpackErr: errBadInt8,
},
{
decodeType: "int8",
inputValue: big.NewInt(math.MinInt8 - 1),
err: errBadInt8,
packErr: errInvalidSign,
},
{
decodeType: "int8",
inputValue: big.NewInt(math.MaxInt8),
err: nil,
unpackErr: nil,
expectValue: int8(math.MaxInt8),
},
{
decodeType: "int16",
inputValue: big.NewInt(math.MaxInt16 + 1),
err: errBadInt16,
unpackErr: errBadInt16,
},
{
decodeType: "int16",
inputValue: big.NewInt(math.MinInt16 - 1),
err: errBadInt16,
packErr: errInvalidSign,
},
{
decodeType: "int16",
inputValue: big.NewInt(math.MaxInt16),
err: nil,
unpackErr: nil,
expectValue: int16(math.MaxInt16),
},
{
decodeType: "int32",
inputValue: big.NewInt(math.MaxInt32 + 1),
err: errBadInt32,
unpackErr: errBadInt32,
},
{
decodeType: "int32",
inputValue: big.NewInt(math.MinInt32 - 1),
err: errBadInt32,
packErr: errInvalidSign,
},
{
decodeType: "int32",
inputValue: big.NewInt(math.MaxInt32),
err: nil,
unpackErr: nil,
expectValue: int32(math.MaxInt32),
},
{
decodeType: "int64",
inputValue: new(big.Int).Add(big.NewInt(math.MaxInt64), big.NewInt(1)),
err: errBadInt64,
unpackErr: errBadInt64,
},
{
decodeType: "int64",
inputValue: new(big.Int).Sub(big.NewInt(math.MinInt64), big.NewInt(1)),
err: errBadInt64,
packErr: errInvalidSign,
},
{
decodeType: "int64",
inputValue: big.NewInt(math.MaxInt64),
err: nil,
unpackErr: nil,
expectValue: int64(math.MaxInt64),
},
}
for i, testCase := range cases {
packed, err := encodeABI.Pack(testCase.inputValue)
if err != nil {
panic(err)
if testCase.packErr != nil {
if err == nil {
t.Fatalf("expected packing of testcase input value to fail")
}
if err != testCase.packErr {
t.Fatalf("expected error '%v', got '%v'", testCase.packErr, err)
}
continue
}
if err != nil && err != testCase.packErr {
panic(fmt.Errorf("unexpected error packing test-case input: %v", err))
}
ty, err := NewType(testCase.decodeType, "", nil)
if err != nil {
@ -1145,8 +1151,8 @@ func TestPackAndUnpackIncompatibleNumber(t *testing.T) {
{Type: ty},
}
decoded, err := decodeABI.Unpack(packed)
if err != testCase.err {
t.Fatalf("Expected error %v, actual error %v. case %d", testCase.err, err, i)
if err != testCase.unpackErr {
t.Fatalf("Expected error %v, actual error %v. case %d", testCase.unpackErr, err, i)
}
if err != nil {
continue

View file

@ -93,9 +93,6 @@ func NewManager(config *Config, backends ...Backend) *Manager {
// Close terminates the account manager's internal notification processes.
func (am *Manager) Close() error {
for _, w := range am.wallets {
w.Close()
}
errc := make(chan error)
am.quit <- errc
return <-errc
@ -149,6 +146,10 @@ func (am *Manager) update() {
am.lock.Unlock()
close(event.processed)
case errc := <-am.quit:
// Close all owned wallets
for _, w := range am.wallets {
w.Close()
}
// Manager terminating, return
errc <- nil
// Signals event emitters the loop is not receiving values

View file

@ -123,6 +123,11 @@ type BlobAndProofV1 struct {
Proof hexutil.Bytes `json:"proof"`
}
type BlobAndProofV2 struct {
Blob hexutil.Bytes `json:"blob"`
CellProofs []hexutil.Bytes `json:"proofs"`
}
// JSON type overrides for ExecutionPayloadEnvelope.
type executionPayloadEnvelopeMarshaling struct {
BlockValue *hexutil.Big
@ -331,7 +336,9 @@ func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars []*types.
for j := range sidecar.Blobs {
bundle.Blobs = append(bundle.Blobs, hexutil.Bytes(sidecar.Blobs[j][:]))
bundle.Commitments = append(bundle.Commitments, hexutil.Bytes(sidecar.Commitments[j][:]))
bundle.Proofs = append(bundle.Proofs, hexutil.Bytes(sidecar.Proofs[j][:]))
}
for _, proof := range sidecar.Proofs {
bundle.Proofs = append(bundle.Proofs, hexutil.Bytes(proof[:]))
}
}

View file

@ -0,0 +1,56 @@
// Copyright 2025 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum 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 go-ethereum 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 go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package engine
import (
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto/kzg4844"
)
func TestBlobs(t *testing.T) {
var (
emptyBlob = new(kzg4844.Blob)
emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob)
emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit)
emptyCellProof, _ = kzg4844.ComputeCellProofs(emptyBlob)
)
header := types.Header{}
block := types.NewBlock(&header, &types.Body{}, nil, nil)
sidecarWithoutCellProofs := &types.BlobTxSidecar{
Blobs: []kzg4844.Blob{*emptyBlob},
Commitments: []kzg4844.Commitment{emptyBlobCommit},
Proofs: []kzg4844.Proof{emptyBlobProof},
}
env := BlockToExecutableData(block, common.Big0, []*types.BlobTxSidecar{sidecarWithoutCellProofs}, nil)
if len(env.BlobsBundle.Proofs) != 1 {
t.Fatalf("Expect 1 proof in blobs bundle, got %v", len(env.BlobsBundle.Proofs))
}
sidecarWithCellProofs := &types.BlobTxSidecar{
Blobs: []kzg4844.Blob{*emptyBlob},
Commitments: []kzg4844.Commitment{emptyBlobCommit},
Proofs: emptyCellProof,
}
env = BlockToExecutableData(block, common.Big0, []*types.BlobTxSidecar{sidecarWithCellProofs}, nil)
if len(env.BlobsBundle.Proofs) != 128 {
t.Fatalf("Expect 128 proofs in blobs bundle, got %v", len(env.BlobsBundle.Proofs))
}
}

View file

@ -1,58 +1,58 @@
# This file contains sha256 checksums of optional build dependencies.
# version:spec-tests pectra-devnet-6@v1.0.0
# version:spec-tests v4.5.0
# https://github.com/ethereum/execution-spec-tests/releases
# https://github.com/ethereum/execution-spec-tests/releases/download/pectra-devnet-6%40v1.0.0/
b69211752a3029083c020dc635fe12156ca1a6725a08559da540a0337586a77e fixtures_pectra-devnet-6.tar.gz
# https://github.com/ethereum/execution-spec-tests/releases/download/v4.5.0/
58afb92a0075a2cb7c4dec1281f7cb88b21b02afbedad096b580f3f8cc14c54c fixtures_develop.tar.gz
# version:golang 1.24.3
# version:golang 1.24.4
# https://go.dev/dl/
229c08b600b1446798109fae1f569228102c8473caba8104b6418cb5bc032878 go1.24.3.src.tar.gz
6f6901497547db3b77c14f7f953fbcef9fa5fb84199ee2ee14a5686e66bed5a6 go1.24.3.aix-ppc64.tar.gz
a05fa7e4043a4fec66897135219e3b8ab2202b5ef351c60c2fbb531dfb8f2900 go1.24.3.darwin-amd64.pkg
13e6fe3fcf65689d77d40e633de1e31c6febbdbcb846eb05fc2434ed2213e92b go1.24.3.darwin-amd64.tar.gz
97055ff4214043b39dc32e043fdd5c565df7c0a4e2fc0174e779a134c347ae0e go1.24.3.darwin-arm64.pkg
64a3fa22142f627e78fac3018ce3d4aeace68b743eff0afda8aae0411df5e4fb go1.24.3.darwin-arm64.tar.gz
32de3fd44d5055973978436a7f1f0ffbaae85c1b603ec6105e5c38d8a674c721 go1.24.3.dragonfly-amd64.tar.gz
9fe6101b3797919bd7337ee5ce591954f85d59db7ae88983904db29fd64c3dd1 go1.24.3.freebsd-386.tar.gz
6ccf4cca287e90cc28cd7954b6172f5d177a17e20b072b65f7f39636c325e2fb go1.24.3.freebsd-amd64.tar.gz
ce45ebf389066f82a7b056b66dd650efb51fde6f8bf92a2a3ab6990f02788ebf go1.24.3.freebsd-arm.tar.gz
8f6494a12a874d0ea57c67987829359e016960ce3ba0673273609d6ac2af589a go1.24.3.freebsd-arm64.tar.gz
f9db392560cf0851f0bc8f2190e1978e01b4603038c27fecfc8658a695b71616 go1.24.3.freebsd-riscv64.tar.gz
01717fff64c5d98457272002fa825d0a15e307bf6e189f2b0c23817fa033b61c go1.24.3.illumos-amd64.tar.gz
41b1051063e68cbd2b919bf12326764fe33937cf1d32b5c529dd1a4f43dce578 go1.24.3.linux-386.tar.gz
3333f6ea53afa971e9078895eaa4ac7204a8c6b5c68c10e6bc9a33e8e391bdd8 go1.24.3.linux-amd64.tar.gz
a463cb59382bd7ae7d8f4c68846e73c4d589f223c589ac76871b66811ded7836 go1.24.3.linux-arm64.tar.gz
17a392d7e826625dd12a32099df0b00b85c32d8132ed86fe917183ee5c3f88ed go1.24.3.linux-armv6l.tar.gz
e4b003c04c902edc140153d279b42167f1ad7c229f48f1f729bbef5e65e88d1f go1.24.3.linux-loong64.tar.gz
1c79d89edf835edf9d4336ccea7cb89bc5c0ca82b12b36b218d599a5400d60fe go1.24.3.linux-mips.tar.gz
0b64fe147d69f4d681d8e8a035c760477531432f83d831f18d37cb9bf3652488 go1.24.3.linux-mips64.tar.gz
396b784c255b64512dc00c302c053e43a3cbfc77518664c6ac5569aafad4d1e6 go1.24.3.linux-mips64le.tar.gz
93898313887f14e8efbe9d7386d5da4792b2d6c492bee562993fd4c9daa75c6d go1.24.3.linux-mipsle.tar.gz
873ae3a6a6655a7b6f820e095d9965507e8dfd3cf76bc92d75c564ecbca385f6 go1.24.3.linux-ppc64.tar.gz
341a749d168f47b1d4dad25e32cae70849b7ceed7c290823b853c9e6b0df0856 go1.24.3.linux-ppc64le.tar.gz
fa482f53ccb4ba280316b8c5751ea67291507280d9166f2a38fe4d9b5d5fb64b go1.24.3.linux-riscv64.tar.gz
a87b0c2a079a0bece1620fb29a00e02b4dba17507850f837e754af7d57cda282 go1.24.3.linux-s390x.tar.gz
63155382308db1306200aff7821aa26bf2a2dda23537dd637a9704b485b6ddf0 go1.24.3.netbsd-386.tar.gz
fe2c5c79482958b867c08a4fc2a10a998de9c0206b08d5b3ebcb2232e8d2777c go1.24.3.netbsd-amd64.tar.gz
e8ff77aef21521b5dd94e44282a3243309b80717414cf12f72835a45886a049f go1.24.3.netbsd-arm.tar.gz
b337fbaf82822685940ffaa76fbcf4be5d2f0258bc819cd80bc408b491f45c04 go1.24.3.netbsd-arm64.tar.gz
c1bb9dd8418480aa7f65452b08de3759da3bf89702be71b5a9fc084836b24ad5 go1.24.3.openbsd-386.tar.gz
531218de748b0caaf6d1ad18921206fc12baaa89bf483a0a5e60a571c206fe6f go1.24.3.openbsd-amd64.tar.gz
bcd0dc959986fc346969b5d4111c3c8031882d8bf8d87a2c2ecf1328962a91f2 go1.24.3.openbsd-arm.tar.gz
00ee6f8f1c41fd2e28ad386bd7e39acce7cab84af6de835855b29d1c597335c4 go1.24.3.openbsd-arm64.tar.gz
9f4ec0a9203ed3c54ce1a2a390ad3d45838cdb7efd85baeff857e37dfde04edd go1.24.3.openbsd-ppc64.tar.gz
da4d6f80e2373250d8c31c32dcd1e08775c327c0d610923604660cc0e07e8cba go1.24.3.openbsd-riscv64.tar.gz
f5d02149132eedda6c2d46b360d7da462b8a5f9e3f8567db100c2d7bff0ddcd7 go1.24.3.plan9-386.tar.gz
175f3d79f4762a3c545d2c6393bf6b8bac24e838026869dafab06b930735c94f go1.24.3.plan9-amd64.tar.gz
d1e4ac15095da1611659261c2228c2058756cf87d61d9fad262f76755ef26849 go1.24.3.plan9-arm.tar.gz
e644220a6ced3c07a7acc1364193cb709a97737dd8b6792a07a8ec6d9996713e go1.24.3.solaris-amd64.tar.gz
0d7e7dc0a31ba0cdd487415709d03b02fc9490ef111e8dfd22788a6d63316f37 go1.24.3.windows-386.msi
c27c463a61ab849266baa0c17a6c5c4256a574ab642f609ba25c96ec965dc184 go1.24.3.windows-386.zip
d5b7637e7e138be877d96a4501709d480e050d86a8f402bc950e72112b5aedc5 go1.24.3.windows-amd64.msi
be9787cb08998b1860fe3513e48a5fe5b96302d358a321b58e651184fa9638b3 go1.24.3.windows-amd64.zip
7efde2e5e8468e9caf2c7fc94f4da78a726a5031a1ed63acff7899527cdddff6 go1.24.3.windows-arm64.msi
eec9fa736056b54dd88ecb669db2bfad39b0c48f6f9080f036dfa1ca42dc4bb5 go1.24.3.windows-arm64.zip
5a86a83a31f9fa81490b8c5420ac384fd3d95a3e71fba665c7b3f95d1dfef2b4 go1.24.4.src.tar.gz
0d2af78e3b6e08f8013dbbdb26ae33052697b6b72e03ec17d496739c2a1aed68 go1.24.4.aix-ppc64.tar.gz
69bef555e114b4a2252452b6e7049afc31fbdf2d39790b669165e89525cd3f5c go1.24.4.darwin-amd64.tar.gz
c4d74453a26f488bdb4b0294da4840d9020806de4661785334eb6d1803ee5c27 go1.24.4.darwin-amd64.pkg
27973684b515eaf461065054e6b572d9390c05e69ba4a423076c160165336470 go1.24.4.darwin-arm64.tar.gz
2fe1f8746745c4bfebd494583aaef24cad42594f6d25ed67856879d567ee66e7 go1.24.4.darwin-arm64.pkg
70b2de9c1cafe5af7be3eb8f80753cce0501ef300db3f3bd59be7ccc464234e1 go1.24.4.dragonfly-amd64.tar.gz
8d529839db29ee171505b89dc9c3de76003a4ab56202d84bddbbecacbfb6d7c9 go1.24.4.freebsd-386.tar.gz
6cbc3ad6cc21bdcc7283824d3ac0e85512c02022f6a35eb2e844882ea6e8448c go1.24.4.freebsd-amd64.tar.gz
d49ae050c20aff646a7641dd903f03eb674570790b90ffb298076c4d41e36655 go1.24.4.freebsd-arm.tar.gz
e31924abef2a28456b7103c0a5d333dcc11ecf19e76d5de1a383ad5fe0b42457 go1.24.4.freebsd-arm64.tar.gz
b5bca135eae8ebddf22972611ac1c58ae9fbb5979fd953cc5245c5b1b2517546 go1.24.4.freebsd-riscv64.tar.gz
7d5efda511ff7e3114b130acee5d0bffbb078fedbfa9b2c1b6a807107e1ca23a go1.24.4.illumos-amd64.tar.gz
130c9b061082eca15513e595e9952a2ded32e737e609dd0e49f7dfa74eba026d go1.24.4.linux-386.tar.gz
77e5da33bb72aeaef1ba4418b6fe511bc4d041873cbf82e5aa6318740df98717 go1.24.4.linux-amd64.tar.gz
d5501ee5aca0f258d5fe9bfaed401958445014495dc115f202d43d5210b45241 go1.24.4.linux-arm64.tar.gz
6a554e32301cecae3162677e66d4264b81b3b1a89592dd1b7b5c552c7a49fe37 go1.24.4.linux-armv6l.tar.gz
b208eb25fe244408cbe269ed426454bc46e59d0e0a749b6240d39e884e969875 go1.24.4.linux-loong64.tar.gz
fddfcb28fd36fe63d2ae181026798f86f3bbd3a7bb0f1e1f617dd3d604bf3fe4 go1.24.4.linux-mips.tar.gz
7934b924d5ab8c8ae3134a09a6ae74d3c39f63f6c4322ec289364dbbf0bac3ca go1.24.4.linux-mips64.tar.gz
fa763d8673f94d6e534bb72c3cf675d4c2b8da4a6da42a89f08c5586106db39c go1.24.4.linux-mips64le.tar.gz
84363dbfe49b41d43df84420a09bd53a4770053d63bfa509868c46a5f8eb3ff7 go1.24.4.linux-mipsle.tar.gz
28fcbd5d3b56493606873c33f2b4bdd84ba93c633f37313613b5a1e6495c6fe5 go1.24.4.linux-ppc64.tar.gz
9ca4afef813a2578c23843b640ae0290aa54b2e3c950a6cc4c99e16a57dec2ec go1.24.4.linux-ppc64le.tar.gz
1d7034f98662d8f2c8abd7c700ada4093acb4f9c00e0e51a30344821d0785c77 go1.24.4.linux-riscv64.tar.gz
0449f3203c39703ab27684be763e9bb78ca9a051e0e4176727aead9461b6deb5 go1.24.4.linux-s390x.tar.gz
954b49ccc2cfcf4b5f7cd33ff662295e0d3b74e7590c8e25fc2abb30bce120ba go1.24.4.netbsd-386.tar.gz
370fabcdfee7c18857c96fdd5b706e025d4fb86a208da88ba56b1493b35498e9 go1.24.4.netbsd-amd64.tar.gz
7935ef95d4d1acc48587b1eb4acab98b0a7d9569736a32398b9c1d2e89026865 go1.24.4.netbsd-arm.tar.gz
ead78fd0fa29fbb176cc83f1caa54032e1a44f842affa56a682c647e0759f237 go1.24.4.netbsd-arm64.tar.gz
913e217394b851a636b99de175f0c2f9ab9938b41c557f047168f77ee485d776 go1.24.4.openbsd-386.tar.gz
24568da3dcbcdb24ec18b631f072faf0f3763e3d04f79032dc56ad9ec35379c4 go1.24.4.openbsd-amd64.tar.gz
45abf523f870632417ab007de3841f64dd906bde546ffc8c6380ccbe91c7fb73 go1.24.4.openbsd-arm.tar.gz
7c57c69b5dd1e946b28a3034c285240a48e2861bdcb50b7d9c0ed61bcf89c879 go1.24.4.openbsd-arm64.tar.gz
91ed711f704829372d6931e1897631ef40288b8f9e3cd6ef4a24df7126d1066a go1.24.4.openbsd-ppc64.tar.gz
de5e270d971c8790e8880168d56a2ea103979927c10ded136d792bbdf9bce3d3 go1.24.4.openbsd-riscv64.tar.gz
ff429d03f00bcd32a50f445320b8329d0fadb2a2fff899c11e95e0922a82c543 go1.24.4.plan9-386.tar.gz
39d6363a43fd16b60ae9ad7346a264e982e4fa653dee3b45f83e03cd2f7a6647 go1.24.4.plan9-amd64.tar.gz
1964ae2571259de77b930e97f2891aa92706ff81aac9909d45bb107b0fab16c8 go1.24.4.plan9-arm.tar.gz
a7f9af424e8fb87886664754badca459513f64f6a321d17f1d219b8edf519821 go1.24.4.solaris-amd64.tar.gz
d454d3cb144432f1726bf00e28c6017e78ccb256a8d01b8e3fb1b2e6b5650f28 go1.24.4.windows-386.zip
966ecace1cdbb3497a2b930bdb0f90c3ad32922fa1a7c655b2d4bbeb7e4ac308 go1.24.4.windows-386.msi
b751a1136cb9d8a2e7ebb22c538c4f02c09b98138c7c8bfb78a54a4566c013b1 go1.24.4.windows-amd64.zip
0cbb6e83865747dbe69b3d4155f92e88fcf336ff5d70182dba145e9d7bd3d8f6 go1.24.4.windows-amd64.msi
d17da51bc85bd010754a4063215d15d2c033cc289d67ca9201a03c9041b2969d go1.24.4.windows-arm64.zip
47dbe734b6a829de45654648a7abcf05bdceef5c80e03ea0b208eeebef75a852 go1.24.4.windows-arm64.msi
# version:golangci 2.0.2
# https://github.com/golangci/golangci-lint/releases/

View file

@ -332,7 +332,7 @@ func doTest(cmdline []string) {
// downloadSpecTestFixtures downloads and extracts the execution-spec-tests fixtures.
func downloadSpecTestFixtures(csdb *download.ChecksumDB, cachedir string) string {
ext := ".tar.gz"
base := "fixtures_pectra-devnet-6" // TODO(s1na) rename once the version becomes part of the filename
base := "fixtures_develop"
archivePath := filepath.Join(cachedir, base+ext)
if err := csdb.DownloadFileFromKnownURL(archivePath); err != nil {
log.Fatal(err)

View file

@ -150,7 +150,7 @@ All hex encoded values must be prefixed with `0x`.
#### Create new password protected account
The signer will generate a new private key, encrypt it according to [web3 keystore spec](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) and store it in the keystore directory.
The signer will generate a new private key, encrypt it according to [web3 keystore spec](https://ethereum.org/en/developers/docs/data-structures-and-encoding/web3-secret-storage/) and store it in the keystore directory.
The client is responsible for creating a backup of the keystore. If the keystore is lost there is no method of retrieving lost accounts.
#### Arguments

View file

@ -66,10 +66,9 @@ func (s *Suite) dialAs(key *ecdsa.PrivateKey) (*Conn, error) {
return nil, err
}
conn.caps = []p2p.Cap{
{Name: "eth", Version: 67},
{Name: "eth", Version: 68},
{Name: "eth", Version: 69},
}
conn.ourHighestProtoVersion = 68
conn.ourHighestProtoVersion = 69
return &conn, nil
}
@ -156,7 +155,7 @@ func (c *Conn) ReadEth() (any, error) {
var msg any
switch int(code) {
case eth.StatusMsg:
msg = new(eth.StatusPacket)
msg = new(eth.StatusPacket69)
case eth.GetBlockHeadersMsg:
msg = new(eth.GetBlockHeadersPacket)
case eth.BlockHeadersMsg:
@ -229,9 +228,21 @@ func (c *Conn) ReadSnap() (any, error) {
}
}
// dialAndPeer creates a peer connection and runs the handshake.
func (s *Suite) dialAndPeer(status *eth.StatusPacket69) (*Conn, error) {
c, err := s.dial()
if err != nil {
return nil, err
}
if err = c.peer(s.chain, status); err != nil {
c.Close()
}
return c, err
}
// peer performs both the protocol handshake and the status message
// exchange with the node in order to peer with it.
func (c *Conn) peer(chain *Chain, status *eth.StatusPacket) error {
func (c *Conn) peer(chain *Chain, status *eth.StatusPacket69) error {
if err := c.handshake(); err != nil {
return fmt.Errorf("handshake failed: %v", err)
}
@ -304,7 +315,7 @@ func (c *Conn) negotiateEthProtocol(caps []p2p.Cap) {
}
// statusExchange performs a `Status` message exchange with the given node.
func (c *Conn) statusExchange(chain *Chain, status *eth.StatusPacket) error {
func (c *Conn) statusExchange(chain *Chain, status *eth.StatusPacket69) error {
loop:
for {
code, data, err := c.Read()
@ -313,11 +324,15 @@ loop:
}
switch code {
case eth.StatusMsg + protoOffset(ethProto):
msg := new(eth.StatusPacket)
msg := new(eth.StatusPacket69)
if err := rlp.DecodeBytes(data, &msg); err != nil {
return fmt.Errorf("error decoding status packet: %w", err)
}
if have, want := msg.Head, chain.blocks[chain.Len()-1].Hash(); have != want {
if have, want := msg.LatestBlock, chain.blocks[chain.Len()-1].NumberU64(); have != want {
return fmt.Errorf("wrong head block in status, want: %d, have %d",
want, have)
}
if have, want := msg.LatestBlockHash, chain.blocks[chain.Len()-1].Hash(); have != want {
return fmt.Errorf("wrong head block in status, want: %#x (block %d) have %#x",
want, chain.blocks[chain.Len()-1].NumberU64(), have)
}
@ -348,13 +363,14 @@ loop:
}
if status == nil {
// default status message
status = &eth.StatusPacket{
status = &eth.StatusPacket69{
ProtocolVersion: uint32(c.negotiatedProtoVersion),
NetworkID: chain.config.ChainID.Uint64(),
TD: chain.TD(),
Head: chain.blocks[chain.Len()-1].Hash(),
Genesis: chain.blocks[0].Hash(),
ForkID: chain.ForkID(),
EarliestBlock: 0,
LatestBlock: chain.blocks[chain.Len()-1].NumberU64(),
LatestBlockHash: chain.blocks[chain.Len()-1].Hash(),
}
}
if err := c.Write(ethProto, eth.StatusMsg, status); err != nil {

View file

@ -32,7 +32,7 @@ const (
// Unexported devp2p protocol lengths from p2p package.
const (
baseProtoLen = 16
ethProtoLen = 17
ethProtoLen = 18
snapProtoLen = 8
)

View file

@ -68,16 +68,19 @@ func (s *Suite) EthTests() []utesting.Test {
return []utesting.Test{
// status
{Name: "Status", Fn: s.TestStatus},
{Name: "MaliciousHandshake", Fn: s.TestMaliciousHandshake},
{Name: "BlockRangeUpdateExpired", Fn: s.TestBlockRangeUpdateHistoryExp},
{Name: "BlockRangeUpdateFuture", Fn: s.TestBlockRangeUpdateFuture},
{Name: "BlockRangeUpdateInvalid", Fn: s.TestBlockRangeUpdateInvalid},
// get block headers
{Name: "GetBlockHeaders", Fn: s.TestGetBlockHeaders},
{Name: "GetNonexistentBlockHeaders", Fn: s.TestGetNonexistentBlockHeaders},
{Name: "SimultaneousRequests", Fn: s.TestSimultaneousRequests},
{Name: "SameRequestID", Fn: s.TestSameRequestID},
{Name: "ZeroRequestID", Fn: s.TestZeroRequestID},
// get block bodies
// get history
{Name: "GetBlockBodies", Fn: s.TestGetBlockBodies},
// // malicious handshakes + status
{Name: "MaliciousHandshake", Fn: s.TestMaliciousHandshake},
{Name: "GetReceipts", Fn: s.TestGetReceipts},
// test transactions
{Name: "LargeTxRequest", Fn: s.TestLargeTxRequest, Slow: true},
{Name: "Transaction", Fn: s.TestTransaction},
@ -101,15 +104,11 @@ func (s *Suite) SnapTests() []utesting.Test {
func (s *Suite) TestStatus(t *utesting.T) {
t.Log(`This test is just a sanity check. It performs an eth protocol handshake.`)
conn, err := s.dial()
conn, err := s.dialAndPeer(nil)
if err != nil {
t.Fatalf("dial failed: %v", err)
}
defer conn.Close()
if err := conn.peer(s.chain, nil); err != nil {
t.Fatalf("peering failed: %v", err)
t.Fatal("peering failed:", err)
}
conn.Close()
}
// headersMatch returns whether the received headers match the given request
@ -119,15 +118,12 @@ func headersMatch(expected []*types.Header, headers []*types.Header) bool {
func (s *Suite) TestGetBlockHeaders(t *utesting.T) {
t.Log(`This test requests block headers from the node.`)
conn, err := s.dial()
conn, err := s.dialAndPeer(nil)
if err != nil {
t.Fatalf("dial failed: %v", err)
}
defer conn.Close()
if err = conn.peer(s.chain, nil); err != nil {
t.Fatalf("peering failed: %v", err)
}
defer conn.Close()
// Send headers request.
req := &eth.GetBlockHeadersPacket{
RequestId: 33,
@ -162,16 +158,11 @@ func (s *Suite) TestGetBlockHeaders(t *utesting.T) {
func (s *Suite) TestGetNonexistentBlockHeaders(t *utesting.T) {
t.Log(`This test sends GetBlockHeaders requests for nonexistent blocks (using max uint64 value)
to check if the node disconnects after receiving multiple invalid requests.`)
conn, err := s.dial()
conn, err := s.dialAndPeer(nil)
if err != nil {
t.Fatalf("dial failed: %v", err)
}
defer conn.Close()
if err := conn.peer(s.chain, nil); err != nil {
t.Fatalf("peering failed: %v", err)
}
defer conn.Close()
// Create request with max uint64 value for a nonexistent block
badReq := &eth.GetBlockHeadersPacket{
@ -204,15 +195,11 @@ to check if the node disconnects after receiving multiple invalid requests.`)
func (s *Suite) TestSimultaneousRequests(t *utesting.T) {
t.Log(`This test requests blocks headers from the node, performing two requests
concurrently, with different request IDs.`)
conn, err := s.dial()
conn, err := s.dialAndPeer(nil)
if err != nil {
t.Fatalf("dial failed: %v", err)
}
defer conn.Close()
if err := conn.peer(s.chain, nil); err != nil {
t.Fatalf("peering failed: %v", err)
}
defer conn.Close()
// Create two different requests.
req1 := &eth.GetBlockHeadersPacket{
@ -278,15 +265,11 @@ concurrently, with different request IDs.`)
func (s *Suite) TestSameRequestID(t *utesting.T) {
t.Log(`This test requests block headers, performing two concurrent requests with the
same request ID. The node should handle the request by responding to both requests.`)
conn, err := s.dial()
conn, err := s.dialAndPeer(nil)
if err != nil {
t.Fatalf("dial failed: %v", err)
}
defer conn.Close()
if err := conn.peer(s.chain, nil); err != nil {
t.Fatalf("peering failed: %v", err)
}
defer conn.Close()
// Create two different requests with the same ID.
reqID := uint64(1234)
@ -349,15 +332,12 @@ same request ID. The node should handle the request by responding to both reques
func (s *Suite) TestZeroRequestID(t *utesting.T) {
t.Log(`This test sends a GetBlockHeaders message with a request-id of zero,
and expects a response.`)
conn, err := s.dial()
conn, err := s.dialAndPeer(nil)
if err != nil {
t.Fatalf("dial failed: %v", err)
}
defer conn.Close()
if err := conn.peer(s.chain, nil); err != nil {
t.Fatalf("peering failed: %v", err)
}
defer conn.Close()
req := &eth.GetBlockHeadersPacket{
GetBlockHeadersRequest: &eth.GetBlockHeadersRequest{
Origin: eth.HashOrNumber{Number: 0},
@ -384,15 +364,12 @@ and expects a response.`)
func (s *Suite) TestGetBlockBodies(t *utesting.T) {
t.Log(`This test sends GetBlockBodies requests to the node for known blocks in the test chain.`)
conn, err := s.dial()
conn, err := s.dialAndPeer(nil)
if err != nil {
t.Fatalf("dial failed: %v", err)
}
defer conn.Close()
if err := conn.peer(s.chain, nil); err != nil {
t.Fatalf("peering failed: %v", err)
}
defer conn.Close()
// Create block bodies request.
req := &eth.GetBlockBodiesPacket{
RequestId: 55,
@ -418,6 +395,47 @@ func (s *Suite) TestGetBlockBodies(t *utesting.T) {
}
}
func (s *Suite) TestGetReceipts(t *utesting.T) {
t.Log(`This test sends GetReceipts requests to the node for known blocks in the test chain.`)
conn, err := s.dialAndPeer(nil)
if err != nil {
t.Fatalf("peering failed: %v", err)
}
defer conn.Close()
// Find some blocks containing receipts.
var hashes = make([]common.Hash, 0, 3)
for i := range s.chain.Len() {
block := s.chain.GetBlock(i)
if len(block.Transactions()) > 0 {
hashes = append(hashes, block.Hash())
}
if len(hashes) == cap(hashes) {
break
}
}
// Create block bodies request.
req := &eth.GetReceiptsPacket{
RequestId: 66,
GetReceiptsRequest: (eth.GetReceiptsRequest)(hashes),
}
if err := conn.Write(ethProto, eth.GetReceiptsMsg, req); err != nil {
t.Fatalf("could not write to connection: %v", err)
}
// Wait for response.
resp := new(eth.ReceiptsPacket[*eth.ReceiptList69])
if err := conn.ReadMsg(ethProto, eth.ReceiptsMsg, &resp); err != nil {
t.Fatalf("error reading block bodies msg: %v", err)
}
if got, want := resp.RequestId, req.RequestId; got != want {
t.Fatalf("unexpected request id in respond", got, want)
}
if len(resp.List) != len(req.GetReceiptsRequest) {
t.Fatalf("wrong bodies in response: expected %d bodies, got %d", len(req.GetReceiptsRequest), len(resp.List))
}
}
// randBuf makes a random buffer size kilobytes large.
func randBuf(size int) []byte {
buf := make([]byte, size*1024)
@ -500,6 +518,97 @@ func (s *Suite) TestMaliciousHandshake(t *utesting.T) {
}
}
func (s *Suite) TestBlockRangeUpdateInvalid(t *utesting.T) {
t.Log(`This test sends an invalid BlockRangeUpdate message to the node and expects to be disconnected.`)
conn, err := s.dialAndPeer(nil)
if err != nil {
t.Fatal(err)
}
defer conn.Close()
conn.Write(ethProto, eth.BlockRangeUpdateMsg, &eth.BlockRangeUpdatePacket{
EarliestBlock: 10,
LatestBlock: 8,
LatestBlockHash: s.chain.GetBlock(8).Hash(),
})
if code, _, err := conn.Read(); err != nil {
t.Fatalf("expected disconnect, got err: %v", err)
} else if code != discMsg {
t.Fatalf("expected disconnect message, got msg code %d", code)
}
}
func (s *Suite) TestBlockRangeUpdateFuture(t *utesting.T) {
t.Log(`This test sends a BlockRangeUpdate that is beyond the chain head.
The node should accept the update and should not disonnect.`)
conn, err := s.dialAndPeer(nil)
if err != nil {
t.Fatal(err)
}
defer conn.Close()
head := s.chain.Head().NumberU64()
var hash common.Hash
rand.Read(hash[:])
conn.Write(ethProto, eth.BlockRangeUpdateMsg, &eth.BlockRangeUpdatePacket{
EarliestBlock: head + 10,
LatestBlock: head + 50,
LatestBlockHash: hash,
})
// Ensure the node does not disconnect us.
// Just send a few ping messages.
for range 10 {
time.Sleep(100 * time.Millisecond)
if err := conn.Write(baseProto, pingMsg, []any{}); err != nil {
t.Fatal("write error:", err)
}
code, _, err := conn.Read()
switch {
case err != nil:
t.Fatal("read error:", err)
case code == discMsg:
t.Fatal("got disconnect")
case code == pongMsg:
}
}
}
func (s *Suite) TestBlockRangeUpdateHistoryExp(t *utesting.T) {
t.Log(`This test sends a BlockRangeUpdate announcing incomplete (expired) history.
The node should accept the update and should not disonnect.`)
conn, err := s.dialAndPeer(nil)
if err != nil {
t.Fatal(err)
}
defer conn.Close()
head := s.chain.Head()
conn.Write(ethProto, eth.BlockRangeUpdateMsg, &eth.BlockRangeUpdatePacket{
EarliestBlock: head.NumberU64() - 10,
LatestBlock: head.NumberU64(),
LatestBlockHash: head.Hash(),
})
// Ensure the node does not disconnect us.
// Just send a few ping messages.
for range 10 {
time.Sleep(100 * time.Millisecond)
if err := conn.Write(baseProto, pingMsg, []any{}); err != nil {
t.Fatal("write error:", err)
}
code, _, err := conn.Read()
switch {
case err != nil:
t.Fatal("read error:", err)
case code == discMsg:
t.Fatal("got disconnect")
case code == pongMsg:
}
}
}
func (s *Suite) TestTransaction(t *utesting.T) {
t.Log(`This test sends a valid transaction to the node and checks if the
transaction gets propagated.`)

View file

@ -1,228 +0,0 @@
// Copyright 2024 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package main
import (
"bufio"
"encoding/hex"
"encoding/json"
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/log"
"github.com/urfave/cli/v2"
)
var jt vm.JumpTable
const initcode = "INITCODE"
func init() {
jt = vm.NewEOFInstructionSetForTesting()
}
var (
hexFlag = &cli.StringFlag{
Name: "hex",
Usage: "Single container data parse and validation",
}
refTestFlag = &cli.StringFlag{
Name: "test",
Usage: "Path to EOF validation reference test.",
}
eofParseCommand = &cli.Command{
Name: "eofparse",
Aliases: []string{"eof"},
Usage: "Parses hex eof container and returns validation errors (if any)",
Action: eofParseAction,
Flags: []cli.Flag{
hexFlag,
refTestFlag,
},
}
eofDumpCommand = &cli.Command{
Name: "eofdump",
Usage: "Parses hex eof container and prints out human-readable representation of the container.",
Action: eofDumpAction,
Flags: []cli.Flag{
hexFlag,
},
}
)
func eofParseAction(ctx *cli.Context) error {
// If `--test` is set, parse and validate the reference test at the provided path.
if ctx.IsSet(refTestFlag.Name) {
var (
file = ctx.String(refTestFlag.Name)
executedTests int
passedTests int
)
err := filepath.Walk(file, func(path string, info fs.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
log.Debug("Executing test", "name", info.Name())
passed, tot, err := executeTest(path)
passedTests += passed
executedTests += tot
return err
})
if err != nil {
return err
}
log.Info("Executed tests", "passed", passedTests, "total executed", executedTests)
return nil
}
// If `--hex` is set, parse and validate the hex string argument.
if ctx.IsSet(hexFlag.Name) {
if _, err := parseAndValidate(ctx.String(hexFlag.Name), false); err != nil {
return fmt.Errorf("err: %w", err)
}
fmt.Println("OK")
return nil
}
// If neither are passed in, read input from stdin.
scanner := bufio.NewScanner(os.Stdin)
scanner.Buffer(make([]byte, 1024*1024), 10*1024*1024)
for scanner.Scan() {
l := strings.TrimSpace(scanner.Text())
if strings.HasPrefix(l, "#") || l == "" {
continue
}
if _, err := parseAndValidate(l, false); err != nil {
fmt.Printf("err: %v\n", err)
} else {
fmt.Println("OK")
}
}
if err := scanner.Err(); err != nil {
fmt.Println(err.Error())
}
return nil
}
type refTests struct {
Vectors map[string]eOFTest `json:"vectors"`
}
type eOFTest struct {
Code string `json:"code"`
Results map[string]etResult `json:"results"`
ContainerKind string `json:"containerKind"`
}
type etResult struct {
Result bool `json:"result"`
Exception string `json:"exception,omitempty"`
}
func executeTest(path string) (int, int, error) {
src, err := os.ReadFile(path)
if err != nil {
return 0, 0, err
}
var testsByName map[string]refTests
if err := json.Unmarshal(src, &testsByName); err != nil {
return 0, 0, err
}
passed, total := 0, 0
for testsName, tests := range testsByName {
for name, tt := range tests.Vectors {
for fork, r := range tt.Results {
total++
_, err := parseAndValidate(tt.Code, tt.ContainerKind == initcode)
if r.Result && err != nil {
log.Error("Test failure, expected validation success", "name", testsName, "idx", name, "fork", fork, "err", err)
continue
}
if !r.Result && err == nil {
log.Error("Test failure, expected validation error", "name", testsName, "idx", name, "fork", fork, "have err", r.Exception, "err", err)
continue
}
passed++
}
}
}
return passed, total, nil
}
func parseAndValidate(s string, isInitCode bool) (*vm.Container, error) {
if len(s) >= 2 && strings.HasPrefix(s, "0x") {
s = s[2:]
}
b, err := hex.DecodeString(s)
if err != nil {
return nil, fmt.Errorf("unable to decode data: %w", err)
}
return parse(b, isInitCode)
}
func parse(b []byte, isInitCode bool) (*vm.Container, error) {
var c vm.Container
if err := c.UnmarshalBinary(b, isInitCode); err != nil {
return nil, err
}
if err := c.ValidateCode(&jt, isInitCode); err != nil {
return nil, err
}
return &c, nil
}
func eofDumpAction(ctx *cli.Context) error {
// If `--hex` is set, parse and validate the hex string argument.
if ctx.IsSet(hexFlag.Name) {
return eofDump(ctx.String(hexFlag.Name))
}
// Otherwise read from stdin
scanner := bufio.NewScanner(os.Stdin)
scanner.Buffer(make([]byte, 1024*1024), 10*1024*1024)
for scanner.Scan() {
l := strings.TrimSpace(scanner.Text())
if strings.HasPrefix(l, "#") || l == "" {
continue
}
if err := eofDump(l); err != nil {
return err
}
fmt.Println("")
}
return scanner.Err()
}
func eofDump(hexdata string) error {
if len(hexdata) >= 2 && strings.HasPrefix(hexdata, "0x") {
hexdata = hexdata[2:]
}
b, err := hex.DecodeString(hexdata)
if err != nil {
return fmt.Errorf("unable to decode data: %w", err)
}
var c vm.Container
if err := c.UnmarshalBinary(b, false); err != nil {
return err
}
fmt.Println(c.String())
return nil
}

View file

@ -1,182 +0,0 @@
// Copyright 2024 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package main
import (
"bufio"
"bytes"
"encoding/hex"
"fmt"
"os"
"strings"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
)
func FuzzEofParsing(f *testing.F) {
// Seed with corpus from execution-spec-tests
for i := 0; ; i++ {
fname := fmt.Sprintf("testdata/eof/eof_corpus_%d.txt", i)
corpus, err := os.Open(fname)
if err != nil {
break
}
f.Logf("Reading seed data from %v", fname)
scanner := bufio.NewScanner(corpus)
scanner.Buffer(make([]byte, 1024), 10*1024*1024)
for scanner.Scan() {
s := scanner.Text()
if len(s) >= 2 && strings.HasPrefix(s, "0x") {
s = s[2:]
}
b, err := hex.DecodeString(s)
if err != nil {
panic(err) // rotten corpus
}
f.Add(b)
}
corpus.Close()
if err := scanner.Err(); err != nil {
panic(err) // rotten corpus
}
}
// And do the fuzzing
f.Fuzz(func(t *testing.T, data []byte) {
var (
jt = vm.NewEOFInstructionSetForTesting()
c vm.Container
)
cpy := common.CopyBytes(data)
if err := c.UnmarshalBinary(data, true); err == nil {
c.ValidateCode(&jt, true)
if have := c.MarshalBinary(); !bytes.Equal(have, data) {
t.Fatal("Unmarshal-> Marshal failure!")
}
}
if err := c.UnmarshalBinary(data, false); err == nil {
c.ValidateCode(&jt, false)
if have := c.MarshalBinary(); !bytes.Equal(have, data) {
t.Fatal("Unmarshal-> Marshal failure!")
}
}
if !bytes.Equal(cpy, data) {
panic("data modified during unmarshalling")
}
})
}
func TestEofParseInitcode(t *testing.T) {
testEofParse(t, true, "testdata/eof/results.initcode.txt")
}
func TestEofParseRegular(t *testing.T) {
testEofParse(t, false, "testdata/eof/results.regular.txt")
}
func testEofParse(t *testing.T, isInitCode bool, wantFile string) {
var wantFn func() string
var wantLoc = 0
{ // Configure the want-reader
wants, err := os.Open(wantFile)
if err != nil {
t.Fatal(err)
}
scanner := bufio.NewScanner(wants)
scanner.Buffer(make([]byte, 1024), 10*1024*1024)
wantFn = func() string {
if scanner.Scan() {
wantLoc++
return scanner.Text()
}
return "end of file reached"
}
}
for i := 0; ; i++ {
fname := fmt.Sprintf("testdata/eof/eof_corpus_%d.txt", i)
corpus, err := os.Open(fname)
if err != nil {
break
}
t.Logf("# Reading seed data from %v", fname)
scanner := bufio.NewScanner(corpus)
scanner.Buffer(make([]byte, 1024), 10*1024*1024)
line := 1
for scanner.Scan() {
s := scanner.Text()
if len(s) >= 2 && strings.HasPrefix(s, "0x") {
s = s[2:]
}
b, err := hex.DecodeString(s)
if err != nil {
panic(err) // rotten corpus
}
have := "OK"
if _, err := parse(b, isInitCode); err != nil {
have = fmt.Sprintf("ERR: %v", err)
}
if false { // Change this to generate the want-output
fmt.Printf("%v\n", have)
} else {
want := wantFn()
if have != want {
if len(want) > 100 {
want = want[:100]
}
if len(b) > 100 {
b = b[:100]
}
t.Errorf("%v:%d\n%v\ninput %x\nisInit: %v\nhave: %q\nwant: %q\n",
fname, line, fmt.Sprintf("%v:%d", wantFile, wantLoc), b, isInitCode, have, want)
}
}
line++
}
corpus.Close()
}
}
func BenchmarkEofParse(b *testing.B) {
corpus, err := os.Open("testdata/eof/eof_benches.txt")
if err != nil {
b.Fatal(err)
}
defer corpus.Close()
scanner := bufio.NewScanner(corpus)
scanner.Buffer(make([]byte, 1024), 10*1024*1024)
line := 1
for scanner.Scan() {
s := scanner.Text()
if len(s) >= 2 && strings.HasPrefix(s, "0x") {
s = s[2:]
}
data, err := hex.DecodeString(s)
if err != nil {
b.Fatal(err) // rotten corpus
}
b.Run(fmt.Sprintf("test-%d", line), func(b *testing.B) {
b.ReportAllocs()
b.SetBytes(int64(len(data)))
for i := 0; i < b.N; i++ {
_, _ = parse(data, false)
}
})
line++
}
}

View file

@ -303,7 +303,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
}
// Set the receipt logs and create the bloom filter.
receipt.Logs = statedb.GetLogs(tx.Hash(), vmContext.BlockNumber.Uint64(), blockHash)
receipt.Logs = statedb.GetLogs(tx.Hash(), vmContext.BlockNumber.Uint64(), blockHash, vmContext.Time)
receipt.Bloom = types.CreateBloom(receipt)
// These three are non-consensus fields:

View file

@ -210,8 +210,6 @@ func init() {
stateTransitionCommand,
transactionCommand,
blockBuilderCommand,
eofParseCommand,
eofDumpCommand,
}
app.Before = func(ctx *cli.Context) error {
flags.MigrateGlobalFlags(ctx)

View file

@ -46,6 +46,7 @@ import (
"github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/trie"
"github.com/urfave/cli/v2"
@ -59,7 +60,7 @@ var (
ArgsUsage: "<genesisPath>",
Flags: slices.Concat([]cli.Flag{
utils.CachePreimagesFlag,
utils.OverridePrague,
utils.OverrideOsaka,
utils.OverrideVerkle,
}, utils.DatabaseFlags),
Description: `
@ -270,19 +271,16 @@ func initGenesis(ctx *cli.Context) error {
defer stack.Close()
var overrides core.ChainOverrides
if ctx.IsSet(utils.OverridePrague.Name) {
v := ctx.Uint64(utils.OverridePrague.Name)
overrides.OverridePrague = &v
if ctx.IsSet(utils.OverrideOsaka.Name) {
v := ctx.Uint64(utils.OverrideOsaka.Name)
overrides.OverrideOsaka = &v
}
if ctx.IsSet(utils.OverrideVerkle.Name) {
v := ctx.Uint64(utils.OverrideVerkle.Name)
overrides.OverrideVerkle = &v
}
chaindb, err := stack.OpenDatabaseWithFreezer("chaindata", 0, 0, ctx.String(utils.AncientFlag.Name), "", false)
if err != nil {
utils.Fatalf("Failed to open database: %v", err)
}
chaindb := utils.MakeChainDatabase(ctx, stack, false)
defer chaindb.Close()
triedb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle())
@ -319,7 +317,7 @@ func dumpGenesis(ctx *cli.Context) error {
// dump whatever already exists in the datadir
stack, _ := makeConfigNode(ctx)
db, err := stack.OpenDatabase("chaindata", 0, 0, "", true)
db, err := stack.OpenDatabaseWithOptions("chaindata", node.DatabaseOptions{ReadOnly: true})
if err != nil {
return err
}
@ -798,8 +796,12 @@ func downloadEra(ctx *cli.Context) error {
// Resolve the destination directory.
stack, _ := makeConfigNode(ctx)
defer stack.Close()
ancients := stack.ResolveAncient("chaindata", "")
dir := filepath.Join(ancients, "era")
dir := filepath.Join(ancients, rawdb.ChainFreezerName, "era")
if ctx.IsSet(utils.EraFlag.Name) {
dir = filepath.Join(ancients, ctx.String(utils.EraFlag.Name))
}
baseURL := ctx.String(eraServerFlag.Name)
if baseURL == "" {
@ -836,15 +838,8 @@ func downloadEra(ctx *cli.Context) error {
}
func parseRange(s string) (start uint64, end uint64, ok bool) {
if m, _ := regexp.MatchString("[0-9]+", s); m {
start, err := strconv.ParseUint(s, 10, 64)
if err != nil {
return 0, 0, false
}
end = start
return start, end, true
}
if m, _ := regexp.MatchString("[0-9]+-[0-9]+", s); m {
log.Info("Parsing block range", "input", s)
if m, _ := regexp.MatchString("^[0-9]+-[0-9]+$", s); m {
s1, s2, _ := strings.Cut(s, "-")
start, err := strconv.ParseUint(s1, 10, 64)
if err != nil {
@ -854,6 +849,19 @@ func parseRange(s string) (start uint64, end uint64, ok bool) {
if err != nil {
return 0, 0, false
}
if start > end {
return 0, 0, false
}
log.Info("Parsing block range", "start", start, "end", end)
return start, end, true
}
if m, _ := regexp.MatchString("^[0-9]+$", s); m {
start, err := strconv.ParseUint(s, 10, 64)
if err != nil {
return 0, 0, false
}
end = start
log.Info("Parsing single block range", "block", start)
return start, end, true
}
return 0, 0, false

98
cmd/geth/chaincmd_test.go Normal file
View file

@ -0,0 +1,98 @@
// Copyright 2025 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package main
import "testing"
func TestParseRange(t *testing.T) {
var cases = []struct {
input string
valid bool
expStart uint64
expEnd uint64
}{
{
input: "0",
valid: true,
expStart: 0,
expEnd: 0,
},
{
input: "500",
valid: true,
expStart: 500,
expEnd: 500,
},
{
input: "-1",
valid: false,
expStart: 0,
expEnd: 0,
},
{
input: "1-1",
valid: true,
expStart: 1,
expEnd: 1,
},
{
input: "0-1",
valid: true,
expStart: 0,
expEnd: 1,
},
{
input: "1-0",
valid: false,
expStart: 0,
expEnd: 0,
},
{
input: "1-1000",
valid: true,
expStart: 1,
expEnd: 1000,
},
{
input: "1-1-",
valid: false,
expStart: 0,
expEnd: 0,
},
{
input: "-1-1",
valid: false,
expStart: 0,
expEnd: 0,
},
}
for _, c := range cases {
start, end, valid := parseRange(c.input)
if valid != c.valid {
t.Errorf("Unexpected result, want: %t, got: %t", c.valid, valid)
continue
}
if valid {
if c.expStart != start {
t.Errorf("Unexpected start, want: %d, got: %d", c.expStart, start)
}
if c.expEnd != end {
t.Errorf("Unexpected end, want: %d, got: %d", c.expEnd, end)
}
}
}
}

View file

@ -36,6 +36,7 @@ import (
"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/crypto"
"github.com/ethereum/go-ethereum/eth/catalyst"
"github.com/ethereum/go-ethereum/eth/ethconfig"
"github.com/ethereum/go-ethereum/internal/flags"
@ -180,12 +181,51 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
return stack, cfg
}
// constructs the disclaimer text block which will be printed in the logs upon
// startup when Geth is running in dev mode.
func constructDevModeBanner(ctx *cli.Context, cfg gethConfig) string {
devModeBanner := `You are running Geth in --dev mode. Please note the following:
1. This mode is only intended for fast, iterative development without assumptions on
security or persistence.
2. The database is created in memory unless specified otherwise. Therefore, shutting down
your computer or losing power will wipe your entire block data and chain state for
your dev environment.
3. A random, pre-allocated developer account will be available and unlocked as
eth.coinbase, which can be used for testing. The random dev account is temporary,
stored on a ramdisk, and will be lost if your machine is restarted.
4. Mining is enabled by default. However, the client will only seal blocks if transactions
are pending in the mempool. The miner's minimum accepted gas price is 1.
5. Networking is disabled; there is no listen-address, the maximum number of peers is set
to 0, and discovery is disabled.
`
if !ctx.IsSet(utils.DataDirFlag.Name) {
devModeBanner += fmt.Sprintf(`
Running in ephemeral mode. The following account has been prefunded in the genesis:
Account
------------------
0x%x (10^49 ETH)
`, cfg.Eth.Miner.PendingFeeRecipient)
if cfg.Eth.Miner.PendingFeeRecipient == utils.DeveloperAddr {
devModeBanner += fmt.Sprintf(`
Private Key
------------------
0x%x
`, crypto.FromECDSA(utils.DeveloperKey))
}
}
return devModeBanner
}
// makeFullNode loads geth configuration and creates the Ethereum backend.
func makeFullNode(ctx *cli.Context) *node.Node {
stack, cfg := makeConfigNode(ctx)
if ctx.IsSet(utils.OverridePrague.Name) {
v := ctx.Uint64(utils.OverridePrague.Name)
cfg.Eth.OverridePrague = &v
if ctx.IsSet(utils.OverrideOsaka.Name) {
v := ctx.Uint64(utils.OverrideOsaka.Name)
cfg.Eth.OverrideOsaka = &v
}
if ctx.IsSet(utils.OverrideVerkle.Name) {
v := ctx.Uint64(utils.OverrideVerkle.Name)
@ -239,6 +279,11 @@ func makeFullNode(ctx *cli.Context) *node.Node {
}
catalyst.RegisterSimulatedBeaconAPIs(stack, simBeacon)
stack.RegisterLifecycle(simBeacon)
banner := constructDevModeBanner(ctx, cfg)
for _, line := range strings.Split(banner, "\n") {
log.Warn(line)
}
} else if ctx.IsSet(utils.BeaconApiFlag.Name) {
// Start blsync mode.
srv := rpc.NewServer()

View file

@ -62,7 +62,7 @@ var (
utils.NoUSBFlag, // deprecated
utils.USBFlag,
utils.SmartCardDaemonPathFlag,
utils.OverridePrague,
utils.OverrideOsaka,
utils.OverrideVerkle,
utils.EnablePersonal, // deprecated
utils.TxPoolLocalsFlag,
@ -91,13 +91,7 @@ var (
utils.LogNoHistoryFlag,
utils.LogExportCheckpointsFlag,
utils.StateHistoryFlag,
utils.LightServeFlag, // deprecated
utils.LightIngressFlag, // deprecated
utils.LightEgressFlag, // deprecated
utils.LightMaxPeersFlag, // deprecated
utils.LightNoPruneFlag, // deprecated
utils.LightKDFFlag,
utils.LightNoSyncServeFlag, // deprecated
utils.EthRequiredBlocksFlag,
utils.LegacyWhitelistFlag, // deprecated
utils.CacheFlag,
@ -300,24 +294,6 @@ func prepare(ctx *cli.Context) {
case ctx.IsSet(utils.HoodiFlag.Name):
log.Info("Starting Geth on Hoodi testnet...")
case ctx.IsSet(utils.DeveloperFlag.Name):
log.Info("Starting Geth in ephemeral dev mode...")
log.Warn(`You are running Geth in --dev mode. Please note the following:
1. This mode is only intended for fast, iterative development without assumptions on
security or persistence.
2. The database is created in memory unless specified otherwise. Therefore, shutting down
your computer or losing power will wipe your entire block data and chain state for
your dev environment.
3. A random, pre-allocated developer account will be available and unlocked as
eth.coinbase, which can be used for testing. The random dev account is temporary,
stored on a ramdisk, and will be lost if your machine is restarted.
4. Mining is enabled by default. However, the client will only seal blocks if transactions
are pending in the mempool. The miner's minimum accepted gas price is 1.
5. Networking is disabled; there is no listen-address, the maximum number of peers is set
to 0, and discovery is disabled.
`)
case !ctx.IsSet(utils.NetworkIdFlag.Name):
log.Info("Starting Geth on Ethereum mainnet...")
}

View file

@ -220,6 +220,27 @@ func verifyState(ctx *cli.Context) error {
triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false)
defer triedb.Close()
var (
err error
root = headBlock.Root()
)
if ctx.NArg() == 1 {
root, err = parseRoot(ctx.Args().First())
if err != nil {
log.Error("Failed to resolve state root", "err", err)
return err
}
}
if triedb.Scheme() == rawdb.PathScheme {
if err := triedb.VerifyState(root); err != nil {
log.Error("Failed to verify state", "root", root, "err", err)
return err
}
log.Info("Verified the state", "root", root)
// TODO(rjl493456442) implement dangling checks in pathdb.
return nil
} else {
snapConfig := snapshot.Config{
CacheSize: 256,
Recovery: false,
@ -231,18 +252,6 @@ func verifyState(ctx *cli.Context) error {
log.Error("Failed to open snapshot tree", "err", err)
return err
}
if ctx.NArg() > 1 {
log.Error("Too many arguments given")
return errors.New("too many arguments")
}
var root = headBlock.Root()
if ctx.NArg() == 1 {
root, err = parseRoot(ctx.Args().First())
if err != nil {
log.Error("Failed to resolve state root", "err", err)
return err
}
}
if err := snaptree.Verify(root); err != nil {
log.Error("Failed to verify state", "root", root, "err", err)
return err
@ -250,6 +259,7 @@ func verifyState(ctx *cli.Context) error {
log.Info("Verified the state", "root", root)
return snapshot.CheckDanglingStorage(chaindb)
}
}
// checkDanglingStorage iterates the snap storage data, and verifies that all
// storage also has corresponding account data.

View file

@ -309,7 +309,8 @@ func ImportHistory(chain *core.BlockChain, dir string, network string) error {
if err != nil {
return fmt.Errorf("error reading receipts %d: %w", it.Number(), err)
}
if _, err := chain.InsertReceiptChain([]*types.Block{block}, []types.Receipts{receipts}, 2^64-1); err != nil {
encReceipts := types.EncodeBlockReceiptLists([]types.Receipts{receipts})
if _, err := chain.InsertReceiptChain([]*types.Block{block}, encReceipts, 2^64-1); err != nil {
return fmt.Errorf("error inserting body %d: %w", it.Number(), err)
}
imported += 1

View file

@ -111,6 +111,11 @@ var (
Usage: "Root directory for ancient data (default = inside chaindata)",
Category: flags.EthCategory,
}
EraFlag = &flags.DirectoryFlag{
Name: "datadir.era",
Usage: "Root directory for era1 history (default = inside ancient/chain)",
Category: flags.EthCategory,
}
MinFreeDiskSpaceFlag = &flags.DirectoryFlag{
Name: "datadir.minfreedisk",
Usage: "Minimum free disk space in MB, once reached triggers auto shut down (default = --cache.gc converted to MB, 0 = disabled)",
@ -145,7 +150,7 @@ var (
}
SepoliaFlag = &cli.BoolFlag{
Name: "sepolia",
Usage: "Sepolia network: pre-configured proof-of-work test network",
Usage: "Sepolia network: pre-configured proof-of-stake test network",
Category: flags.EthCategory,
}
HoleskyFlag = &cli.BoolFlag{
@ -238,9 +243,9 @@ var (
Value: 2048,
Category: flags.EthCategory,
}
OverridePrague = &cli.Uint64Flag{
Name: "override.prague",
Usage: "Manually specify the Prague fork timestamp, overriding the bundled setting",
OverrideOsaka = &cli.Uint64Flag{
Name: "override.osaka",
Usage: "Manually specify the Osaka fork timestamp, overriding the bundled setting",
Category: flags.EthCategory,
}
OverrideVerkle = &cli.Uint64Flag{
@ -977,6 +982,7 @@ var (
DatabaseFlags = []cli.Flag{
DataDirFlag,
AncientFlag,
EraFlag,
RemoteDBFlag,
DBEngineFlag,
StateSchemeFlag,
@ -984,6 +990,12 @@ var (
}
)
// default account to prefund when running Geth in dev mode
var (
DeveloperKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
DeveloperAddr = crypto.PubkeyToAddress(DeveloperKey.PublicKey)
)
// MakeDataDir retrieves the currently requested data directory, terminating
// if none (or the empty string) is specified. If the node is starting a testnet,
// then a subdirectory of the specified datadir will be used.
@ -1245,28 +1257,6 @@ func setIPC(ctx *cli.Context, cfg *node.Config) {
}
}
// setLes shows the deprecation warnings for LES flags.
func setLes(ctx *cli.Context, cfg *ethconfig.Config) {
if ctx.IsSet(LightServeFlag.Name) {
log.Warn("The light server has been deprecated, please remove this flag", "flag", LightServeFlag.Name)
}
if ctx.IsSet(LightIngressFlag.Name) {
log.Warn("The light server has been deprecated, please remove this flag", "flag", LightIngressFlag.Name)
}
if ctx.IsSet(LightEgressFlag.Name) {
log.Warn("The light server has been deprecated, please remove this flag", "flag", LightEgressFlag.Name)
}
if ctx.IsSet(LightMaxPeersFlag.Name) {
log.Warn("The light server has been deprecated, please remove this flag", "flag", LightMaxPeersFlag.Name)
}
if ctx.IsSet(LightNoPruneFlag.Name) {
log.Warn("The light server has been deprecated, please remove this flag", "flag", LightNoPruneFlag.Name)
}
if ctx.IsSet(LightNoSyncServeFlag.Name) {
log.Warn("The light server has been deprecated, please remove this flag", "flag", LightNoSyncServeFlag.Name)
}
}
// MakeDatabaseHandles raises out the number of allowed file handles per process
// for Geth and returns half of the allowance to assign to the database.
func MakeDatabaseHandles(max int) int {
@ -1582,7 +1572,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
setBlobPool(ctx, &cfg.BlobPool)
setMiner(ctx, &cfg.Miner)
setRequiredBlocks(ctx, cfg)
setLes(ctx, cfg)
// Cap the cache allowance and tune the garbage collector
mem, err := gopsutil.VirtualMemory()
@ -1630,6 +1619,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
if ctx.IsSet(AncientFlag.Name) {
cfg.DatabaseFreezer = ctx.String(AncientFlag.Name)
}
if ctx.IsSet(EraFlag.Name) {
cfg.DatabaseEra = ctx.String(EraFlag.Name)
}
if gcmode := ctx.String(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
@ -1669,11 +1661,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
cfg.TransactionHistory = 0
log.Warn("Disabled transaction unindexing for archive node")
}
if cfg.StateScheme != rawdb.HashScheme {
cfg.StateScheme = rawdb.HashScheme
log.Warn("Forcing hash state-scheme for archive mode")
}
}
if ctx.IsSet(LogHistoryFlag.Name) {
cfg.LogHistory = ctx.Uint64(LogHistoryFlag.Name)
@ -1792,9 +1779,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
} else if accs := ks.Accounts(); len(accs) > 0 {
developer = ks.Accounts()[0]
} else {
developer, err = ks.NewAccount(passphrase)
developer, err = ks.ImportECDSA(DeveloperKey, passphrase)
if err != nil {
Fatalf("Failed to create developer account: %v", err)
Fatalf("Failed to import developer account: %v", err)
}
}
// Make sure the address is configured as fee recipient, otherwise
@ -1809,14 +1796,18 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
}
log.Info("Using developer account", "address", developer.Address)
// Create a new developer genesis block or reuse existing one
// configure default developer genesis which will be used unless a
// datadir is specified and a chain is preexisting at that location.
cfg.Genesis = core.DeveloperGenesisBlock(ctx.Uint64(DeveloperGasLimitFlag.Name), &developer.Address)
// If a datadir is specified, ensure that any preexisting chain in that location
// has a configuration that is compatible with dev mode: it must be merged at genesis.
if ctx.IsSet(DataDirFlag.Name) {
chaindb := tryMakeReadOnlyDatabase(ctx, stack)
if rawdb.ReadCanonicalHash(chaindb, 0) != (common.Hash{}) {
cfg.Genesis = nil // fallback to db content
// signal fallback to preexisting chain on disk
cfg.Genesis = nil
//validate genesis has PoS enabled in block 0
genesis, err := core.ReadGenesis(chaindb)
if err != nil {
Fatalf("Could not read genesis from database: %v", err)
@ -1900,11 +1891,11 @@ func MakeBeaconLightConfig(ctx *cli.Context) bparams.ClientConfig {
if c, err := hexutil.Decode(ctx.String(BeaconGenesisRootFlag.Name)); err == nil && len(c) <= 32 {
copy(config.GenesisValidatorsRoot[:len(c)], c)
} else {
Fatalf("Invalid hex string", "beacon.genesis.gvroot", ctx.String(BeaconGenesisRootFlag.Name), "error", err)
Fatalf("Could not parse --%s: %v", BeaconGenesisRootFlag.Name, err)
}
configFile := ctx.String(BeaconConfigFlag.Name)
if err := config.ChainConfig.LoadForks(configFile); err != nil {
Fatalf("Could not load beacon chain config", "file", configFile, "error", err)
Fatalf("Could not load beacon chain config '%s': %v", configFile, err)
}
log.Info("Using custom beacon chain config", "file", configFile)
} else {
@ -1921,17 +1912,17 @@ func MakeBeaconLightConfig(ctx *cli.Context) bparams.ClientConfig {
// are saved to the specified file.
if ctx.IsSet(BeaconCheckpointFileFlag.Name) {
if _, err := config.SetCheckpointFile(ctx.String(BeaconCheckpointFileFlag.Name)); err != nil {
Fatalf("Could not load beacon checkpoint file", "beacon.checkpoint.file", ctx.String(BeaconCheckpointFileFlag.Name), "error", err)
Fatalf("Could not load beacon checkpoint file '%s': %v", ctx.String(BeaconCheckpointFileFlag.Name), err)
}
}
if ctx.IsSet(BeaconCheckpointFlag.Name) {
hex := ctx.String(BeaconCheckpointFlag.Name)
c, err := hexutil.Decode(hex)
if err != nil {
Fatalf("Invalid hex string", "beacon.checkpoint", hex, "error", err)
Fatalf("Could not parse --%s: %v", BeaconCheckpointFlag.Name, err)
}
if len(c) != 32 {
Fatalf("Invalid hex string length", "beacon.checkpoint", hex, "length", len(c))
Fatalf("Could not parse --%s: invalid length %d, want 32", BeaconCheckpointFlag.Name, len(c))
}
copy(config.Checkpoint[:len(c)], c)
}
@ -2043,7 +2034,6 @@ func SetupMetrics(cfg *metrics.Config) {
log.Info("Enabling metrics export to InfluxDB")
go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", tagsMap)
} else if enableExportV2 {
tagsMap := SplitTagsFlag(cfg.InfluxDBTags)
log.Info("Enabling metrics export to InfluxDB (v2)")
go influxdb.InfluxDBV2WithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, token, bucket, organization, "geth.", tagsMap)
}
@ -2096,7 +2086,15 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb.
}
chainDb = remotedb.New(client)
default:
chainDb, err = stack.OpenDatabaseWithFreezer("chaindata", cache, handles, ctx.String(AncientFlag.Name), "eth/db/chaindata/", readonly)
options := node.DatabaseOptions{
ReadOnly: readonly,
Cache: cache,
Handles: handles,
AncientsDirectory: ctx.String(AncientFlag.Name),
MetricsNamespace: "eth/db/chaindata/",
EraDirectory: ctx.String(EraFlag.Name),
}
chainDb, err = stack.OpenDatabaseWithOptions("chaindata", options)
}
if err != nil {
Fatalf("Could not open database: %v", err)
@ -2188,36 +2186,38 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
if err != nil {
Fatalf("%v", err)
}
cache := &core.CacheConfig{
options := &core.BlockChainConfig{
TrieCleanLimit: ethconfig.Defaults.TrieCleanCache,
TrieCleanNoPrefetch: ctx.Bool(CacheNoPrefetchFlag.Name),
NoPrefetch: ctx.Bool(CacheNoPrefetchFlag.Name),
TrieDirtyLimit: ethconfig.Defaults.TrieDirtyCache,
TrieDirtyDisabled: ctx.String(GCModeFlag.Name) == "archive",
ArchiveMode: ctx.String(GCModeFlag.Name) == "archive",
TrieTimeLimit: ethconfig.Defaults.TrieTimeout,
SnapshotLimit: ethconfig.Defaults.SnapshotCache,
Preimages: ctx.Bool(CachePreimagesFlag.Name),
StateScheme: scheme,
StateHistory: ctx.Uint64(StateHistoryFlag.Name),
// Disable transaction indexing/unindexing.
TxLookupLimit: -1,
}
if cache.TrieDirtyDisabled && !cache.Preimages {
cache.Preimages = true
if options.ArchiveMode && !options.Preimages {
options.Preimages = true
log.Info("Enabling recording of key preimages since archive mode is used")
}
if !ctx.Bool(SnapshotFlag.Name) {
cache.SnapshotLimit = 0 // Disabled
options.SnapshotLimit = 0 // Disabled
} else if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheSnapshotFlag.Name) {
cache.SnapshotLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheSnapshotFlag.Name) / 100
options.SnapshotLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheSnapshotFlag.Name) / 100
}
// If we're in readonly, do not bother generating snapshot data.
if readonly {
cache.SnapshotNoBuild = true
options.SnapshotNoBuild = true
}
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheTrieFlag.Name) {
cache.TrieCleanLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheTrieFlag.Name) / 100
options.TrieCleanLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheTrieFlag.Name) / 100
}
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheGCFlag.Name) {
cache.TrieDirtyLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100
options.TrieDirtyLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100
}
vmcfg := vm.Config{
EnablePreimageRecording: ctx.Bool(VMEnableDebugFlag.Name),
@ -2232,8 +2232,9 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
vmcfg.Tracer = t
}
}
// Disable transaction indexing/unindexing by default.
chain, err := core.NewBlockChain(chainDb, cache, gspec, nil, engine, vmcfg, nil)
options.VmConfig = vmcfg
chain, err := core.NewBlockChain(chainDb, gspec, engine, options)
if err != nil {
Fatalf("Can't create BlockChain: %v", err)
}

View file

@ -39,12 +39,6 @@ var DeprecatedFlags = []cli.Flag{
CacheTrieRejournalFlag,
LegacyDiscoveryV5Flag,
TxLookupLimitFlag,
LightServeFlag,
LightIngressFlag,
LightEgressFlag,
LightMaxPeersFlag,
LightNoPruneFlag,
LightNoSyncServeFlag,
LogBacktraceAtFlag,
LogDebugFlag,
MinerNewPayloadTimeoutFlag,
@ -88,37 +82,6 @@ var (
Value: ethconfig.Defaults.TransactionHistory,
Category: flags.DeprecatedCategory,
}
// Light server and client settings, Deprecated November 2023
LightServeFlag = &cli.IntFlag{
Name: "light.serve",
Usage: "Maximum percentage of time allowed for serving LES requests (deprecated)",
Category: flags.DeprecatedCategory,
}
LightIngressFlag = &cli.IntFlag{
Name: "light.ingress",
Usage: "Incoming bandwidth limit for serving light clients (deprecated)",
Category: flags.DeprecatedCategory,
}
LightEgressFlag = &cli.IntFlag{
Name: "light.egress",
Usage: "Outgoing bandwidth limit for serving light clients (deprecated)",
Category: flags.DeprecatedCategory,
}
LightMaxPeersFlag = &cli.IntFlag{
Name: "light.maxpeers",
Usage: "Maximum number of light clients to serve, or light servers to attach to (deprecated)",
Category: flags.DeprecatedCategory,
}
LightNoPruneFlag = &cli.BoolFlag{
Name: "light.nopruning",
Usage: "Disable ancient light chain data pruning (deprecated)",
Category: flags.DeprecatedCategory,
}
LightNoSyncServeFlag = &cli.BoolFlag{
Name: "light.nosyncserve",
Usage: "Enables serving light clients before syncing (deprecated)",
Category: flags.DeprecatedCategory,
}
// Deprecated November 2023
LogBacktraceAtFlag = &cli.StringFlag{
Name: "log.backtrace",

View file

@ -31,7 +31,6 @@ import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/internal/era"
"github.com/ethereum/go-ethereum/params"
@ -78,7 +77,7 @@ func TestHistoryImportAndExport(t *testing.T) {
})
// Initialize BlockChain.
chain, err := core.NewBlockChain(db, nil, genesis, nil, ethash.NewFaker(), vm.Config{}, nil)
chain, err := core.NewBlockChain(db, genesis, ethash.NewFaker(), nil)
if err != nil {
t.Fatalf("unable to initialize chain: %v", err)
}
@ -158,7 +157,7 @@ func TestHistoryImportAndExport(t *testing.T) {
}
// Now import Era.
db2, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
db2, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
if err != nil {
panic(err)
}
@ -167,7 +166,7 @@ func TestHistoryImportAndExport(t *testing.T) {
})
genesis.MustCommit(db2, triedb.NewDatabase(db2, triedb.HashDefaults))
imported, err := core.NewBlockChain(db2, nil, genesis, nil, ethash.NewFaker(), vm.Config{}, nil)
imported, err := core.NewBlockChain(db2, genesis, ethash.NewFaker(), nil)
if err != nil {
t.Fatalf("unable to initialize chain: %v", err)
}

View file

@ -26,4 +26,5 @@ the following commands (in this directory) against a synced mainnet node:
```shell
> go run . filtergen --queries queries/filter_queries_mainnet.json http://host:8545
> go run . historygen --history-tests queries/history_mainnet.json http://host:8545
> go run . tracegen --trace-tests queries/trace_mainnet.json http://host:8545
```

104
cmd/workload/client.go Normal file
View file

@ -0,0 +1,104 @@
// Copyright 2025 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package main
import (
"context"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethclient/gethclient"
"github.com/ethereum/go-ethereum/rpc"
"github.com/urfave/cli/v2"
)
type client struct {
Eth *ethclient.Client
Geth *gethclient.Client
RPC *rpc.Client
}
func makeClient(ctx *cli.Context) *client {
if ctx.NArg() < 1 {
exit("missing RPC endpoint URL as command-line argument")
}
url := ctx.Args().First()
cl, err := rpc.Dial(url)
if err != nil {
exit(fmt.Errorf("could not create RPC client at %s: %v", url, err))
}
return &client{
RPC: cl,
Eth: ethclient.NewClient(cl),
Geth: gethclient.New(cl),
}
}
type simpleBlock struct {
Number hexutil.Uint64 `json:"number"`
Hash common.Hash `json:"hash"`
}
type simpleTransaction struct {
Hash common.Hash `json:"hash"`
TransactionIndex hexutil.Uint64 `json:"transactionIndex"`
}
func (c *client) getBlockByHash(ctx context.Context, arg common.Hash, fullTx bool) (*simpleBlock, error) {
var r *simpleBlock
err := c.RPC.CallContext(ctx, &r, "eth_getBlockByHash", arg, fullTx)
return r, err
}
func (c *client) getBlockByNumber(ctx context.Context, arg uint64, fullTx bool) (*simpleBlock, error) {
var r *simpleBlock
err := c.RPC.CallContext(ctx, &r, "eth_getBlockByNumber", hexutil.Uint64(arg), fullTx)
return r, err
}
func (c *client) getTransactionByBlockHashAndIndex(ctx context.Context, block common.Hash, index uint64) (*simpleTransaction, error) {
var r *simpleTransaction
err := c.RPC.CallContext(ctx, &r, "eth_getTransactionByBlockHashAndIndex", block, hexutil.Uint64(index))
return r, err
}
func (c *client) getTransactionByBlockNumberAndIndex(ctx context.Context, block uint64, index uint64) (*simpleTransaction, error) {
var r *simpleTransaction
err := c.RPC.CallContext(ctx, &r, "eth_getTransactionByBlockNumberAndIndex", hexutil.Uint64(block), hexutil.Uint64(index))
return r, err
}
func (c *client) getBlockTransactionCountByHash(ctx context.Context, block common.Hash) (uint64, error) {
var r hexutil.Uint64
err := c.RPC.CallContext(ctx, &r, "eth_getBlockTransactionCountByHash", block)
return uint64(r), err
}
func (c *client) getBlockTransactionCountByNumber(ctx context.Context, block uint64) (uint64, error) {
var r hexutil.Uint64
err := c.RPC.CallContext(ctx, &r, "eth_getBlockTransactionCountByNumber", hexutil.Uint64(block))
return uint64(r), err
}
func (c *client) getBlockReceipts(ctx context.Context, arg any) ([]*types.Receipt, error) {
var result []*types.Receipt
err := c.RPC.CallContext(ctx, &result, "eth_getBlockReceipts", arg)
return result, err
}

View file

@ -45,11 +45,11 @@ func newFilterTestSuite(cfg testConfig) *filterTestSuite {
return s
}
func (s *filterTestSuite) allTests() []utesting.Test {
return []utesting.Test{
{Name: "Filter/ShortRange", Fn: s.filterShortRange},
{Name: "Filter/LongRange", Fn: s.filterLongRange, Slow: true},
{Name: "Filter/FullRange", Fn: s.filterFullRange, Slow: true},
func (s *filterTestSuite) allTests() []workloadTest {
return []workloadTest{
newWorkLoadTest("Filter/ShortRange", s.filterShortRange),
newSlowWorkloadTest("Filter/LongRange", s.filterLongRange),
newSlowWorkloadTest("Filter/FullRange", s.filterFullRange),
}
}

View file

@ -23,7 +23,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/internal/utesting"
)
@ -65,40 +64,16 @@ func (s *historyTestSuite) loadTests() error {
return nil
}
func (s *historyTestSuite) allTests() []utesting.Test {
return []utesting.Test{
{
Name: "History/getBlockByHash",
Fn: s.testGetBlockByHash,
},
{
Name: "History/getBlockByNumber",
Fn: s.testGetBlockByNumber,
},
{
Name: "History/getBlockReceiptsByHash",
Fn: s.testGetBlockReceiptsByHash,
},
{
Name: "History/getBlockReceiptsByNumber",
Fn: s.testGetBlockReceiptsByNumber,
},
{
Name: "History/getBlockTransactionCountByHash",
Fn: s.testGetBlockTransactionCountByHash,
},
{
Name: "History/getBlockTransactionCountByNumber",
Fn: s.testGetBlockTransactionCountByNumber,
},
{
Name: "History/getTransactionByBlockHashAndIndex",
Fn: s.testGetTransactionByBlockHashAndIndex,
},
{
Name: "History/getTransactionByBlockNumberAndIndex",
Fn: s.testGetTransactionByBlockNumberAndIndex,
},
func (s *historyTestSuite) allTests() []workloadTest {
return []workloadTest{
newWorkLoadTest("History/getBlockByHash", s.testGetBlockByHash),
newWorkLoadTest("History/getBlockByNumber", s.testGetBlockByNumber),
newWorkLoadTest("History/getBlockReceiptsByHash", s.testGetBlockReceiptsByHash),
newWorkLoadTest("History/getBlockReceiptsByNumber", s.testGetBlockReceiptsByNumber),
newWorkLoadTest("History/getBlockTransactionCountByHash", s.testGetBlockTransactionCountByHash),
newWorkLoadTest("History/getBlockTransactionCountByNumber", s.testGetBlockTransactionCountByNumber),
newWorkLoadTest("History/getTransactionByBlockHashAndIndex", s.testGetTransactionByBlockHashAndIndex),
newWorkLoadTest("History/getTransactionByBlockNumberAndIndex", s.testGetTransactionByBlockNumberAndIndex),
}
}
@ -279,55 +254,3 @@ func (s *historyTestSuite) testGetTransactionByBlockNumberAndIndex(t *utesting.T
}
}
}
type simpleBlock struct {
Number hexutil.Uint64 `json:"number"`
Hash common.Hash `json:"hash"`
}
type simpleTransaction struct {
Hash common.Hash `json:"hash"`
TransactionIndex hexutil.Uint64 `json:"transactionIndex"`
}
func (c *client) getBlockByHash(ctx context.Context, arg common.Hash, fullTx bool) (*simpleBlock, error) {
var r *simpleBlock
err := c.RPC.CallContext(ctx, &r, "eth_getBlockByHash", arg, fullTx)
return r, err
}
func (c *client) getBlockByNumber(ctx context.Context, arg uint64, fullTx bool) (*simpleBlock, error) {
var r *simpleBlock
err := c.RPC.CallContext(ctx, &r, "eth_getBlockByNumber", hexutil.Uint64(arg), fullTx)
return r, err
}
func (c *client) getTransactionByBlockHashAndIndex(ctx context.Context, block common.Hash, index uint64) (*simpleTransaction, error) {
var r *simpleTransaction
err := c.RPC.CallContext(ctx, &r, "eth_getTransactionByBlockHashAndIndex", block, hexutil.Uint64(index))
return r, err
}
func (c *client) getTransactionByBlockNumberAndIndex(ctx context.Context, block uint64, index uint64) (*simpleTransaction, error) {
var r *simpleTransaction
err := c.RPC.CallContext(ctx, &r, "eth_getTransactionByBlockNumberAndIndex", hexutil.Uint64(block), hexutil.Uint64(index))
return r, err
}
func (c *client) getBlockTransactionCountByHash(ctx context.Context, block common.Hash) (uint64, error) {
var r hexutil.Uint64
err := c.RPC.CallContext(ctx, &r, "eth_getBlockTransactionCountByHash", block)
return uint64(r), err
}
func (c *client) getBlockTransactionCountByNumber(ctx context.Context, block uint64) (uint64, error) {
var r hexutil.Uint64
err := c.RPC.CallContext(ctx, &r, "eth_getBlockTransactionCountByNumber", hexutil.Uint64(block))
return uint64(r), err
}
func (c *client) getBlockReceipts(ctx context.Context, arg any) ([]*types.Receipt, error) {
var result []*types.Receipt
err := c.RPC.CallContext(ctx, &result, "eth_getBlockReceipts", arg)
return result, err
}

View file

@ -51,7 +51,7 @@ var (
}
historyTestEarliestFlag = &cli.IntFlag{
Name: "earliest",
Usage: "JSON file containing filter test queries",
Usage: "The earliest block to test queries",
Value: 0,
Category: flags.TestingCategory,
}
@ -139,7 +139,7 @@ func calcReceiptsHash(rcpt []*types.Receipt) common.Hash {
func writeJSON(fileName string, value any) {
file, err := os.Create(fileName)
if err != nil {
exit(fmt.Errorf("Error creating %s: %v", fileName, err))
exit(fmt.Errorf("error creating %s: %v", fileName, err))
return
}
defer file.Close()

View file

@ -20,10 +20,8 @@ import (
"fmt"
"os"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/internal/debug"
"github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/rpc"
"github.com/urfave/cli/v2"
)
@ -49,6 +47,7 @@ func init() {
runTestCommand,
historyGenerateCommand,
filterGenerateCommand,
traceGenerateCommand,
filterPerfCommand,
}
}
@ -57,26 +56,6 @@ func main() {
exit(app.Run(os.Args))
}
type client struct {
Eth *ethclient.Client
RPC *rpc.Client
}
func makeClient(ctx *cli.Context) *client {
if ctx.NArg() < 1 {
exit("missing RPC endpoint URL as command-line argument")
}
url := ctx.Args().First()
cl, err := rpc.Dial(url)
if err != nil {
exit(fmt.Errorf("Could not create RPC client at %s: %v", url, err))
}
return &client{
RPC: cl,
Eth: ethclient.NewClient(cl),
}
}
func exit(err any) {
if err == nil {
os.Exit(0)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -21,7 +21,6 @@ import (
"fmt"
"io/fs"
"os"
"slices"
"github.com/ethereum/go-ethereum/core/history"
"github.com/ethereum/go-ethereum/internal/flags"
@ -45,10 +44,13 @@ var (
testPatternFlag,
testTAPFlag,
testSlowFlag,
testArchiveFlag,
testSepoliaFlag,
testMainnetFlag,
filterQueryFileFlag,
historyTestFileFlag,
traceTestFileFlag,
traceTestInvalidOutputFlag,
},
}
testPatternFlag = &cli.StringFlag{
@ -67,6 +69,12 @@ var (
Value: false,
Category: flags.TestingCategory,
}
testArchiveFlag = &cli.BoolFlag{
Name: "archive",
Usage: "Enable archive tests",
Value: false,
Category: flags.TestingCategory,
}
testSepoliaFlag = &cli.BoolFlag{
Name: "sepolia",
Usage: "Use test cases for sepolia network",
@ -86,6 +94,7 @@ type testConfig struct {
filterQueryFile string
historyTestFile string
historyPruneBlock *uint64
traceTestFile string
}
var errPrunedHistory = fmt.Errorf("attempt to access pruned history")
@ -125,36 +134,85 @@ func testConfigFromCLI(ctx *cli.Context) (cfg testConfig) {
cfg.historyTestFile = "queries/history_mainnet.json"
cfg.historyPruneBlock = new(uint64)
*cfg.historyPruneBlock = history.PrunePoints[params.MainnetGenesisHash].BlockNumber
cfg.traceTestFile = "queries/trace_mainnet.json"
case ctx.Bool(testSepoliaFlag.Name):
cfg.fsys = builtinTestFiles
cfg.filterQueryFile = "queries/filter_queries_sepolia.json"
cfg.historyTestFile = "queries/history_sepolia.json"
cfg.historyPruneBlock = new(uint64)
*cfg.historyPruneBlock = history.PrunePoints[params.SepoliaGenesisHash].BlockNumber
cfg.traceTestFile = "queries/trace_sepolia.json"
default:
cfg.fsys = os.DirFS(".")
cfg.filterQueryFile = ctx.String(filterQueryFileFlag.Name)
cfg.historyTestFile = ctx.String(historyTestFileFlag.Name)
cfg.traceTestFile = ctx.String(traceTestFileFlag.Name)
}
return cfg
}
// workloadTest represents a single test in the workload. It's a wrapper
// of utesting.Test by adding a few additional attributes.
type workloadTest struct {
utesting.Test
archive bool // Flag whether the archive node (full state history) is required for this test
}
func newWorkLoadTest(name string, fn func(t *utesting.T)) workloadTest {
return workloadTest{
Test: utesting.Test{
Name: name,
Fn: fn,
},
}
}
func newSlowWorkloadTest(name string, fn func(t *utesting.T)) workloadTest {
t := newWorkLoadTest(name, fn)
t.Slow = true
return t
}
func newArchiveWorkloadTest(name string, fn func(t *utesting.T)) workloadTest {
t := newWorkLoadTest(name, fn)
t.archive = true
return t
}
func filterTests(tests []workloadTest, pattern string, filterFn func(t workloadTest) bool) []utesting.Test {
var utests []utesting.Test
for _, t := range tests {
if filterFn(t) {
utests = append(utests, t.Test)
}
}
if pattern == "" {
return utests
}
return utesting.MatchTests(utests, pattern)
}
func runTestCmd(ctx *cli.Context) error {
cfg := testConfigFromCLI(ctx)
filterSuite := newFilterTestSuite(cfg)
historySuite := newHistoryTestSuite(cfg)
traceSuite := newTraceTestSuite(cfg, ctx)
// Filter test cases.
tests := filterSuite.allTests()
tests = append(tests, historySuite.allTests()...)
if ctx.IsSet(testPatternFlag.Name) {
tests = utesting.MatchTests(tests, ctx.String(testPatternFlag.Name))
tests = append(tests, traceSuite.allTests()...)
utests := filterTests(tests, ctx.String(testPatternFlag.Name), func(t workloadTest) bool {
if t.Slow && !ctx.Bool(testSlowFlag.Name) {
return false
}
if !ctx.Bool(testSlowFlag.Name) {
tests = slices.DeleteFunc(tests, func(test utesting.Test) bool {
return test.Slow
if t.archive && !ctx.Bool(testArchiveFlag.Name) {
return false
}
return true
})
}
// Disable logging unless explicitly enabled.
if !ctx.IsSet("verbosity") && !ctx.IsSet("vmodule") {
@ -166,7 +224,7 @@ func runTestCmd(ctx *cli.Context) error {
if ctx.Bool(testTAPFlag.Name) {
run = utesting.RunTAP
}
results := run(tests, os.Stdout)
results := run(utests, os.Stdout)
if utesting.CountFailures(results) > 0 {
os.Exit(1)
}

126
cmd/workload/tracetest.go Normal file
View file

@ -0,0 +1,126 @@
// Copyright 2025 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package main
import (
"context"
"encoding/json"
"fmt"
"os"
"path/filepath"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/internal/utesting"
"github.com/ethereum/go-ethereum/log"
"github.com/urfave/cli/v2"
)
// traceTest is the content of a history test.
type traceTest struct {
TxHashes []common.Hash `json:"txHashes"`
TraceConfigs []tracers.TraceConfig `json:"traceConfigs"`
ResultHashes []common.Hash `json:"resultHashes"`
}
type traceTestSuite struct {
cfg testConfig
tests traceTest
invalidDir string
}
func newTraceTestSuite(cfg testConfig, ctx *cli.Context) *traceTestSuite {
s := &traceTestSuite{
cfg: cfg,
invalidDir: ctx.String(traceTestInvalidOutputFlag.Name),
}
if err := s.loadTests(); err != nil {
exit(err)
}
return s
}
func (s *traceTestSuite) loadTests() error {
file, err := s.cfg.fsys.Open(s.cfg.traceTestFile)
if err != nil {
return fmt.Errorf("can't open traceTestFile: %v", err)
}
defer file.Close()
if err := json.NewDecoder(file).Decode(&s.tests); err != nil {
return fmt.Errorf("invalid JSON in %s: %v", s.cfg.traceTestFile, err)
}
if len(s.tests.TxHashes) == 0 {
return fmt.Errorf("traceTestFile %s has no test data", s.cfg.traceTestFile)
}
return nil
}
func (s *traceTestSuite) allTests() []workloadTest {
return []workloadTest{
newArchiveWorkloadTest("Trace/Transaction", s.traceTransaction),
}
}
// traceTransaction runs all transaction tracing tests
func (s *traceTestSuite) traceTransaction(t *utesting.T) {
ctx := context.Background()
for i, hash := range s.tests.TxHashes {
config := s.tests.TraceConfigs[i]
result, err := s.cfg.client.Geth.TraceTransaction(ctx, hash, &config)
if err != nil {
t.Fatalf("Transaction %d (hash %v): error %v", i, hash, err)
}
blob, err := json.Marshal(result)
if err != nil {
t.Fatalf("Transaction %d (hash %v): error %v", i, hash, err)
continue
}
if crypto.Keccak256Hash(blob) != s.tests.ResultHashes[i] {
t.Errorf("Transaction %d (hash %v): invalid result", i, hash)
writeInvalidTraceResult(s.invalidDir, hash, result)
}
}
}
func writeInvalidTraceResult(dir string, hash common.Hash, result any) {
if dir == "" {
return
}
err := os.MkdirAll(dir, os.ModePerm)
if err != nil {
log.Info("Failed to make output directory", "err", err)
return
}
name := filepath.Join(dir, "invalid"+"_"+hash.String())
file, err := os.Create(name)
if err != nil {
exit(fmt.Errorf("error creating %s: %v", name, err))
return
}
defer file.Close()
data, _ := json.MarshalIndent(result, "", " ")
_, err = file.Write(data)
if err != nil {
exit(fmt.Errorf("error writing %s: %v", name, err))
return
}
}

View file

@ -0,0 +1,195 @@
// Copyright 2025 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>
package main
import (
"context"
"encoding/json"
"fmt"
"math/big"
"math/rand"
"os"
"path/filepath"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/eth/tracers/logger"
"github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/log"
"github.com/urfave/cli/v2"
)
var (
defaultBlocksToTrace = 64 // the number of states assumed to be available
traceGenerateCommand = &cli.Command{
Name: "tracegen",
Usage: "Generates tests for state tracing",
ArgsUsage: "<RPC endpoint URL>",
Action: generateTraceTests,
Flags: []cli.Flag{
traceTestFileFlag,
traceTestResultOutputFlag,
traceTestBlockFlag,
},
}
traceTestFileFlag = &cli.StringFlag{
Name: "trace-tests",
Usage: "JSON file containing trace test queries",
Value: "trace_tests.json",
Category: flags.TestingCategory,
}
traceTestResultOutputFlag = &cli.StringFlag{
Name: "trace-output",
Usage: "Folder containing the trace output files",
Value: "",
Category: flags.TestingCategory,
}
traceTestBlockFlag = &cli.IntFlag{
Name: "trace-blocks",
Usage: "The number of blocks for tracing",
Value: defaultBlocksToTrace,
Category: flags.TestingCategory,
}
traceTestInvalidOutputFlag = &cli.StringFlag{
Name: "trace-invalid",
Usage: "Folder containing the mismatched trace output files",
Value: "",
Category: flags.TestingCategory,
}
)
func generateTraceTests(clictx *cli.Context) error {
var (
client = makeClient(clictx)
outputFile = clictx.String(traceTestFileFlag.Name)
outputDir = clictx.String(traceTestResultOutputFlag.Name)
blocks = clictx.Int(traceTestBlockFlag.Name)
ctx = context.Background()
test = new(traceTest)
)
if outputDir != "" {
err := os.MkdirAll(outputDir, os.ModePerm)
if err != nil {
return err
}
}
latest, err := client.Eth.BlockNumber(ctx)
if err != nil {
exit(err)
}
if latest < uint64(blocks) {
exit(fmt.Errorf("node seems not synced, latest block is %d", latest))
}
// Get blocks and assign block info into the test
var (
start = time.Now()
logged = time.Now()
failed int
)
log.Info("Trace transactions around the chain tip", "head", latest, "blocks", blocks)
for i := 0; i < blocks; i++ {
number := latest - uint64(i)
block, err := client.Eth.BlockByNumber(ctx, big.NewInt(int64(number)))
if err != nil {
exit(err)
}
for _, tx := range block.Transactions() {
config, configName := randomTraceOption()
result, err := client.Geth.TraceTransaction(ctx, tx.Hash(), config)
if err != nil {
failed += 1
break
}
blob, err := json.Marshal(result)
if err != nil {
failed += 1
break
}
test.TxHashes = append(test.TxHashes, tx.Hash())
test.TraceConfigs = append(test.TraceConfigs, *config)
test.ResultHashes = append(test.ResultHashes, crypto.Keccak256Hash(blob))
writeTraceResult(outputDir, tx.Hash(), result, configName)
}
if time.Since(logged) > time.Second*8 {
logged = time.Now()
log.Info("Tracing transactions", "executed", len(test.TxHashes), "failed", failed, "elapsed", common.PrettyDuration(time.Since(start)))
}
}
log.Info("Traced transactions", "executed", len(test.TxHashes), "failed", failed, "elapsed", common.PrettyDuration(time.Since(start)))
// Write output file.
writeJSON(outputFile, test)
return nil
}
func randomTraceOption() (*tracers.TraceConfig, string) {
x := rand.Intn(11)
if x == 0 {
// struct-logger, with all fields enabled, very heavy
return &tracers.TraceConfig{
Config: &logger.Config{
EnableMemory: true,
EnableReturnData: true,
},
}, "structAll"
}
if x == 1 {
// default options for struct-logger, with stack and storage capture
// enabled
return &tracers.TraceConfig{
Config: &logger.Config{},
}, "structDefault"
}
if x == 2 || x == 3 || x == 4 {
// struct-logger with storage capture enabled
return &tracers.TraceConfig{
Config: &logger.Config{
DisableStack: true,
},
}, "structStorage"
}
// Native tracer
loggers := []string{"callTracer", "4byteTracer", "flatCallTracer", "muxTracer", "noopTracer", "prestateTracer"}
return &tracers.TraceConfig{
Tracer: &loggers[x-5],
}, loggers[x-5]
}
func writeTraceResult(dir string, hash common.Hash, result any, configName string) {
if dir == "" {
return
}
name := filepath.Join(dir, configName+"_"+hash.String())
file, err := os.Create(name)
if err != nil {
exit(fmt.Errorf("error creating %s: %v", name, err))
return
}
defer file.Close()
data, _ := json.MarshalIndent(result, "", " ")
_, err = file.Write(data)
if err != nil {
exit(fmt.Errorf("error writing %s: %v", name, err))
return
}
}

View file

@ -47,30 +47,37 @@ func NewBasicLRU[K comparable, V any](capacity int) BasicLRU[K, V] {
// Add adds a value to the cache. Returns true if an item was evicted to store the new item.
func (c *BasicLRU[K, V]) Add(key K, value V) (evicted bool) {
_, _, evicted = c.Add3(key, value)
return evicted
}
// Add3 adds a value to the cache. If an item was evicted to store the new one, it returns the evicted item.
func (c *BasicLRU[K, V]) Add3(key K, value V) (ek K, ev V, evicted bool) {
item, ok := c.items[key]
if ok {
// Already exists in cache.
item.value = value
c.items[key] = item
c.list.moveToFront(item.elem)
return false
return ek, ev, false
}
var elem *listElem[K]
if c.Len() >= c.cap {
elem = c.list.removeLast()
delete(c.items, elem.v)
evicted = true
ek = elem.v
ev = c.items[ek].value
delete(c.items, ek)
} else {
elem = new(listElem[K])
}
// Store the new item.
// Note that, if another item was evicted, we re-use its list element here.
// Note that if another item was evicted, we re-use its list element here.
elem.v = key
c.items[key] = cacheItem[K, V]{elem, value}
c.list.pushElem(elem)
return evicted
return ek, ev, evicted
}
// Contains reports whether the given key exists in the cache.

View file

@ -30,7 +30,6 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/trie"
"github.com/holiman/uint256"
)
@ -392,8 +391,12 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
if err != nil {
return nil, fmt.Errorf("error opening pre-state tree root: %w", err)
}
postTrie := state.GetTrie()
if postTrie == nil {
return nil, errors.New("post-state tree is not available")
}
vktPreTrie, okpre := preTrie.(*trie.VerkleTrie)
vktPostTrie, okpost := state.GetTrie().(*trie.VerkleTrie)
vktPostTrie, okpost := postTrie.(*trie.VerkleTrie)
// The witness is only attached iff both parent and current block are
// using verkle tree.
@ -445,11 +448,6 @@ func (beacon *Beacon) CalcDifficulty(chain consensus.ChainHeaderReader, time uin
return beaconDifficulty
}
// APIs implements consensus.Engine, returning the user facing RPC APIs.
func (beacon *Beacon) APIs(chain consensus.ChainHeaderReader) []rpc.API {
return beacon.ethone.APIs(chain)
}
// Close shutdowns the consensus engine
func (beacon *Beacon) Close() error {
return beacon.ethone.Close()

View file

@ -1,235 +0,0 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum 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 go-ethereum 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 go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package clique
import (
"encoding/json"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
)
// API is a user facing RPC API to allow controlling the signer and voting
// mechanisms of the proof-of-authority scheme.
type API struct {
chain consensus.ChainHeaderReader
clique *Clique
}
// GetSnapshot retrieves the state snapshot at a given block.
func (api *API) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) {
// Retrieve the requested block number (or current if none requested)
var header *types.Header
if number == nil || *number == rpc.LatestBlockNumber {
header = api.chain.CurrentHeader()
} else {
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
}
// Ensure we have an actually valid block and return its snapshot
if header == nil {
return nil, errUnknownBlock
}
return api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
}
// GetSnapshotAtHash retrieves the state snapshot at a given block.
func (api *API) GetSnapshotAtHash(hash common.Hash) (*Snapshot, error) {
header := api.chain.GetHeaderByHash(hash)
if header == nil {
return nil, errUnknownBlock
}
return api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
}
// GetSigners retrieves the list of authorized signers at the specified block.
func (api *API) GetSigners(number *rpc.BlockNumber) ([]common.Address, error) {
// Retrieve the requested block number (or current if none requested)
var header *types.Header
if number == nil || *number == rpc.LatestBlockNumber {
header = api.chain.CurrentHeader()
} else {
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
}
// Ensure we have an actually valid block and return the signers from its snapshot
if header == nil {
return nil, errUnknownBlock
}
snap, err := api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
if err != nil {
return nil, err
}
return snap.signers(), nil
}
// GetSignersAtHash retrieves the list of authorized signers at the specified block.
func (api *API) GetSignersAtHash(hash common.Hash) ([]common.Address, error) {
header := api.chain.GetHeaderByHash(hash)
if header == nil {
return nil, errUnknownBlock
}
snap, err := api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
if err != nil {
return nil, err
}
return snap.signers(), nil
}
// Proposals returns the current proposals the node tries to uphold and vote on.
func (api *API) Proposals() map[common.Address]bool {
api.clique.lock.RLock()
defer api.clique.lock.RUnlock()
proposals := make(map[common.Address]bool)
for address, auth := range api.clique.proposals {
proposals[address] = auth
}
return proposals
}
// Propose injects a new authorization proposal that the signer will attempt to
// push through.
func (api *API) Propose(address common.Address, auth bool) {
api.clique.lock.Lock()
defer api.clique.lock.Unlock()
api.clique.proposals[address] = auth
}
// Discard drops a currently running proposal, stopping the signer from casting
// further votes (either for or against).
func (api *API) Discard(address common.Address) {
api.clique.lock.Lock()
defer api.clique.lock.Unlock()
delete(api.clique.proposals, address)
}
type status struct {
InturnPercent float64 `json:"inturnPercent"`
SigningStatus map[common.Address]int `json:"sealerActivity"`
NumBlocks uint64 `json:"numBlocks"`
}
// Status returns the status of the last N blocks,
// - the number of active signers,
// - the number of signers,
// - the percentage of in-turn blocks
func (api *API) Status() (*status, error) {
var (
numBlocks = uint64(64)
header = api.chain.CurrentHeader()
diff = uint64(0)
optimals = 0
)
snap, err := api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
if err != nil {
return nil, err
}
var (
signers = snap.signers()
end = header.Number.Uint64()
start = end - numBlocks
)
if numBlocks > end {
start = 1
numBlocks = end - start
}
signStatus := make(map[common.Address]int)
for _, s := range signers {
signStatus[s] = 0
}
for n := start; n < end; n++ {
h := api.chain.GetHeaderByNumber(n)
if h == nil {
return nil, fmt.Errorf("missing block %d", n)
}
if h.Difficulty.Cmp(diffInTurn) == 0 {
optimals++
}
diff += h.Difficulty.Uint64()
sealer, err := api.clique.Author(h)
if err != nil {
return nil, err
}
signStatus[sealer]++
}
return &status{
InturnPercent: float64(100*optimals) / float64(numBlocks),
SigningStatus: signStatus,
NumBlocks: numBlocks,
}, nil
}
type blockNumberOrHashOrRLP struct {
*rpc.BlockNumberOrHash
RLP hexutil.Bytes `json:"rlp,omitempty"`
}
func (sb *blockNumberOrHashOrRLP) UnmarshalJSON(data []byte) error {
bnOrHash := new(rpc.BlockNumberOrHash)
// Try to unmarshal bNrOrHash
if err := bnOrHash.UnmarshalJSON(data); err == nil {
sb.BlockNumberOrHash = bnOrHash
return nil
}
// Try to unmarshal RLP
var input string
if err := json.Unmarshal(data, &input); err != nil {
return err
}
blob, err := hexutil.Decode(input)
if err != nil {
return err
}
sb.RLP = blob
return nil
}
// GetSigner returns the signer for a specific clique block.
// Can be called with a block number, a block hash or a rlp encoded blob.
// The RLP encoded blob can either be a block or a header.
func (api *API) GetSigner(rlpOrBlockNr *blockNumberOrHashOrRLP) (common.Address, error) {
if len(rlpOrBlockNr.RLP) == 0 {
blockNrOrHash := rlpOrBlockNr.BlockNumberOrHash
var header *types.Header
if blockNrOrHash == nil {
header = api.chain.CurrentHeader()
} else if hash, ok := blockNrOrHash.Hash(); ok {
header = api.chain.GetHeaderByHash(hash)
} else if number, ok := blockNrOrHash.Number(); ok {
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
}
if header == nil {
return common.Address{}, fmt.Errorf("missing block %v", blockNrOrHash.String())
}
return api.clique.Author(header)
}
block := new(types.Block)
if err := rlp.DecodeBytes(rlpOrBlockNr.RLP, block); err == nil {
return api.clique.Author(block.Header())
}
header := new(types.Header)
if err := rlp.DecodeBytes(rlpOrBlockNr.RLP, header); err != nil {
return common.Address{}, err
}
return api.clique.Author(header)
}

View file

@ -41,7 +41,6 @@ import (
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/trie"
"golang.org/x/crypto/sha3"
)
@ -641,15 +640,6 @@ func (c *Clique) Close() error {
return nil
}
// APIs implements consensus.Engine, returning the user facing RPC API to allow
// controlling the signer voting.
func (c *Clique) APIs(chain consensus.ChainHeaderReader) []rpc.API {
return []rpc.API{{
Namespace: "clique",
Service: &API{chain: chain, clique: c},
}}
}
// SealHash returns the hash of a block prior to it being sealed.
func SealHash(header *types.Header) (hash common.Hash) {
hasher := sha3.NewLegacyKeccak256()

View file

@ -24,7 +24,6 @@ import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
)
@ -55,7 +54,7 @@ func TestReimportMirroredState(t *testing.T) {
copy(genspec.ExtraData[extraVanity:], addr[:])
// Generate a batch of blocks, each properly signed
chain, _ := core.NewBlockChain(rawdb.NewMemoryDatabase(), nil, genspec, nil, engine, vm.Config{}, nil)
chain, _ := core.NewBlockChain(rawdb.NewMemoryDatabase(), genspec, engine, nil)
defer chain.Stop()
_, blocks, _ := core.GenerateChainWithGenesis(genspec, engine, 3, func(i int, block *core.BlockGen) {
@ -87,7 +86,7 @@ func TestReimportMirroredState(t *testing.T) {
}
// Insert the first two blocks and make sure the chain is valid
db = rawdb.NewMemoryDatabase()
chain, _ = core.NewBlockChain(db, nil, genspec, nil, engine, vm.Config{}, nil)
chain, _ = core.NewBlockChain(db, genspec, engine, nil)
defer chain.Stop()
if _, err := chain.InsertChain(blocks[:2]); err != nil {
@ -100,7 +99,7 @@ func TestReimportMirroredState(t *testing.T) {
// Simulate a crash by creating a new chain on top of the database, without
// flushing the dirty states out. Insert the last block, triggering a sidechain
// reimport.
chain, _ = core.NewBlockChain(db, nil, genspec, nil, engine, vm.Config{}, nil)
chain, _ = core.NewBlockChain(db, genspec, engine, nil)
defer chain.Stop()
if _, err := chain.InsertChain(blocks[2:]); err != nil {

View file

@ -28,7 +28,6 @@ import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
)
@ -458,7 +457,7 @@ func (tt *cliqueTest) run(t *testing.T) {
batches[len(batches)-1] = append(batches[len(batches)-1], block)
}
// Pass all the headers through clique and ensure tallying succeeds
chain, err := core.NewBlockChain(rawdb.NewMemoryDatabase(), nil, genesis, nil, engine, vm.Config{}, nil)
chain, err := core.NewBlockChain(rawdb.NewMemoryDatabase(), genesis, engine, nil)
if err != nil {
t.Fatalf("failed to create test chain: %v", err)
}

View file

@ -25,7 +25,6 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
)
// ChainHeaderReader defines a small collection of methods needed to access the local
@ -109,9 +108,6 @@ type Engine interface {
// that a new block should have.
CalcDifficulty(chain ChainHeaderReader, time uint64, parent *types.Header) *big.Int
// APIs returns the RPC APIs this consensus engine provides.
APIs(chain ChainHeaderReader) []rpc.API
// Close terminates any background threads maintained by the consensus engine.
Close() error
}

View file

@ -22,7 +22,6 @@ import (
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rpc"
)
// Ethash is a consensus engine based on proof-of-work implementing the ethash
@ -71,12 +70,6 @@ func (ethash *Ethash) Close() error {
return nil
}
// APIs implements consensus.Engine, returning no APIs as ethash is an empty
// shell in the post-merge world.
func (ethash *Ethash) APIs(chain consensus.ChainHeaderReader) []rpc.API {
return []rpc.API{}
}
// Seal generates a new sealing request for the given input block and pushes
// the result into the given channel. For the ethash engine, this method will
// just panic as sealing is not supported anymore.

View file

@ -26,7 +26,6 @@ import (
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethdb/pebble"
@ -200,7 +199,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
// Time the insertion of the new chain.
// State and blocks are stored in the same DB.
chainman, _ := NewBlockChain(db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
chainman, _ := NewBlockChain(db, gspec, ethash.NewFaker(), nil)
defer chainman.Stop()
b.ReportAllocs()
b.ResetTimer()
@ -325,9 +324,7 @@ func benchReadChain(b *testing.B, full bool, count uint64) {
genesis := &Genesis{Config: params.AllEthashProtocolChanges}
makeChainForBench(db, genesis, full, count)
db.Close()
cacheConfig := *defaultCacheConfig
cacheConfig.TrieDirtyDisabled = true
options := DefaultConfig().WithArchive(true)
b.ReportAllocs()
b.ResetTimer()
@ -338,7 +335,7 @@ func benchReadChain(b *testing.B, full bool, count uint64) {
}
db = rawdb.NewDatabase(pdb)
chain, err := NewBlockChain(db, &cacheConfig, genesis, nil, ethash.NewFaker(), vm.Config{}, nil)
chain, err := NewBlockChain(db, genesis, ethash.NewFaker(), options)
if err != nil {
b.Fatalf("error creating chain: %v", err)
}

View file

@ -28,7 +28,6 @@ import (
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
)
@ -50,7 +49,8 @@ func testHeaderVerification(t *testing.T, scheme string) {
headers[i] = block.Header()
}
// Run the header checker for blocks one-by-one, checking for both valid and invalid nonces
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
options := DefaultConfig().WithStateScheme(scheme)
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, ethash.NewFaker(), options)
defer chain.Stop()
if err != nil {
t.Fatal(err)
@ -166,7 +166,7 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) {
postHeaders[i] = block.Header()
}
// Run the header checker for blocks one-by-one, checking for both valid and invalid nonces
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, nil)
defer chain.Stop()
if err != nil {
t.Fatal(err)

View file

@ -66,7 +66,7 @@ var (
headSafeBlockGauge = metrics.NewRegisteredGauge("chain/head/safe", nil)
chainInfoGauge = metrics.NewRegisteredGaugeInfo("chain/info", nil)
chainMgaspsGauge = metrics.NewRegisteredGauge("chain/mgasps", nil)
chainMgaspsMeter = metrics.NewRegisteredResettingTimer("chain/mgasps", nil)
accountReadTimer = metrics.NewRegisteredResettingTimer("chain/account/reads", nil)
accountHashTimer = metrics.NewRegisteredResettingTimer("chain/account/hashes", nil)
@ -77,6 +77,16 @@ var (
storageUpdateTimer = metrics.NewRegisteredResettingTimer("chain/storage/updates", nil)
storageCommitTimer = metrics.NewRegisteredResettingTimer("chain/storage/commits", nil)
accountCacheHitMeter = metrics.NewRegisteredMeter("chain/account/reads/cache/process/hit", nil)
accountCacheMissMeter = metrics.NewRegisteredMeter("chain/account/reads/cache/process/miss", nil)
storageCacheHitMeter = metrics.NewRegisteredMeter("chain/storage/reads/cache/process/hit", nil)
storageCacheMissMeter = metrics.NewRegisteredMeter("chain/storage/reads/cache/process/miss", nil)
accountCacheHitPrefetchMeter = metrics.NewRegisteredMeter("chain/account/reads/cache/prefetch/hit", nil)
accountCacheMissPrefetchMeter = metrics.NewRegisteredMeter("chain/account/reads/cache/prefetch/miss", nil)
storageCacheHitPrefetchMeter = metrics.NewRegisteredMeter("chain/storage/reads/cache/prefetch/hit", nil)
storageCacheMissPrefetchMeter = metrics.NewRegisteredMeter("chain/storage/reads/cache/prefetch/miss", nil)
accountReadSingleTimer = metrics.NewRegisteredResettingTimer("chain/account/single/reads", nil)
storageReadSingleTimer = metrics.NewRegisteredResettingTimer("chain/storage/single/reads", nil)
@ -151,65 +161,102 @@ const (
BlockChainVersion uint64 = 9
)
// CacheConfig contains the configuration values for the trie database
// and state snapshot these are resident in a blockchain.
type CacheConfig struct {
// BlockChainConfig contains the configuration of the BlockChain object.
type BlockChainConfig struct {
// Trie database related options
TrieCleanLimit int // Memory allowance (MB) to use for caching trie nodes in memory
TrieCleanNoPrefetch bool // Whether to disable heuristic state prefetching for followup blocks
TrieDirtyLimit int // Memory limit (MB) at which to start flushing dirty trie nodes to disk
TrieDirtyDisabled bool // Whether to disable trie write caching and GC altogether (archive node)
TrieTimeLimit time.Duration // Time limit after which to flush the current in-memory trie to disk
SnapshotLimit int // Memory allowance (MB) to use for caching snapshot entries in memory
TrieNoAsyncFlush bool // Whether the asynchronous buffer flushing is disallowed
Preimages bool // Whether to store preimage of trie key to the disk
StateHistory uint64 // Number of blocks from head whose state histories are reserved.
StateScheme string // Scheme used to store ethereum states and merkle tree nodes on top
ArchiveMode bool // Whether to enable the archive mode
// State snapshot related options
SnapshotLimit int // Memory allowance (MB) to use for caching snapshot entries in memory
SnapshotNoBuild bool // Whether the background generation is allowed
SnapshotWait bool // Wait for snapshot construction on startup. TODO(karalabe): This is a dirty hack for testing, nuke it
// This defines the cutoff block for history expiry.
// Blocks before this number may be unavailable in the chain database.
ChainHistoryMode history.HistoryMode
// Misc options
NoPrefetch bool // Whether to disable heuristic state prefetching when processing blocks
Overrides *ChainOverrides // Optional chain config overrides
VmConfig vm.Config // Config options for the EVM Interpreter
// TxLookupLimit specifies the maximum number of blocks from head for which
// transaction hashes will be indexed.
//
// If the value is zero, all transactions of the entire chain will be indexed.
// If the value is -1, indexing is disabled.
TxLookupLimit int64
}
// triedbConfig derives the configures for trie database.
func (c *CacheConfig) triedbConfig(isVerkle bool) *triedb.Config {
config := &triedb.Config{
Preimages: c.Preimages,
IsVerkle: isVerkle,
}
if c.StateScheme == rawdb.HashScheme {
config.HashDB = &hashdb.Config{
CleanCacheSize: c.TrieCleanLimit * 1024 * 1024,
}
}
if c.StateScheme == rawdb.PathScheme {
config.PathDB = &pathdb.Config{
StateHistory: c.StateHistory,
CleanCacheSize: c.TrieCleanLimit * 1024 * 1024,
WriteBufferSize: c.TrieDirtyLimit * 1024 * 1024,
}
}
return config
}
// defaultCacheConfig are the default caching values if none are specified by the
// user (also used during testing).
var defaultCacheConfig = &CacheConfig{
// DefaultConfig returns the default config.
// Note the returned object is safe to modify!
func DefaultConfig() *BlockChainConfig {
return &BlockChainConfig{
TrieCleanLimit: 256,
TrieDirtyLimit: 256,
TrieTimeLimit: 5 * time.Minute,
StateScheme: rawdb.HashScheme,
SnapshotLimit: 256,
SnapshotWait: true,
StateScheme: rawdb.HashScheme,
ChainHistoryMode: history.KeepAll,
// Transaction indexing is disabled by default.
// This is appropriate for most unit tests.
TxLookupLimit: -1,
}
}
// DefaultCacheConfigWithScheme returns a deep copied default cache config with
// a provided trie node scheme.
func DefaultCacheConfigWithScheme(scheme string) *CacheConfig {
config := *defaultCacheConfig
config.StateScheme = scheme
return &config
// WithArchive enables/disables archive mode on the config.
func (cfg BlockChainConfig) WithArchive(on bool) *BlockChainConfig {
cfg.ArchiveMode = on
return &cfg
}
// WithStateScheme sets the state storage scheme on the config.
func (cfg BlockChainConfig) WithStateScheme(scheme string) *BlockChainConfig {
cfg.StateScheme = scheme
return &cfg
}
// WithNoAsyncFlush enables/disables asynchronous buffer flushing mode on the config.
func (cfg BlockChainConfig) WithNoAsyncFlush(on bool) *BlockChainConfig {
cfg.TrieNoAsyncFlush = on
return &cfg
}
// triedbConfig derives the configures for trie database.
func (cfg *BlockChainConfig) triedbConfig(isVerkle bool) *triedb.Config {
config := &triedb.Config{
Preimages: cfg.Preimages,
IsVerkle: isVerkle,
}
if cfg.StateScheme == rawdb.HashScheme {
config.HashDB = &hashdb.Config{
CleanCacheSize: cfg.TrieCleanLimit * 1024 * 1024,
}
}
if cfg.StateScheme == rawdb.PathScheme {
config.PathDB = &pathdb.Config{
StateHistory: cfg.StateHistory,
EnableStateIndexing: cfg.ArchiveMode,
TrieCleanSize: cfg.TrieCleanLimit * 1024 * 1024,
StateCleanSize: cfg.SnapshotLimit * 1024 * 1024,
// TODO(rjl493456442): The write buffer represents the memory limit used
// for flushing both trie data and state data to disk. The config name
// should be updated to eliminate the confusion.
WriteBufferSize: cfg.TrieDirtyLimit * 1024 * 1024,
NoAsyncFlush: cfg.TrieNoAsyncFlush,
}
}
return config
}
// txLookup is wrapper over transaction lookup along with the corresponding
@ -235,7 +282,7 @@ type txLookup struct {
// canonical chain.
type BlockChain struct {
chainConfig *params.ChainConfig // Chain & network configuration
cacheConfig *CacheConfig // Cache configuration for pruning
cfg *BlockChainConfig // Blockchain configuration
db ethdb.Database // Low level persistent database to store final content in
snaps *snapshot.Tree // Snapshot tree for fast trie leaf access
@ -269,13 +316,12 @@ type BlockChain struct {
bodyCache *lru.Cache[common.Hash, *types.Body]
bodyRLPCache *lru.Cache[common.Hash, rlp.RawValue]
receiptsCache *lru.Cache[common.Hash, []*types.Receipt]
receiptsCache *lru.Cache[common.Hash, []*types.Receipt] // Receipts cache with all fields derived
blockCache *lru.Cache[common.Hash, *types.Block]
txLookupLock sync.RWMutex
txLookupCache *lru.Cache[common.Hash, txLookup]
quit chan struct{} // shutdown signal, closed in Stop.
stopping atomic.Bool // false if chain is running, true when stopped
procInterrupt atomic.Bool // interrupt signaler for block processing
@ -283,7 +329,6 @@ type BlockChain struct {
validator Validator // Block and state validator interface
prefetcher Prefetcher
processor Processor // Block transaction processor interface
vmConfig vm.Config
logger *tracing.Hooks
lastForkReadyAlert time.Time // Last time there was a fork readiness print out
@ -292,22 +337,23 @@ type BlockChain struct {
// NewBlockChain returns a fully initialised block chain using information
// available in the database. It initialises the default Ethereum Validator
// and Processor.
func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis, overrides *ChainOverrides, engine consensus.Engine, vmConfig vm.Config, txLookupLimit *uint64) (*BlockChain, error) {
if cacheConfig == nil {
cacheConfig = defaultCacheConfig
func NewBlockChain(db ethdb.Database, genesis *Genesis, engine consensus.Engine, cfg *BlockChainConfig) (*BlockChain, error) {
if cfg == nil {
cfg = DefaultConfig()
}
// Open trie database with provided config
enableVerkle, err := EnableVerkleAtGenesis(db, genesis)
if err != nil {
return nil, err
}
triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(enableVerkle))
triedb := triedb.NewDatabase(db, cfg.triedbConfig(enableVerkle))
// Write the supplied genesis to the database if it has not been initialized
// yet. The corresponding chain config will be returned, either from the
// provided genesis or from the locally stored configuration if the genesis
// has already been initialized.
chainConfig, genesisHash, compatErr, err := SetupGenesisBlockWithOverride(db, triedb, genesis, overrides)
chainConfig, genesisHash, compatErr, err := SetupGenesisBlockWithOverride(db, triedb, genesis, cfg.Overrides)
if err != nil {
return nil, err
}
@ -321,11 +367,10 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
bc := &BlockChain{
chainConfig: chainConfig,
cacheConfig: cacheConfig,
cfg: cfg,
db: db,
triedb: triedb,
triegc: prque.New[int64, common.Hash](nil),
quit: make(chan struct{}),
chainmu: syncx.NewClosableMutex(),
bodyCache: lru.NewCache[common.Hash, *types.Body](bodyCacheLimit),
bodyRLPCache: lru.NewCache[common.Hash, rlp.RawValue](bodyCacheLimit),
@ -333,14 +378,13 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
blockCache: lru.NewCache[common.Hash, *types.Block](blockCacheLimit),
txLookupCache: lru.NewCache[common.Hash, txLookup](txLookupCacheLimit),
engine: engine,
vmConfig: vmConfig,
logger: vmConfig.Tracer,
logger: cfg.VmConfig.Tracer,
}
bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.insertStopped)
if err != nil {
return nil, err
}
bc.flushInterval.Store(int64(cacheConfig.TrieTimeLimit))
bc.flushInterval.Store(int64(cfg.TrieTimeLimit))
bc.statedb = state.NewDatabase(bc.triedb, nil)
bc.validator = NewBlockValidator(chainConfig, bc)
bc.prefetcher = newStatePrefetcher(chainConfig, bc.hc)
@ -383,11 +427,14 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
// Do nothing here until the state syncer picks it up.
log.Info("Genesis state is missing, wait state sync")
} else {
// Head state is missing, before the state recovery, find out the
// disk layer point of snapshot(if it's enabled). Make sure the
// rewound point is lower than disk layer.
// Head state is missing, before the state recovery, find out the disk
// layer point of snapshot(if it's enabled). Make sure the rewound point
// is lower than disk layer.
//
// Note it's unnecessary in path mode which always keep trie data and
// state data consistent.
var diskRoot common.Hash
if bc.cacheConfig.SnapshotLimit > 0 {
if bc.cfg.SnapshotLimit > 0 && bc.cfg.StateScheme == rawdb.HashScheme {
diskRoot = rawdb.ReadSnapshotRoot(bc.db)
}
if diskRoot != (common.Hash{}) {
@ -460,31 +507,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
bc.logger.OnGenesisBlock(bc.genesisBlock, alloc)
}
}
// Load any existing snapshot, regenerating it if loading failed
if bc.cacheConfig.SnapshotLimit > 0 {
// If the chain was rewound past the snapshot persistent layer (causing
// a recovery block number to be persisted to disk), check if we're still
// in recovery mode and in that case, don't invalidate the snapshot on a
// head mismatch.
var recover bool
head := bc.CurrentBlock()
if layer := rawdb.ReadSnapshotRecoveryNumber(bc.db); layer != nil && *layer >= head.Number.Uint64() {
log.Warn("Enabling snapshot recovery", "chainhead", head.Number, "diskbase", *layer)
recover = true
}
snapconfig := snapshot.Config{
CacheSize: bc.cacheConfig.SnapshotLimit,
Recovery: recover,
NoBuild: bc.cacheConfig.SnapshotNoBuild,
AsyncBuild: !bc.cacheConfig.SnapshotWait,
}
bc.snaps, _ = snapshot.New(snapconfig, bc.db, bc.triedb, head.Root)
// Re-initialize the state database with snapshot
bc.statedb = state.NewDatabase(bc.triedb, bc.snaps)
}
bc.setupSnapshot()
// Rewind the chain in case of an incompatible config upgrade.
if compatErr != nil {
@ -496,13 +519,45 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
}
rawdb.WriteChainConfig(db, genesisHash, chainConfig)
}
// Start tx indexer if it's enabled.
if txLookupLimit != nil {
bc.txIndexer = newTxIndexer(*txLookupLimit, bc)
if bc.cfg.TxLookupLimit >= 0 {
bc.txIndexer = newTxIndexer(uint64(bc.cfg.TxLookupLimit), bc)
}
return bc, nil
}
func (bc *BlockChain) setupSnapshot() {
// Short circuit if the chain is established with path scheme, as the
// state snapshot has been integrated into path database natively.
if bc.cfg.StateScheme == rawdb.PathScheme {
return
}
// Load any existing snapshot, regenerating it if loading failed
if bc.cfg.SnapshotLimit > 0 {
// If the chain was rewound past the snapshot persistent layer (causing
// a recovery block number to be persisted to disk), check if we're still
// in recovery mode and in that case, don't invalidate the snapshot on a
// head mismatch.
var recover bool
head := bc.CurrentBlock()
if layer := rawdb.ReadSnapshotRecoveryNumber(bc.db); layer != nil && *layer >= head.Number.Uint64() {
log.Warn("Enabling snapshot recovery", "chainhead", head.Number, "diskbase", *layer)
recover = true
}
snapconfig := snapshot.Config{
CacheSize: bc.cfg.SnapshotLimit,
Recovery: recover,
NoBuild: bc.cfg.SnapshotNoBuild,
AsyncBuild: !bc.cfg.SnapshotWait,
}
bc.snaps, _ = snapshot.New(snapconfig, bc.db, bc.triedb, head.Root)
// Re-initialize the state database with snapshot
bc.statedb = state.NewDatabase(bc.triedb, bc.snaps)
}
}
// empty returns an indicator whether the blockchain is empty.
// Note, it's a special case that we connect a non-empty ancient
// database with an empty node, so that we can plugin the ancient
@ -618,7 +673,7 @@ func (bc *BlockChain) loadLastState() error {
func (bc *BlockChain) initializeHistoryPruning(latest uint64) error {
freezerTail, _ := bc.db.Tail()
switch bc.cacheConfig.ChainHistoryMode {
switch bc.cfg.ChainHistoryMode {
case history.KeepAll:
if freezerTail == 0 {
return nil
@ -639,7 +694,7 @@ func (bc *BlockChain) initializeHistoryPruning(latest uint64) error {
// postmerge directly on an existing DB. We could just trigger the pruning
// here, but it'd be a bit dangerous since they may not have intended this
// action to happen. So just tell them how to do it.
log.Error(fmt.Sprintf("Chain history mode is configured as %q, but database is not pruned.", bc.cacheConfig.ChainHistoryMode.String()))
log.Error(fmt.Sprintf("Chain history mode is configured as %q, but database is not pruned.", bc.cfg.ChainHistoryMode.String()))
log.Error(fmt.Sprintf("Run 'geth prune-history' to prune pre-merge history."))
return fmt.Errorf("history pruning requested via configuration")
}
@ -655,7 +710,7 @@ func (bc *BlockChain) initializeHistoryPruning(latest uint64) error {
return nil
default:
return fmt.Errorf("invalid history mode: %d", bc.cacheConfig.ChainHistoryMode)
return fmt.Errorf("invalid history mode: %d", bc.cfg.ChainHistoryMode)
}
}
@ -1193,8 +1248,7 @@ func (bc *BlockChain) stopWithoutSaving() {
bc.scope.Close()
// Signal shutdown to all goroutines.
close(bc.quit)
bc.StopInsert()
bc.InterruptInsert(true)
// Now wait for all chain modifications to end and persistent goroutines to exit.
//
@ -1230,7 +1284,7 @@ func (bc *BlockChain) Stop() {
// - HEAD: So we don't need to reprocess any blocks in the general case
// - HEAD-1: So we don't do large reorgs if our HEAD becomes an uncle
// - HEAD-127: So we have a hard limit on the number of blocks reexecuted
if !bc.cacheConfig.TrieDirtyDisabled {
if !bc.cfg.ArchiveMode {
triedb := bc.triedb
for _, offset := range []uint64{0, 1, state.TriesInMemory - 1} {
@ -1268,11 +1322,15 @@ func (bc *BlockChain) Stop() {
log.Info("Blockchain stopped")
}
// StopInsert interrupts all insertion methods, causing them to return
// errInsertionInterrupted as soon as possible. Insertion is permanently disabled after
// calling this method.
func (bc *BlockChain) StopInsert() {
// InterruptInsert interrupts all insertion methods, causing them to return
// errInsertionInterrupted as soon as possible, or resume the chain insertion
// if required.
func (bc *BlockChain) InterruptInsert(on bool) {
if on {
bc.procInterrupt.Store(true)
} else {
bc.procInterrupt.Store(false)
}
}
// insertStopped returns true after StopInsert has been called.
@ -1296,12 +1354,11 @@ const (
//
// The optional ancientLimit can also be specified and chain segment before that
// will be directly stored in the ancient, getting rid of the chain migration.
func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts, ancientLimit uint64) (int, error) {
func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []rlp.RawValue, ancientLimit uint64) (int, error) {
// Verify the supplied headers before insertion without lock
var headers []*types.Header
for _, block := range blockChain {
headers = append(headers, block.Header())
// Here we also validate that blob transactions in the block do not
// contain a sidecar. While the sidecar does not affect the block hash
// or tx hash, sending blobs within a block is not allowed.
@ -1344,11 +1401,11 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
//
// this function only accepts canonical chain data. All side chain will be reverted
// eventually.
writeAncient := func(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) {
writeAncient := func(blockChain types.Blocks, receiptChain []rlp.RawValue) (int, error) {
// Ensure genesis is in the ancient store
if blockChain[0].NumberU64() == 1 {
if frozen, _ := bc.db.Ancients(); frozen == 0 {
writeSize, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []types.Receipts{nil})
writeSize, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []rlp.RawValue{rlp.EmptyList})
if err != nil {
log.Error("Error writing genesis to ancients", "err", err)
return 0, err
@ -1391,7 +1448,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
// existing local chain segments (reorg around the chain tip). The reorganized part
// will be included in the provided chain segment, and stale canonical markers will be
// silently rewritten. Therefore, no explicit reorg logic is needed.
writeLive := func(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) {
writeLive := func(blockChain types.Blocks, receiptChain []rlp.RawValue) (int, error) {
var (
skipPresenceCheck = false
batch = bc.db.NewBatch()
@ -1416,7 +1473,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
// Write all the data out into the database
rawdb.WriteCanonicalHash(batch, block.Hash(), block.NumberU64())
rawdb.WriteBlock(batch, block)
rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receiptChain[i])
rawdb.WriteRawReceipts(batch, block.Hash(), block.NumberU64(), receiptChain[i])
// Write everything belongs to the blocks into the database. So that
// we can ensure all components of body is completed(body, receipts)
@ -1537,7 +1594,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
return nil
}
// If we're running an archive node, always flush
if bc.cacheConfig.TrieDirtyDisabled {
if bc.cfg.ArchiveMode {
return bc.triedb.Commit(root, false)
}
// Full but not archive node, do proper garbage collection
@ -1552,7 +1609,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
// If we exceeded our memory allowance, flush matured singleton nodes to disk
var (
_, nodes, imgs = bc.triedb.Size() // all memory is contained within the nodes return for hashdb
limit = common.StorageSize(bc.cacheConfig.TrieDirtyLimit) * 1024 * 1024
limit = common.StorageSize(bc.cfg.TrieDirtyLimit) * 1024 * 1024
)
if nodes > limit || imgs > 4*1024*1024 {
bc.triedb.Cap(limit - ethdb.IdealBatchSize)
@ -1902,8 +1959,7 @@ func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, s
)
defer interrupt.Store(true) // terminate the prefetch at the end
bc.cacheConfig.TrieCleanNoPrefetch = true
if bc.cacheConfig.TrieCleanNoPrefetch {
if bc.cfg.NoPrefetch {
statedb, err = state.New(parentRoot, bc.statedb)
if err != nil {
return nil, err
@ -1923,21 +1979,35 @@ func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, s
//
// Note: the main processor and prefetcher share the same reader with a local
// cache for mitigating the overhead of state access.
reader, err := bc.statedb.ReaderWithCache(parentRoot)
prefetch, process, err := bc.statedb.ReadersWithCacheStats(parentRoot)
if err != nil {
return nil, err
}
throwaway, err := state.NewWithReader(parentRoot, bc.statedb, reader)
throwaway, err := state.NewWithReader(parentRoot, bc.statedb, prefetch)
if err != nil {
return nil, err
}
statedb, err = state.NewWithReader(parentRoot, bc.statedb, reader)
statedb, err = state.NewWithReader(parentRoot, bc.statedb, process)
if err != nil {
return nil, err
}
// Upload the statistics of reader at the end
defer func() {
stats := prefetch.GetStats()
accountCacheHitPrefetchMeter.Mark(stats.AccountHit)
accountCacheMissPrefetchMeter.Mark(stats.AccountMiss)
storageCacheHitPrefetchMeter.Mark(stats.StorageHit)
storageCacheMissPrefetchMeter.Mark(stats.StorageMiss)
stats = process.GetStats()
accountCacheHitMeter.Mark(stats.AccountHit)
accountCacheMissMeter.Mark(stats.AccountMiss)
storageCacheHitMeter.Mark(stats.StorageHit)
storageCacheMissMeter.Mark(stats.StorageMiss)
}()
go func(start time.Time, throwaway *state.StateDB, block *types.Block) {
// Disable tracing for prefetcher executions.
vmCfg := bc.vmConfig
vmCfg := bc.cfg.VmConfig
vmCfg.Tracer = nil
bc.prefetcher.Prefetch(block, throwaway, vmCfg, &interrupt)
@ -1956,7 +2026,7 @@ func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, s
// Generate witnesses either if we're self-testing, or if it's the
// only block being inserted. A bit crude, but witnesses are huge,
// so we refuse to make an entire chain of them.
if bc.vmConfig.StatelessSelfValidation || makeWitness {
if bc.cfg.VmConfig.StatelessSelfValidation || makeWitness {
witness, err = stateless.NewWitness(block.Header(), bc)
if err != nil {
return nil, err
@ -1981,7 +2051,7 @@ func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, s
// Process block using the parent state as reference point
pstart := time.Now()
res, err := bc.processor.Process(block, statedb, bc.vmConfig)
res, err := bc.processor.Process(block, statedb, bc.cfg.VmConfig)
if err != nil {
bc.reportBlock(block, res, err)
return nil, err
@ -2001,7 +2071,7 @@ func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, s
// witness builder/runner, which would otherwise be impossible due to the
// various invalid chain states/behaviors being contained in those tests.
xvstart := time.Now()
if witness := statedb.Witness(); witness != nil && bc.vmConfig.StatelessSelfValidation {
if witness := statedb.Witness(); witness != nil && bc.cfg.VmConfig.StatelessSelfValidation {
log.Warn("Running stateless self-validation", "block", block.Number(), "hash", block.Hash())
// Remove critical computed fields from the block to force true recalculation
@ -2012,7 +2082,7 @@ func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, s
task := types.NewBlockWithHeader(context).WithBody(*block.Body())
// Run the stateless self-cross-validation
crossStateRoot, crossReceiptRoot, err := ExecuteStateless(bc.chainConfig, bc.vmConfig, task, witness)
crossStateRoot, crossReceiptRoot, err := ExecuteStateless(bc.chainConfig, bc.cfg.VmConfig, task, witness)
if err != nil {
return nil, fmt.Errorf("stateless self-validation failed: %v", err)
}
@ -2065,7 +2135,12 @@ func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, s
triedbCommitTimer.Update(statedb.TrieDBCommits) // Trie database commits are complete, we can mark them
blockWriteTimer.Update(time.Since(wstart) - max(statedb.AccountCommits, statedb.StorageCommits) /* concurrent */ - statedb.SnapshotCommits - statedb.TrieDBCommits)
blockInsertTimer.UpdateSince(startTime)
elapsed := time.Since(startTime) + 1 // prevent zero division
blockInsertTimer.Update(elapsed)
// TODO(rjl493456442) generalize the ResettingTimer
mgasps := float64(res.GasUsed) * 1000 / float64(elapsed)
chainMgaspsMeter.Update(time.Duration(mgasps))
return &blockProcessingResult{
usedGas: res.GasUsed,
@ -2647,7 +2722,7 @@ func (bc *BlockChain) InsertHeadersBeforeCutoff(headers []*types.Header) (int, e
first = headers[0].Number.Uint64()
)
if first == 1 && frozen == 0 {
_, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []types.Receipts{nil})
_, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []rlp.RawValue{rlp.EmptyList})
if err != nil {
log.Error("Error writing genesis to ancients", "err", err)
return 0, err

View file

@ -27,7 +27,7 @@ import (
// insertStats tracks and reports on block insertion.
type insertStats struct {
queued, processed, ignored int
processed, ignored int
usedGas uint64
lastIndex int
startTime mclock.AbsTime
@ -79,9 +79,6 @@ func (st *insertStats) report(chain []*types.Block, index int, snapDiffItems, sn
}
context = append(context, []interface{}{"triedirty", triebufNodes}...)
if st.queued > 0 {
context = append(context, []interface{}{"queued", st.queued}...)
}
if st.ignored > 0 {
context = append(context, []interface{}{"ignored", st.ignored}...)
}

View file

@ -18,9 +18,12 @@ package core
import (
"errors"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/state/snapshot"
@ -213,6 +216,44 @@ func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*type
return
}
// GetCanonicalReceipt allows fetching a receipt for a transaction that was
// already looked up on the index. Notably, only receipt in canonical chain
// is visible.
func (bc *BlockChain) GetCanonicalReceipt(tx *types.Transaction, blockHash common.Hash, blockNumber, txIndex uint64) (*types.Receipt, error) {
// The receipt retrieved from the cache contains all previously derived fields
if receipts, ok := bc.receiptsCache.Get(blockHash); ok {
if int(txIndex) >= len(receipts) {
return nil, fmt.Errorf("receipt out of index, length: %d, index: %d", len(receipts), txIndex)
}
return receipts[int(txIndex)], nil
}
header := bc.GetHeader(blockHash, blockNumber)
if header == nil {
return nil, fmt.Errorf("block header is not found, %d, %x", blockNumber, blockHash)
}
var blobGasPrice *big.Int
if header.ExcessBlobGas != nil {
blobGasPrice = eip4844.CalcBlobFee(bc.chainConfig, header)
}
receipt, ctx, err := rawdb.ReadCanonicalRawReceipt(bc.db, blockHash, blockNumber, txIndex)
if err != nil {
return nil, err
}
signer := types.MakeSigner(bc.chainConfig, new(big.Int).SetUint64(blockNumber), header.Time)
receipt.DeriveFields(signer, types.DeriveReceiptContext{
BlockHash: blockHash,
BlockNumber: blockNumber,
BlockTime: header.Time,
BaseFee: header.BaseFee,
BlobGasPrice: blobGasPrice,
GasUsed: ctx.GasUsed,
LogIndex: ctx.LogIndex,
Tx: tx,
TxIndex: uint(txIndex),
})
return receipt, nil
}
// GetReceiptsByHash retrieves the receipts for all transactions in a given block.
func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
if receipts, ok := bc.receiptsCache.Get(hash); ok {
@ -234,12 +275,22 @@ func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
return receipts
}
func (bc *BlockChain) GetRawReceiptsByHash(hash common.Hash) types.Receipts {
// GetRawReceipts retrieves the receipts for all transactions in a given block
// without deriving the internal fields and the Bloom.
func (bc *BlockChain) GetRawReceipts(hash common.Hash, number uint64) types.Receipts {
if receipts, ok := bc.receiptsCache.Get(hash); ok {
return receipts
}
return rawdb.ReadRawReceipts(bc.db, hash, number)
}
// GetReceiptsRLP retrieves the receipts of a block.
func (bc *BlockChain) GetReceiptsRLP(hash common.Hash) rlp.RawValue {
number := rawdb.ReadHeaderNumber(bc.db, hash)
if number == nil {
return nil
}
return rawdb.ReadRawReceipts(bc.db, hash, *number)
return rawdb.ReadReceiptsRLP(bc.db, hash, *number)
}
// GetUnclesInChain retrieves all the uncles from a given block backwards until
@ -267,13 +318,15 @@ func (bc *BlockChain) GetAncestor(hash common.Hash, number, ancestor uint64, max
return bc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical)
}
// GetTransactionLookup retrieves the lookup along with the transaction
// GetCanonicalTransaction retrieves the lookup along with the transaction
// itself associate with the given transaction hash.
//
// A null will be returned if the transaction is not found. This can be due to
// the transaction indexer not being finished. The caller must explicitly check
// the indexer progress.
func (bc *BlockChain) GetTransactionLookup(hash common.Hash) (*rawdb.LegacyTxLookupEntry, *types.Transaction) {
//
// Notably, only the transaction in the canonical chain is visible.
func (bc *BlockChain) GetCanonicalTransaction(hash common.Hash) (*rawdb.LegacyTxLookupEntry, *types.Transaction) {
bc.txLookupLock.RLock()
defer bc.txLookupLock.RUnlock()
@ -281,7 +334,7 @@ func (bc *BlockChain) GetTransactionLookup(hash common.Hash) (*rawdb.LegacyTxLoo
if item, exist := bc.txLookupCache.Get(hash); exist {
return item.lookup, item.transaction
}
tx, blockHash, blockNumber, txIndex := rawdb.ReadTransaction(bc.db, hash)
tx, blockHash, blockNumber, txIndex := rawdb.ReadCanonicalTransaction(bc.db, hash)
if tx == nil {
return nil, nil
}
@ -360,6 +413,13 @@ func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
return state.New(root, bc.statedb)
}
// HistoricState returns a historic state specified by the given root.
// Live states are not available and won't be served, please use `State`
// or `StateAt` instead.
func (bc *BlockChain) HistoricState(root common.Hash) (*state.StateDB, error) {
return state.New(root, state.NewHistoricDatabase(bc.db, bc.triedb))
}
// Config retrieves the chain's fork configuration.
func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig }
@ -398,7 +458,7 @@ func (bc *BlockChain) Genesis() *types.Block {
// GetVMConfig returns the block chain VM config.
func (bc *BlockChain) GetVMConfig() *vm.Config {
return &bc.vmConfig
return &bc.cfg.VmConfig
}
// TxIndexProgress returns the transaction indexing progress.
@ -409,6 +469,11 @@ func (bc *BlockChain) TxIndexProgress() (TxIndexProgress, error) {
return bc.txIndexer.txIndexProgress(), nil
}
// StateIndexProgress returns the historical state indexing progress.
func (bc *BlockChain) StateIndexProgress() (uint64, error) {
return bc.triedb.IndexProgress()
}
// HistoryPruningCutoff returns the configured history pruning point.
// Blocks before this might not be available in the database.
func (bc *BlockChain) HistoryPruningCutoff() (uint64, common.Hash) {

View file

@ -30,7 +30,6 @@ import (
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb/pebble"
"github.com/ethereum/go-ethereum/params"
)
@ -1769,7 +1768,7 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s
if err != nil {
t.Fatalf("Failed to create persistent key-value database: %v", err)
}
db, err := rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false)
db, err := rawdb.Open(pdb, rawdb.OpenOptions{Ancient: ancient})
if err != nil {
t.Fatalf("Failed to create persistent freezer database: %v", err)
}
@ -1782,20 +1781,21 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s
Config: params.AllEthashProtocolChanges,
}
engine = ethash.NewFullFaker()
config = &CacheConfig{
option = &BlockChainConfig{
TrieCleanLimit: 256,
TrieDirtyLimit: 256,
TrieTimeLimit: 5 * time.Minute,
SnapshotLimit: 0, // Disable snapshot by default
SnapshotLimit: 0, // disable snapshot by default
TxLookupLimit: -1, // disable tx indexing
StateScheme: scheme,
}
)
defer engine.Close()
if snapshots {
config.SnapshotLimit = 256
config.SnapshotWait = true
if snapshots && scheme == rawdb.HashScheme {
option.SnapshotLimit = 256
option.SnapshotWait = true
}
chain, err := NewBlockChain(db, config, gspec, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(db, gspec, engine, option)
if err != nil {
t.Fatalf("Failed to create chain: %v", err)
}
@ -1820,7 +1820,7 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s
if err := chain.triedb.Commit(canonblocks[tt.commitBlock-1].Root(), false); err != nil {
t.Fatalf("Failed to flush trie state: %v", err)
}
if snapshots {
if snapshots && scheme == rawdb.HashScheme {
if err := chain.snaps.Cap(canonblocks[tt.commitBlock-1].Root(), 0); err != nil {
t.Fatalf("Failed to flatten snapshots: %v", err)
}
@ -1854,13 +1854,13 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s
if err != nil {
t.Fatalf("Failed to reopen persistent key-value database: %v", err)
}
db, err = rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false)
db, err = rawdb.Open(pdb, rawdb.OpenOptions{Ancient: ancient})
if err != nil {
t.Fatalf("Failed to reopen persistent freezer database: %v", err)
}
defer db.Close()
newChain, err := NewBlockChain(db, config, gspec, nil, engine, vm.Config{}, nil)
newChain, err := NewBlockChain(db, gspec, engine, option)
if err != nil {
t.Fatalf("Failed to recreate chain: %v", err)
}
@ -1919,7 +1919,7 @@ func testIssue23496(t *testing.T, scheme string) {
if err != nil {
t.Fatalf("Failed to create persistent key-value database: %v", err)
}
db, err := rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false)
db, err := rawdb.Open(pdb, rawdb.OpenOptions{Ancient: ancient})
if err != nil {
t.Fatalf("Failed to create persistent freezer database: %v", err)
}
@ -1932,8 +1932,9 @@ func testIssue23496(t *testing.T, scheme string) {
BaseFee: big.NewInt(params.InitialBaseFee),
}
engine = ethash.NewFullFaker()
options = DefaultConfig().WithStateScheme(scheme)
)
chain, err := NewBlockChain(db, DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(db, gspec, engine, options)
if err != nil {
t.Fatalf("Failed to create chain: %v", err)
}
@ -1952,9 +1953,11 @@ func testIssue23496(t *testing.T, scheme string) {
if _, err := chain.InsertChain(blocks[1:2]); err != nil {
t.Fatalf("Failed to import canonical chain start: %v", err)
}
if scheme == rawdb.HashScheme {
if err := chain.snaps.Cap(blocks[1].Root(), 0); err != nil {
t.Fatalf("Failed to flatten snapshots: %v", err)
}
}
// Insert block B3 and commit the state into disk
if _, err := chain.InsertChain(blocks[2:3]); err != nil {
@ -1977,13 +1980,13 @@ func testIssue23496(t *testing.T, scheme string) {
if err != nil {
t.Fatalf("Failed to reopen persistent key-value database: %v", err)
}
db, err = rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false)
db, err = rawdb.Open(pdb, rawdb.OpenOptions{Ancient: ancient})
if err != nil {
t.Fatalf("Failed to reopen persistent freezer database: %v", err)
}
defer db.Close()
chain, err = NewBlockChain(db, DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil)
chain, err = NewBlockChain(db, gspec, engine, DefaultConfig().WithStateScheme(scheme))
if err != nil {
t.Fatalf("Failed to recreate chain: %v", err)
}
@ -1997,16 +2000,24 @@ func testIssue23496(t *testing.T, scheme string) {
}
expHead := uint64(1)
if scheme == rawdb.PathScheme {
expHead = uint64(2)
// The pathdb database makes sure that snapshot and trie are consistent,
// so only the last block is reverted in case of a crash.
expHead = uint64(3)
}
if head := chain.CurrentBlock(); head.Number.Uint64() != expHead {
t.Errorf("Head block mismatch: have %d, want %d", head.Number, expHead)
}
if scheme == rawdb.PathScheme {
// Reinsert B4
if _, err := chain.InsertChain(blocks[3:]); err != nil {
t.Fatalf("Failed to import canonical chain tail: %v", err)
}
} else {
// Reinsert B2-B4
if _, err := chain.InsertChain(blocks[1:]); err != nil {
t.Fatalf("Failed to import canonical chain tail: %v", err)
}
}
if head := chain.CurrentHeader(); head.Number.Uint64() != uint64(4) {
t.Errorf("Head header mismatch: have %d, want %d", head.Number, 4)
}
@ -2016,7 +2027,9 @@ func testIssue23496(t *testing.T, scheme string) {
if head := chain.CurrentBlock(); head.Number.Uint64() != uint64(4) {
t.Errorf("Head block mismatch: have %d, want %d", head.Number, uint64(4))
}
if scheme == rawdb.HashScheme {
if layer := chain.Snapshots().Snapshot(blocks[2].Root()); layer == nil {
t.Error("Failed to regenerate the snapshot of known state")
}
}
}

View file

@ -32,7 +32,6 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb/pebble"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/triedb"
@ -1973,7 +1972,7 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme
if err != nil {
t.Fatalf("Failed to create persistent key-value database: %v", err)
}
db, err := rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false)
db, err := rawdb.Open(pdb, rawdb.OpenOptions{Ancient: ancient})
if err != nil {
t.Fatalf("Failed to create persistent freezer database: %v", err)
}
@ -1986,19 +1985,20 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme
Config: params.AllEthashProtocolChanges,
}
engine = ethash.NewFullFaker()
config = &CacheConfig{
options = &BlockChainConfig{
TrieCleanLimit: 256,
TrieDirtyLimit: 256,
TrieTimeLimit: 5 * time.Minute,
SnapshotLimit: 0, // Disable snapshot
SnapshotLimit: 0, // disable snapshot
TxLookupLimit: -1, // disable tx indexing
StateScheme: scheme,
}
)
if snapshots {
config.SnapshotLimit = 256
config.SnapshotWait = true
options.SnapshotLimit = 256
options.SnapshotWait = true
}
chain, err := NewBlockChain(db, config, gspec, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(db, gspec, engine, options)
if err != nil {
t.Fatalf("Failed to create chain: %v", err)
}
@ -2023,7 +2023,7 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme
}
if tt.commitBlock > 0 {
chain.triedb.Commit(canonblocks[tt.commitBlock-1].Root(), false)
if snapshots {
if snapshots && scheme == rawdb.HashScheme {
if err := chain.snaps.Cap(canonblocks[tt.commitBlock-1].Root(), 0); err != nil {
t.Fatalf("Failed to flatten snapshots: %v", err)
}

View file

@ -33,7 +33,6 @@ import (
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethdb/pebble"
"github.com/ethereum/go-ethereum/params"
@ -70,7 +69,7 @@ func (basic *snapshotTestBasic) prepare(t *testing.T) (*BlockChain, []*types.Blo
if err != nil {
t.Fatalf("Failed to create persistent key-value database: %v", err)
}
db, err := rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false)
db, err := rawdb.Open(pdb, rawdb.OpenOptions{Ancient: ancient})
if err != nil {
t.Fatalf("Failed to create persistent freezer database: %v", err)
}
@ -82,7 +81,7 @@ func (basic *snapshotTestBasic) prepare(t *testing.T) (*BlockChain, []*types.Blo
}
engine = ethash.NewFullFaker()
)
chain, err := NewBlockChain(db, DefaultCacheConfigWithScheme(basic.scheme), gspec, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(db, gspec, engine, DefaultConfig().WithStateScheme(basic.scheme).WithNoAsyncFlush(true))
if err != nil {
t.Fatalf("Failed to create chain: %v", err)
}
@ -105,7 +104,7 @@ func (basic *snapshotTestBasic) prepare(t *testing.T) (*BlockChain, []*types.Blo
if basic.commitBlock > 0 && basic.commitBlock == point {
chain.TrieDB().Commit(blocks[point-1].Root(), false)
}
if basic.snapshotBlock > 0 && basic.snapshotBlock == point {
if basic.snapshotBlock > 0 && basic.snapshotBlock == point && basic.scheme == rawdb.HashScheme {
// Flushing the entire snap tree into the disk, the
// relevant (a) snapshot root and (b) snapshot generator
// will be persisted atomically.
@ -149,15 +148,19 @@ func (basic *snapshotTestBasic) verify(t *testing.T, chain *BlockChain, blocks [
block := chain.GetBlockByNumber(basic.expSnapshotBottom)
if block == nil {
t.Errorf("The corresponding block[%d] of snapshot disk layer is missing", basic.expSnapshotBottom)
} else if !bytes.Equal(chain.snaps.DiskRoot().Bytes(), block.Root().Bytes()) {
} else if basic.scheme == rawdb.HashScheme {
if !bytes.Equal(chain.snaps.DiskRoot().Bytes(), block.Root().Bytes()) {
t.Errorf("The snapshot disk layer root is incorrect, want %x, get %x", block.Root(), chain.snaps.DiskRoot())
}
}
// Check the snapshot, ensure it's integrated
if basic.scheme == rawdb.HashScheme {
if err := chain.snaps.Verify(block.Root()); err != nil {
t.Errorf("The disk layer is not integrated %v", err)
}
}
}
//nolint:unused
func (basic *snapshotTestBasic) dump() string {
@ -229,7 +232,7 @@ func (snaptest *snapshotTest) test(t *testing.T) {
// Restart the chain normally
chain.Stop()
newchain, err := NewBlockChain(snaptest.db, DefaultCacheConfigWithScheme(snaptest.scheme), snaptest.gspec, nil, snaptest.engine, vm.Config{}, nil)
newchain, err := NewBlockChain(snaptest.db, snaptest.gspec, snaptest.engine, DefaultConfig().WithStateScheme(snaptest.scheme))
if err != nil {
t.Fatalf("Failed to recreate chain: %v", err)
}
@ -261,7 +264,7 @@ func (snaptest *crashSnapshotTest) test(t *testing.T) {
if err != nil {
t.Fatalf("Failed to create persistent key-value database: %v", err)
}
newdb, err := rawdb.NewDatabaseWithFreezer(pdb, snaptest.ancient, "", false)
newdb, err := rawdb.Open(pdb, rawdb.OpenOptions{Ancient: snaptest.ancient})
if err != nil {
t.Fatalf("Failed to create persistent freezer database: %v", err)
}
@ -271,13 +274,13 @@ func (snaptest *crashSnapshotTest) test(t *testing.T) {
// the crash, we do restart twice here: one after the crash and one
// after the normal stop. It's used to ensure the broken snapshot
// can be detected all the time.
newchain, err := NewBlockChain(newdb, DefaultCacheConfigWithScheme(snaptest.scheme), snaptest.gspec, nil, snaptest.engine, vm.Config{}, nil)
newchain, err := NewBlockChain(newdb, snaptest.gspec, snaptest.engine, DefaultConfig().WithStateScheme(snaptest.scheme))
if err != nil {
t.Fatalf("Failed to recreate chain: %v", err)
}
newchain.Stop()
newchain, err = NewBlockChain(newdb, DefaultCacheConfigWithScheme(snaptest.scheme), snaptest.gspec, nil, snaptest.engine, vm.Config{}, nil)
newchain, err = NewBlockChain(newdb, snaptest.gspec, snaptest.engine, DefaultConfig().WithStateScheme(snaptest.scheme))
if err != nil {
t.Fatalf("Failed to recreate chain: %v", err)
}
@ -307,14 +310,15 @@ func (snaptest *gappedSnapshotTest) test(t *testing.T) {
gappedBlocks, _ := GenerateChain(snaptest.gspec.Config, blocks[len(blocks)-1], snaptest.engine, snaptest.genDb, snaptest.gapped, func(i int, b *BlockGen) {})
// Insert a few more blocks without enabling snapshot
var cacheConfig = &CacheConfig{
var options = &BlockChainConfig{
TrieCleanLimit: 256,
TrieDirtyLimit: 256,
TrieTimeLimit: 5 * time.Minute,
SnapshotLimit: 0,
StateScheme: snaptest.scheme,
TxLookupLimit: -1,
}
newchain, err := NewBlockChain(snaptest.db, cacheConfig, snaptest.gspec, nil, snaptest.engine, vm.Config{}, nil)
newchain, err := NewBlockChain(snaptest.db, snaptest.gspec, snaptest.engine, options)
if err != nil {
t.Fatalf("Failed to recreate chain: %v", err)
}
@ -322,7 +326,8 @@ func (snaptest *gappedSnapshotTest) test(t *testing.T) {
newchain.Stop()
// Restart the chain with enabling the snapshot
newchain, err = NewBlockChain(snaptest.db, DefaultCacheConfigWithScheme(snaptest.scheme), snaptest.gspec, nil, snaptest.engine, vm.Config{}, nil)
options = DefaultConfig().WithStateScheme(snaptest.scheme)
newchain, err = NewBlockChain(snaptest.db, snaptest.gspec, snaptest.engine, options)
if err != nil {
t.Fatalf("Failed to recreate chain: %v", err)
}
@ -350,7 +355,7 @@ func (snaptest *setHeadSnapshotTest) test(t *testing.T) {
chain.SetHead(snaptest.setHead)
chain.Stop()
newchain, err := NewBlockChain(snaptest.db, DefaultCacheConfigWithScheme(snaptest.scheme), snaptest.gspec, nil, snaptest.engine, vm.Config{}, nil)
newchain, err := NewBlockChain(snaptest.db, snaptest.gspec, snaptest.engine, DefaultConfig().WithStateScheme(snaptest.scheme))
if err != nil {
t.Fatalf("Failed to recreate chain: %v", err)
}
@ -379,14 +384,15 @@ func (snaptest *wipeCrashSnapshotTest) test(t *testing.T) {
// and state committed.
chain.Stop()
config := &CacheConfig{
config := &BlockChainConfig{
TrieCleanLimit: 256,
TrieDirtyLimit: 256,
TrieTimeLimit: 5 * time.Minute,
SnapshotLimit: 0,
StateScheme: snaptest.scheme,
TxLookupLimit: -1,
}
newchain, err := NewBlockChain(snaptest.db, config, snaptest.gspec, nil, snaptest.engine, vm.Config{}, nil)
newchain, err := NewBlockChain(snaptest.db, snaptest.gspec, snaptest.engine, config)
if err != nil {
t.Fatalf("Failed to recreate chain: %v", err)
}
@ -395,15 +401,16 @@ func (snaptest *wipeCrashSnapshotTest) test(t *testing.T) {
newchain.Stop()
// Restart the chain, the wiper should start working
config = &CacheConfig{
config = &BlockChainConfig{
TrieCleanLimit: 256,
TrieDirtyLimit: 256,
TrieTimeLimit: 5 * time.Minute,
SnapshotLimit: 256,
SnapshotWait: false, // Don't wait rebuild
StateScheme: snaptest.scheme,
TxLookupLimit: -1,
}
tmp, err := NewBlockChain(snaptest.db, config, snaptest.gspec, nil, snaptest.engine, vm.Config{}, nil)
tmp, err := NewBlockChain(snaptest.db, snaptest.gspec, snaptest.engine, config)
if err != nil {
t.Fatalf("Failed to recreate chain: %v", err)
}
@ -412,7 +419,7 @@ func (snaptest *wipeCrashSnapshotTest) test(t *testing.T) {
tmp.triedb.Close()
tmp.stopWithoutSaving()
newchain, err = NewBlockChain(snaptest.db, DefaultCacheConfigWithScheme(snaptest.scheme), snaptest.gspec, nil, snaptest.engine, vm.Config{}, nil)
newchain, err = NewBlockChain(snaptest.db, snaptest.gspec, snaptest.engine, DefaultConfig().WithStateScheme(snaptest.scheme))
if err != nil {
t.Fatalf("Failed to recreate chain: %v", err)
}
@ -565,12 +572,14 @@ func TestHighCommitCrashWithNewSnapshot(t *testing.T) {
//
// Expected head header : C8
// Expected head fast block: C8
// Expected head block : G
// Expected snapshot disk : C4
// Expected head block : G (Hash mode), C6 (Path mode)
// Expected snapshot disk : C4 (Hash mode)
for _, scheme := range []string{rawdb.HashScheme, rawdb.PathScheme} {
expHead := uint64(0)
if scheme == rawdb.PathScheme {
expHead = uint64(4)
// The pathdb database makes sure that snapshot and trie are consistent,
// so only the last two blocks are reverted in case of a crash.
expHead = uint64(6)
}
test := &crashSnapshotTest{
snapshotTestBasic{

View file

@ -25,10 +25,12 @@ import (
"math/rand"
"os"
"path"
"reflect"
"sync"
"testing"
"time"
"github.com/davecgh/go-spew/spew"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/beacon"
@ -46,6 +48,7 @@ import (
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/trie"
"github.com/holiman/uint256"
"github.com/stretchr/testify/assert"
)
// So we can deterministically seed different blockchains
@ -66,7 +69,8 @@ func newCanonical(engine consensus.Engine, n int, full bool, scheme string) (eth
}
)
// Initialize a fresh chain with only a genesis block
blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil)
options := DefaultConfig().WithStateScheme(scheme)
blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), genesis, engine, options)
// Create and inject the requested chain
if n == 0 {
@ -723,7 +727,7 @@ func testFastVsFullChains(t *testing.T, scheme string) {
})
// Import the chain as an archive node for the comparison baseline
archiveDb := rawdb.NewMemoryDatabase()
archive, _ := NewBlockChain(archiveDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
archive, _ := NewBlockChain(archiveDb, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
defer archive.Stop()
if n, err := archive.InsertChain(blocks); err != nil {
@ -731,23 +735,23 @@ func testFastVsFullChains(t *testing.T, scheme string) {
}
// Fast import the chain as a non-archive node to test
fastDb := rawdb.NewMemoryDatabase()
fast, _ := NewBlockChain(fastDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
fast, _ := NewBlockChain(fastDb, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
defer fast.Stop()
if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil {
if n, err := fast.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), 0); err != nil {
t.Fatalf("failed to insert receipt %d: %v", n, err)
}
// Freezer style fast import the chain.
ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
ancientDb, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
if err != nil {
t.Fatalf("failed to create temp freezer db: %v", err)
}
defer ancientDb.Close()
ancient, _ := NewBlockChain(ancientDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
ancient, _ := NewBlockChain(ancientDb, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
defer ancient.Stop()
if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(len(blocks)/2)); err != nil {
if n, err := ancient.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), uint64(len(blocks)/2)); err != nil {
t.Fatalf("failed to insert receipt %d: %v", n, err)
}
@ -824,7 +828,7 @@ func testLightVsFastVsFullChainHeads(t *testing.T, scheme string) {
// makeDb creates a db instance for testing.
makeDb := func() ethdb.Database {
db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
db, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
if err != nil {
t.Fatalf("failed to create temp freezer db: %v", err)
}
@ -851,11 +855,8 @@ func testLightVsFastVsFullChainHeads(t *testing.T, scheme string) {
archiveDb := makeDb()
defer archiveDb.Close()
archiveCaching := *defaultCacheConfig
archiveCaching.TrieDirtyDisabled = true
archiveCaching.StateScheme = scheme
archive, _ := NewBlockChain(archiveDb, &archiveCaching, gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
options := DefaultConfig().WithArchive(true).WithStateScheme(scheme)
archive, _ := NewBlockChain(archiveDb, gspec, ethash.NewFaker(), options)
if n, err := archive.InsertChain(blocks); err != nil {
t.Fatalf("failed to process block %d: %v", n, err)
}
@ -868,10 +869,10 @@ func testLightVsFastVsFullChainHeads(t *testing.T, scheme string) {
// Import the chain as a non-archive node and ensure all pointers are updated
fastDb := makeDb()
defer fastDb.Close()
fast, _ := NewBlockChain(fastDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
fast, _ := NewBlockChain(fastDb, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
defer fast.Stop()
if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil {
if n, err := fast.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), 0); err != nil {
t.Fatalf("failed to insert receipt %d: %v", n, err)
}
assert(t, "fast", fast, height, height, 0)
@ -881,10 +882,10 @@ func testLightVsFastVsFullChainHeads(t *testing.T, scheme string) {
// Import the chain as a ancient-first node and ensure all pointers are updated
ancientDb := makeDb()
defer ancientDb.Close()
ancient, _ := NewBlockChain(ancientDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
ancient, _ := NewBlockChain(ancientDb, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
defer ancient.Stop()
if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
if n, err := ancient.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), uint64(3*len(blocks)/4)); err != nil {
t.Fatalf("failed to insert receipt %d: %v", n, err)
}
assert(t, "ancient", ancient, height, height, 0)
@ -902,7 +903,7 @@ func testLightVsFastVsFullChainHeads(t *testing.T, scheme string) {
for i, block := range blocks {
headers[i] = block.Header()
}
light, _ := NewBlockChain(lightDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
light, _ := NewBlockChain(lightDb, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
if n, err := light.InsertHeaderChain(headers); err != nil {
t.Fatalf("failed to insert header %d: %v", n, err)
}
@ -975,7 +976,7 @@ func testChainTxReorgs(t *testing.T, scheme string) {
})
// Import the chain. This runs all block validation rules.
db := rawdb.NewMemoryDatabase()
blockchain, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
blockchain, _ := NewBlockChain(db, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
if i, err := blockchain.InsertChain(chain); err != nil {
t.Fatalf("failed to insert original chain[%d]: %v", i, err)
}
@ -1006,29 +1007,47 @@ func testChainTxReorgs(t *testing.T, scheme string) {
// removed tx
for i, tx := range (types.Transactions{pastDrop, freshDrop}) {
if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil {
if txn, _, _, _ := rawdb.ReadCanonicalTransaction(db, tx.Hash()); txn != nil {
t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
}
if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt != nil {
if rcpt, _, _, _ := rawdb.ReadCanonicalReceipt(db, tx.Hash(), blockchain.Config()); rcpt != nil {
t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt)
}
}
// added tx
for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) {
if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
if txn, _, _, _ := rawdb.ReadCanonicalTransaction(db, tx.Hash()); txn == nil {
t.Errorf("add %d: expected tx to be found", i)
}
if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
if rcpt, _, _, index := rawdb.ReadCanonicalReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
t.Errorf("add %d: expected receipt to be found", i)
} else if rawRcpt, ctx, _ := rawdb.ReadCanonicalRawReceipt(db, rcpt.BlockHash, rcpt.BlockNumber.Uint64(), index); rawRcpt == nil {
t.Errorf("add %d: expected raw receipt to be found", i)
} else {
if rcpt.GasUsed != ctx.GasUsed {
t.Errorf("add %d, raw gasUsedSoFar doesn't make sense", i)
}
if len(rcpt.Logs) > 0 && rcpt.Logs[0].Index != ctx.LogIndex {
t.Errorf("add %d, raw startingLogIndex doesn't make sense", i)
}
}
}
// shared tx
for i, tx := range (types.Transactions{postponed, swapped}) {
if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
if txn, _, _, _ := rawdb.ReadCanonicalTransaction(db, tx.Hash()); txn == nil {
t.Errorf("share %d: expected tx to be found", i)
}
if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
if rcpt, _, _, index := rawdb.ReadCanonicalReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
t.Errorf("share %d: expected receipt to be found", i)
} else if rawRcpt, ctx, _ := rawdb.ReadCanonicalRawReceipt(db, rcpt.BlockHash, rcpt.BlockNumber.Uint64(), index); rawRcpt == nil {
t.Errorf("add %d: expected raw receipt to be found", i)
} else {
if rcpt.GasUsed != ctx.GasUsed {
t.Errorf("add %d, raw gasUsedSoFar doesn't make sense", i)
}
if len(rcpt.Logs) > 0 && rcpt.Logs[0].Index != ctx.LogIndex {
t.Errorf("add %d, raw startingLogIndex doesn't make sense", i)
}
}
}
}
@ -1049,7 +1068,7 @@ func testLogReorgs(t *testing.T, scheme string) {
signer = types.LatestSigner(gspec.Config)
)
blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
defer blockchain.Stop()
rmLogsCh := make(chan RemovedLogsEvent)
@ -1105,7 +1124,7 @@ func testLogRebirth(t *testing.T, scheme string) {
gspec = &Genesis{Config: params.TestChainConfig, Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}}
signer = types.LatestSigner(gspec.Config)
engine = ethash.NewFaker()
blockchain, _ = NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil)
blockchain, _ = NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, DefaultConfig().WithStateScheme(scheme))
)
defer blockchain.Stop()
@ -1186,7 +1205,7 @@ func testSideLogRebirth(t *testing.T, scheme string) {
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
gspec = &Genesis{Config: params.TestChainConfig, Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}}
signer = types.LatestSigner(gspec.Config)
blockchain, _ = NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
blockchain, _ = NewBlockChain(rawdb.NewMemoryDatabase(), gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
)
defer blockchain.Stop()
@ -1385,7 +1404,7 @@ func testEIP155Transition(t *testing.T, scheme string) {
}
})
blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
defer blockchain.Stop()
if _, err := blockchain.InsertChain(blocks); err != nil {
@ -1478,7 +1497,7 @@ func testEIP161AccountRemoval(t *testing.T, scheme string) {
block.AddTx(tx)
})
// account must exist pre eip 161
blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
defer blockchain.Stop()
if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
@ -1536,7 +1555,7 @@ func testBlockchainHeaderchainReorgConsistency(t *testing.T, scheme string) {
}
// Import the canonical and fork chain side by side, verifying the current block
// and current header consistency
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), genesis, engine, DefaultConfig().WithStateScheme(scheme))
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -1580,7 +1599,7 @@ func TestTrieForkGC(t *testing.T) {
forks[i] = fork[0]
}
// Import the canonical and fork chain side by side, forcing the trie cache to cache both
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, genesis, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), genesis, engine, nil)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -1623,10 +1642,10 @@ func testLargeReorgTrieGC(t *testing.T, scheme string) {
competitor, _ := GenerateChain(genesis.Config, shared[len(shared)-1], engine, genDb, 2*state.TriesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
// Import the shared chain and the original canonical one
db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
db, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
defer db.Close()
chain, err := NewBlockChain(db, DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(db, genesis, engine, DefaultConfig().WithStateScheme(scheme))
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -1689,14 +1708,14 @@ func testBlockchainRecovery(t *testing.T, scheme string) {
_, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), int(height), nil)
// Import the chain as a ancient-first node and ensure all pointers are updated
ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false)
ancientDb, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{Ancient: t.TempDir()})
if err != nil {
t.Fatalf("failed to create temp freezer db: %v", err)
}
defer ancientDb.Close()
ancient, _ := NewBlockChain(ancientDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
ancient, _ := NewBlockChain(ancientDb, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
if n, err := ancient.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), uint64(3*len(blocks)/4)); err != nil {
t.Fatalf("failed to insert receipt %d: %v", n, err)
}
rawdb.WriteLastPivotNumber(ancientDb, blocks[len(blocks)-1].NumberU64()) // Force fast sync behavior
@ -1707,7 +1726,7 @@ func testBlockchainRecovery(t *testing.T, scheme string) {
rawdb.WriteHeadFastBlockHash(ancientDb, midBlock.Hash())
// Reopen broken blockchain again
ancient, _ = NewBlockChain(ancientDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
ancient, _ = NewBlockChain(ancientDb, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
defer ancient.Stop()
if num := ancient.CurrentBlock().Number.Uint64(); num != 0 {
t.Errorf("head block mismatch: have #%v, want #%v", num, 0)
@ -1747,10 +1766,10 @@ func testLowDiffLongChain(t *testing.T, scheme string) {
})
// Import the canonical chain
diskdb, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
diskdb, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
defer diskdb.Close()
chain, err := NewBlockChain(diskdb, DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(diskdb, genesis, engine, DefaultConfig().WithStateScheme(scheme))
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -1811,7 +1830,7 @@ func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommon
mergeBlock = gomath.MaxInt32
)
// Generate and import the canonical chain
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, nil)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -1959,13 +1978,13 @@ func testInsertKnownChainData(t *testing.T, typ string, scheme string) {
b.OffsetTime(-9) // A higher difficulty
})
// Import the shared chain and the original canonical one
chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
chaindb, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
if err != nil {
t.Fatalf("failed to create temp freezer db: %v", err)
}
defer chaindb.Close()
chain, err := NewBlockChain(chaindb, DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(chaindb, genesis, engine, DefaultConfig().WithStateScheme(scheme))
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -1991,7 +2010,7 @@ func testInsertKnownChainData(t *testing.T, typ string, scheme string) {
}
} else if typ == "receipts" {
inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
_, err = chain.InsertReceiptChain(blocks, receipts, 0)
_, err = chain.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), 0)
return err
}
asserter = func(t *testing.T, block *types.Block) {
@ -2122,13 +2141,13 @@ func testInsertKnownChainDataWithMerging(t *testing.T, typ string, mergeHeight i
}
})
// Import the shared chain and the original canonical one
chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
chaindb, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
if err != nil {
t.Fatalf("failed to create temp freezer db: %v", err)
}
defer chaindb.Close()
chain, err := NewBlockChain(chaindb, nil, genesis, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(chaindb, genesis, engine, nil)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -2157,7 +2176,7 @@ func testInsertKnownChainDataWithMerging(t *testing.T, typ string, mergeHeight i
}
} else if typ == "receipts" {
inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
_, err = chain.InsertReceiptChain(blocks, receipts, 0)
_, err = chain.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), 0)
return err
}
asserter = func(t *testing.T, block *types.Block) {
@ -2234,7 +2253,7 @@ func getLongAndShortChains(scheme string) (*BlockChain, []*types.Block, []*types
genDb, longChain, _ := GenerateChainWithGenesis(genesis, engine, 80, func(i int, b *BlockGen) {
b.SetCoinbase(common.Address{1})
})
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), genesis, engine, DefaultConfig().WithStateScheme(scheme))
if err != nil {
return nil, nil, nil, nil, fmt.Errorf("failed to create tester chain: %v", err)
}
@ -2410,7 +2429,7 @@ func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks in
b.ResetTimer()
for i := 0; i < b.N; i++ {
// Import the shared chain and the original canonical one
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, nil)
if err != nil {
b.Fatalf("failed to create tester chain: %v", err)
}
@ -2496,13 +2515,13 @@ func testSideImportPrunedBlocks(t *testing.T, scheme string) {
if err != nil {
t.Fatalf("Failed to create persistent key-value database: %v", err)
}
db, err := rawdb.NewDatabaseWithFreezer(pdb, ancient, "", false)
db, err := rawdb.Open(pdb, rawdb.OpenOptions{Ancient: ancient})
if err != nil {
t.Fatalf("Failed to create persistent freezer database: %v", err)
}
defer db.Close()
chain, err := NewBlockChain(db, DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(db, genesis, engine, DefaultConfig().WithStateScheme(scheme))
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -2601,7 +2620,8 @@ func testDeleteCreateRevert(t *testing.T, scheme string) {
b.AddTx(tx)
})
// Import the canonical chain
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil)
options := DefaultConfig().WithStateScheme(scheme)
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -2714,9 +2734,11 @@ func testDeleteRecreateSlots(t *testing.T, scheme string) {
b.AddTx(tx)
})
// Import the canonical chain
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{
options := DefaultConfig().WithStateScheme(scheme)
options.VmConfig = vm.Config{
Tracer: logger.NewJSONLogger(nil, os.Stdout),
}, nil)
}
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -2796,9 +2818,11 @@ func testDeleteRecreateAccount(t *testing.T, scheme string) {
b.AddTx(tx)
})
// Import the canonical chain
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{
options := DefaultConfig().WithStateScheme(scheme)
options.VmConfig = vm.Config{
Tracer: logger.NewJSONLogger(nil, os.Stdout),
}, nil)
}
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -2971,10 +2995,12 @@ func testDeleteRecreateSlotsAcrossManyBlocks(t *testing.T, scheme string) {
current = exp
})
// Import the canonical chain
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{
options := DefaultConfig().WithStateScheme(scheme)
options.VmConfig = vm.Config{
//Debug: true,
//Tracer: vm.NewJSONLogger(nil, os.Stdout),
}, nil)
}
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -3109,10 +3135,12 @@ func testInitThenFailCreateContract(t *testing.T, scheme string) {
})
// Import the canonical chain
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{
options := DefaultConfig().WithStateScheme(scheme)
options.VmConfig = vm.Config{
//Debug: true,
//Tracer: vm.NewJSONLogger(nil, os.Stdout),
}, nil)
}
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -3199,7 +3227,8 @@ func testEIP2718Transition(t *testing.T, scheme string) {
})
// Import the canonical chain
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil)
options := DefaultConfig().WithStateScheme(scheme)
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -3293,7 +3322,8 @@ func testEIP1559Transition(t *testing.T, scheme string) {
b.AddTx(tx)
})
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil)
options := DefaultConfig().WithStateScheme(scheme)
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -3403,10 +3433,11 @@ func testSetCanonical(t *testing.T, scheme string) {
}
gen.AddTx(tx)
})
diskdb, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
diskdb, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
defer diskdb.Close()
chain, err := NewBlockChain(diskdb, DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil)
options := DefaultConfig().WithStateScheme(scheme)
chain, err := NewBlockChain(diskdb, gspec, engine, options)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -3515,7 +3546,8 @@ func testCanonicalHashMarker(t *testing.T, scheme string) {
_, forkB, _ := GenerateChainWithGenesis(gspec, engine, c.forkB, func(i int, gen *BlockGen) {})
// Initialize test chain
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil)
options := DefaultConfig().WithStateScheme(scheme)
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -3649,10 +3681,7 @@ func testCreateThenDelete(t *testing.T, config *params.ChainConfig) {
nonce++
})
// Import the canonical chain
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{
//Debug: true,
//Tracer: logger.NewJSONLogger(nil, os.Stdout),
}, nil)
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, nil)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -3764,7 +3793,7 @@ func TestDeleteThenCreate(t *testing.T) {
}
})
// Import the canonical chain
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, nil)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -3849,7 +3878,9 @@ func TestTransientStorageReset(t *testing.T) {
})
// Initialize the blockchain with 1153 enabled.
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vmConfig, nil)
options := DefaultConfig()
options.VmConfig = vmConfig
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -3943,7 +3974,11 @@ func TestEIP3651(t *testing.T) {
b.AddTx(tx)
})
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{Tracer: logger.NewMarkdownLogger(&logger.Config{}, os.Stderr).Hooks()}, nil)
options := DefaultConfig()
options.VmConfig = vm.Config{
Tracer: logger.NewMarkdownLogger(&logger.Config{}, os.Stderr).Hooks(),
}
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -4052,7 +4087,7 @@ func TestPragueRequests(t *testing.T) {
}
// Insert block to check validation.
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, nil)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -4124,7 +4159,7 @@ func TestEIP7702(t *testing.T) {
tx := types.MustSignNewTx(key1, signer, txdata)
b.AddTx(tx)
})
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil)
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, nil)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -4199,16 +4234,17 @@ func testChainReorgSnapSync(t *testing.T, ancientLimit uint64) {
gen.SetCoinbase(common.Address{0: byte(0xb), 19: byte(i)})
})
db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
db, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
defer db.Close()
chain, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(rawdb.PathScheme), gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil)
options := DefaultConfig().WithStateScheme(rawdb.PathScheme)
chain, _ := NewBlockChain(db, gspec, beacon.New(ethash.NewFaker()), options)
defer chain.Stop()
if n, err := chain.InsertReceiptChain(blocks, receipts, ancientLimit); err != nil {
if n, err := chain.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), ancientLimit); err != nil {
t.Fatalf("failed to insert receipt %d: %v", n, err)
}
if n, err := chain.InsertReceiptChain(chainA, receiptsA, ancientLimit); err != nil {
if n, err := chain.InsertReceiptChain(chainA, types.EncodeBlockReceiptLists(receiptsA), ancientLimit); err != nil {
t.Fatalf("failed to insert receipt %d: %v", n, err)
}
// If the common ancestor is below the ancient limit, rewind the chain head.
@ -4218,7 +4254,7 @@ func testChainReorgSnapSync(t *testing.T, ancientLimit uint64) {
rawdb.WriteLastPivotNumber(db, ancestor)
chain.SetHead(ancestor)
}
if n, err := chain.InsertReceiptChain(chainB, receiptsB, ancientLimit); err != nil {
if n, err := chain.InsertReceiptChain(chainB, types.EncodeBlockReceiptLists(receiptsB), ancientLimit); err != nil {
t.Fatalf("failed to insert receipt %d: %v", n, err)
}
head := chain.CurrentSnapBlock()
@ -4312,12 +4348,14 @@ func testInsertChainWithCutoff(t *testing.T, cutoff uint64, ancientLimit uint64,
}()
// Enable pruning in cache config.
config := DefaultCacheConfigWithScheme(rawdb.PathScheme)
config := DefaultConfig().WithStateScheme(rawdb.PathScheme)
config.ChainHistoryMode = history.KeepPostMerge
db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
db, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
defer db.Close()
chain, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(rawdb.PathScheme), genesis, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil)
options := DefaultConfig().WithStateScheme(rawdb.PathScheme)
chain, _ := NewBlockChain(db, genesis, beacon.New(ethash.NewFaker()), options)
defer chain.Stop()
var (
@ -4336,7 +4374,7 @@ func testInsertChainWithCutoff(t *testing.T, cutoff uint64, ancientLimit uint64,
if n, err := chain.InsertHeadersBeforeCutoff(headersBefore); err != nil {
t.Fatalf("failed to insert headers before cutoff %d: %v", n, err)
}
if n, err := chain.InsertReceiptChain(blocksAfter, receiptsAfter, ancientLimit); err != nil {
if n, err := chain.InsertReceiptChain(blocksAfter, types.EncodeBlockReceiptLists(receiptsAfter), ancientLimit); err != nil {
t.Fatalf("failed to insert receipt %d: %v", n, err)
}
headSnap := chain.CurrentSnapBlock()
@ -4387,6 +4425,93 @@ func testInsertChainWithCutoff(t *testing.T, cutoff uint64, ancientLimit uint64,
if receipts == nil || len(receipts) != 1 {
t.Fatalf("Missed block receipts: %d, cutoff: %d", num, cutoffBlock.NumberU64())
}
for indx, receipt := range receipts {
receiptByLookup, err := chain.GetCanonicalReceipt(body.Transactions[indx], receipt.BlockHash,
receipt.BlockNumber.Uint64(), uint64(indx))
assert.NoError(t, err)
assert.Equal(t, receipt, receiptByLookup)
}
}
}
}
func TestGetCanonicalReceipt(t *testing.T) {
const chainLength = 64
// Configure and generate a sample block chain
var (
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
address = crypto.PubkeyToAddress(key.PublicKey)
funds = big.NewInt(1000000000000000000)
gspec = &Genesis{
Config: params.MergedTestChainConfig,
Alloc: types.GenesisAlloc{address: {Balance: funds}},
BaseFee: big.NewInt(params.InitialBaseFee),
}
signer = types.LatestSigner(gspec.Config)
engine = beacon.New(ethash.NewFaker())
codeBin = common.FromHex("0x608060405234801561000f575f5ffd5b507f8ae1c8c6e5f91159d0bc1c4b9a47ce45301753843012cbe641e4456bfc73538b33426040516100419291906100ff565b60405180910390a1610139565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100778261004e565b9050919050565b6100878161006d565b82525050565b5f819050919050565b61009f8161008d565b82525050565b5f82825260208201905092915050565b7f436f6e7374727563746f72207761732063616c6c6564000000000000000000005f82015250565b5f6100e96016836100a5565b91506100f4826100b5565b602082019050919050565b5f6060820190506101125f83018561007e565b61011f6020830184610096565b8181036040830152610130816100dd565b90509392505050565b603e806101455f395ff3fe60806040525f5ffdfea2646970667358221220e8bc3c31e3ac337eab702e8fdfc1c71894f4df1af4221bcde4a2823360f403fb64736f6c634300081e0033")
)
_, blocks, receipts := GenerateChainWithGenesis(gspec, engine, chainLength, func(i int, block *BlockGen) {
// SPDX-License-Identifier: MIT
// pragma solidity ^0.8.0;
//
// contract ConstructorLogger {
// event ConstructorLog(address sender, uint256 timestamp, string message);
//
// constructor() {
// emit ConstructorLog(msg.sender, block.timestamp, "Constructor was called");
// }
// }
//
// 608060405234801561000f575f5ffd5b507f8ae1c8c6e5f91159d0bc1c4b9a47ce45301753843012cbe641e4456bfc73538b33426040516100419291906100ff565b60405180910390a1610139565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100778261004e565b9050919050565b6100878161006d565b82525050565b5f819050919050565b61009f8161008d565b82525050565b5f82825260208201905092915050565b7f436f6e7374727563746f72207761732063616c6c6564000000000000000000005f82015250565b5f6100e96016836100a5565b91506100f4826100b5565b602082019050919050565b5f6060820190506101125f83018561007e565b61011f6020830184610096565b8181036040830152610130816100dd565b90509392505050565b603e806101455f395ff3fe60806040525f5ffdfea2646970667358221220e8bc3c31e3ac337eab702e8fdfc1c71894f4df1af4221bcde4a2823360f403fb64736f6c634300081e0033
nonce := block.TxNonce(address)
tx, err := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), 100_000, block.header.BaseFee, codeBin), signer, key)
if err != nil {
panic(err)
}
block.AddTx(tx)
tx2, err := types.SignTx(types.NewContractCreation(nonce+1, big.NewInt(0), 100_000, block.header.BaseFee, codeBin), signer, key)
if err != nil {
panic(err)
}
block.AddTx(tx2)
tx3, err := types.SignTx(types.NewContractCreation(nonce+2, big.NewInt(0), 100_000, block.header.BaseFee, codeBin), signer, key)
if err != nil {
panic(err)
}
block.AddTx(tx3)
})
db, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
defer db.Close()
options := DefaultConfig().WithStateScheme(rawdb.PathScheme)
chain, _ := NewBlockChain(db, gspec, beacon.New(ethash.NewFaker()), options)
defer chain.Stop()
chain.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), 0)
for i := 0; i < chainLength; i++ {
block := blocks[i]
blockReceipts := chain.GetReceiptsByHash(block.Hash())
chain.receiptsCache.Purge() // ugly hack
for txIndex, tx := range block.Body().Transactions {
receipt, err := chain.GetCanonicalReceipt(tx, block.Hash(), block.NumberU64(), uint64(txIndex))
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
if !reflect.DeepEqual(receipts[i][txIndex], receipt) {
want := spew.Sdump(receipts[i][txIndex])
got := spew.Sdump(receipt)
t.Fatalf("Receipt is not matched, want %s, got: %s", want, got)
}
if !reflect.DeepEqual(blockReceipts[txIndex], receipt) {
want := spew.Sdump(blockReceipts[txIndex])
got := spew.Sdump(receipt)
t.Fatalf("Receipt is not matched, want %s, got: %s", want, got)
}
}
}
}

View file

@ -124,7 +124,7 @@ func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transacti
}
// Merge the tx-local access event into the "block-local" one, in order to collect
// all values, so that the witness can be built.
if b.statedb.GetTrie().IsVerkle() {
if b.statedb.Database().TrieDB().IsVerkle() {
b.statedb.AccessEvents().Merge(evm.AccessEvents)
}
b.txs = append(b.txs, tx)
@ -579,7 +579,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine
func GenerateVerkleChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, gen func(int, *BlockGen)) (common.Hash, ethdb.Database, []*types.Block, []types.Receipts, []*verkle.VerkleProof, []verkle.StateDiff) {
db := rawdb.NewMemoryDatabase()
cacheConfig := DefaultCacheConfigWithScheme(rawdb.PathScheme)
cacheConfig := DefaultConfig().WithStateScheme(rawdb.PathScheme)
cacheConfig.SnapshotLimit = 0
triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true))
defer triedb.Close()

View file

@ -28,7 +28,6 @@ import (
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/triedb"
@ -119,7 +118,7 @@ func TestGeneratePOSChain(t *testing.T) {
})
// Import the chain. This runs all block validation rules.
blockchain, _ := NewBlockChain(db, nil, gspec, nil, engine, vm.Config{}, nil)
blockchain, _ := NewBlockChain(db, gspec, engine, nil)
defer blockchain.Stop()
if i, err := blockchain.InsertChain(genchain); err != nil {
@ -234,7 +233,7 @@ func ExampleGenerateChain() {
})
// Import the chain. This runs all block validation rules.
blockchain, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(rawdb.HashScheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
blockchain, _ := NewBlockChain(db, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(rawdb.HashScheme))
defer blockchain.Stop()
if i, err := blockchain.InsertChain(chain); err != nil {

View file

@ -22,7 +22,6 @@ import (
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params"
)
@ -50,7 +49,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
BaseFee: big.NewInt(params.InitialBaseFee),
Config: &proConf,
}
proBc, _ := NewBlockChain(proDb, nil, progspec, nil, ethash.NewFaker(), vm.Config{}, nil)
proBc, _ := NewBlockChain(proDb, progspec, ethash.NewFaker(), nil)
defer proBc.Stop()
conDb := rawdb.NewMemoryDatabase()
@ -62,7 +61,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
BaseFee: big.NewInt(params.InitialBaseFee),
Config: &conConf,
}
conBc, _ := NewBlockChain(conDb, nil, congspec, nil, ethash.NewFaker(), vm.Config{}, nil)
conBc, _ := NewBlockChain(conDb, congspec, ethash.NewFaker(), nil)
defer conBc.Stop()
if _, err := proBc.InsertChain(prefix); err != nil {
@ -74,7 +73,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
// Try to expand both pro-fork and non-fork chains iteratively with other camp's blocks
for i := int64(0); i < params.DAOForkExtraRange.Int64(); i++ {
// Create a pro-fork block, and try to feed into the no-fork chain
bc, _ := NewBlockChain(rawdb.NewMemoryDatabase(), nil, congspec, nil, ethash.NewFaker(), vm.Config{}, nil)
bc, _ := NewBlockChain(rawdb.NewMemoryDatabase(), congspec, ethash.NewFaker(), nil)
blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().Number.Uint64()))
for j := 0; j < len(blocks)/2; j++ {
@ -97,7 +96,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
t.Fatalf("contra-fork chain didn't accepted no-fork block: %v", err)
}
// Create a no-fork block, and try to feed into the pro-fork chain
bc, _ = NewBlockChain(rawdb.NewMemoryDatabase(), nil, progspec, nil, ethash.NewFaker(), vm.Config{}, nil)
bc, _ = NewBlockChain(rawdb.NewMemoryDatabase(), progspec, ethash.NewFaker(), nil)
blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().Number.Uint64()))
for j := 0; j < len(blocks)/2; j++ {
@ -121,7 +120,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
}
}
// Verify that contra-forkers accept pro-fork extra-datas after forking finishes
bc, _ := NewBlockChain(rawdb.NewMemoryDatabase(), nil, congspec, nil, ethash.NewFaker(), vm.Config{}, nil)
bc, _ := NewBlockChain(rawdb.NewMemoryDatabase(), congspec, ethash.NewFaker(), nil)
defer bc.Stop()
blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().Number.Uint64()))
@ -139,7 +138,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
t.Fatalf("contra-fork chain didn't accept pro-fork block post-fork: %v", err)
}
// Verify that pro-forkers accept contra-fork extra-datas after forking finishes
bc, _ = NewBlockChain(rawdb.NewMemoryDatabase(), nil, progspec, nil, ethash.NewFaker(), vm.Config{}, nil)
bc, _ = NewBlockChain(rawdb.NewMemoryDatabase(), progspec, ethash.NewFaker(), nil)
defer bc.Stop()
blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().Number.Uint64()))

View file

@ -29,7 +29,7 @@ type blockchain interface {
GetHeader(hash common.Hash, number uint64) *types.Header
GetCanonicalHash(number uint64) common.Hash
GetReceiptsByHash(hash common.Hash) types.Receipts
GetRawReceiptsByHash(hash common.Hash) types.Receipts
GetRawReceipts(hash common.Hash, number uint64) types.Receipts
}
// ChainView represents an immutable view of a chain with a block id and a set
@ -55,7 +55,9 @@ func NewChainView(chain blockchain, number uint64, hash common.Hash) *ChainView
headNumber: number,
hashes: []common.Hash{hash},
}
cv.extendNonCanonical()
if !cv.extendNonCanonical() {
return nil
}
return cv
}
@ -117,7 +119,7 @@ func (cv *ChainView) RawReceipts(number uint64) types.Receipts {
log.Error("Chain view: block hash unavailable", "number", number, "head", cv.headNumber)
return nil
}
return cv.chain.GetRawReceiptsByHash(blockHash)
return cv.chain.GetRawReceipts(blockHash, number)
}
// SharedRange returns the block range shared by two chain views.
@ -129,7 +131,11 @@ func (cv *ChainView) SharedRange(cv2 *ChainView) common.Range[uint64] {
return common.Range[uint64]{}
}
var sharedLen uint64
for n := min(cv.headNumber+1-uint64(len(cv.hashes)), cv2.headNumber+1-uint64(len(cv2.hashes))); n <= cv.headNumber && n <= cv2.headNumber && cv.blockHash(n) == cv2.blockHash(n); n++ {
for n := min(cv.headNumber+1-uint64(len(cv.hashes)), cv2.headNumber+1-uint64(len(cv2.hashes))); n <= cv.headNumber && n <= cv2.headNumber; n++ {
h1, h2 := cv.blockHash(n), cv2.blockHash(n)
if h1 != h2 || h1 == (common.Hash{}) {
break
}
sharedLen = n + 1
}
return common.NewRange(0, sharedLen)
@ -153,10 +159,13 @@ func matchViews(cv1, cv2 *ChainView, number uint64) bool {
if cv1.headNumber < number || cv2.headNumber < number {
return false
}
var h1, h2 common.Hash
if number == cv1.headNumber || number == cv2.headNumber {
return cv1.BlockId(number) == cv2.BlockId(number)
h1, h2 = cv1.BlockId(number), cv2.BlockId(number)
} else {
h1, h2 = cv1.BlockHash(number), cv2.BlockHash(number)
}
return cv1.BlockHash(number) == cv2.BlockHash(number)
return h1 == h2 && h1 != common.Hash{}
}
// extendNonCanonical checks whether the previously known reverse list of head
@ -175,7 +184,10 @@ func (cv *ChainView) extendNonCanonical() bool {
}
header := cv.chain.GetHeader(hash, number)
if header == nil {
log.Error("Header not found", "number", number, "hash", hash)
// Header not found - this can happen after debug_setHead operations
// where blocks have been deleted. Return false to indicate the chain view
// is no longer valid rather than logging repeated errors.
log.Debug("Header not found during chain view extension", "number", number, "hash", hash)
return false
}
cv.hashes = append(cv.hashes, header.ParentHash)

View file

@ -53,7 +53,6 @@ const (
databaseVersion = 2 // reindexed if database version does not match
cachedLastBlocks = 1000 // last block of map pointers
cachedLvPointers = 1000 // first log value pointer of block pointers
cachedBaseRows = 100 // groups of base layer filter row data
cachedFilterMaps = 3 // complete filter maps (cached by map renderer)
cachedRenderSnapshots = 8 // saved map renderer data at block boundaries
)
@ -101,7 +100,6 @@ type FilterMaps struct {
filterMapCache *lru.Cache[uint32, filterMap]
lastBlockCache *lru.Cache[uint32, lastBlockOfMap]
lvPointerCache *lru.Cache[uint64, uint64]
baseRowsCache *lru.Cache[uint64, [][]uint32]
// the matchers set and the fields of FilterMapsMatcherBackend instances are
// read and written both by exported functions and the indexer.
@ -187,11 +185,14 @@ type filterMapsRange struct {
initialized bool
headIndexed bool
headDelimiter uint64 // zero if headIndexed is false
// if initialized then all maps are rendered in the maps range
maps common.Range[uint32]
// if tailPartialEpoch > 0 then maps between firstRenderedMap-mapsPerEpoch and
// firstRenderedMap-mapsPerEpoch+tailPartialEpoch-1 are rendered
tailPartialEpoch uint32
// if initialized then all log values in the blocks range are fully
// rendered
// blockLvPointers are available in the blocks range
@ -225,13 +226,15 @@ type Config struct {
}
// NewFilterMaps creates a new FilterMaps and starts the indexer.
func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, finalBlock uint64, params Params, config Config) *FilterMaps {
func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, finalBlock uint64, params Params, config Config) (*FilterMaps, error) {
rs, initialized, err := rawdb.ReadFilterMapsRange(db)
if err != nil || rs.Version != databaseVersion {
if err != nil || (initialized && rs.Version != databaseVersion) {
rs, initialized = rawdb.FilterMapsRange{}, false
log.Warn("Invalid log index database version; resetting log index")
}
params.deriveFields()
if err := params.sanitize(); err != nil {
return nil, err
}
f := &FilterMaps{
db: db,
closeCh: make(chan struct{}),
@ -256,7 +259,6 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, f
},
// deleting last unindexed epoch might have been interrupted by shutdown
cleanedEpochsBefore: max(rs.MapsFirst>>params.logMapsPerEpoch, 1) - 1,
historyCutoff: historyCutoff,
finalBlock: finalBlock,
matcherSyncCh: make(chan *FilterMapsMatcherBackend),
@ -264,7 +266,6 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, f
filterMapCache: lru.NewCache[uint32, filterMap](cachedFilterMaps),
lastBlockCache: lru.NewCache[uint32, lastBlockOfMap](cachedLastBlocks),
lvPointerCache: lru.NewCache[uint64, uint64](cachedLvPointers),
baseRowsCache: lru.NewCache[uint64, [][]uint32](cachedBaseRows),
renderSnapshots: lru.NewCache[uint64, *renderedMap](cachedRenderSnapshots),
}
f.checkRevertRange() // revert maps that are inconsistent with the current chain view
@ -275,7 +276,7 @@ func NewFilterMaps(db ethdb.KeyValueStore, initView *ChainView, historyCutoff, f
"firstmap", f.indexedRange.maps.First(), "lastmap", f.indexedRange.maps.Last(),
"headindexed", f.indexedRange.headIndexed)
}
return f
return f, nil
}
// Start starts the indexer.
@ -348,7 +349,6 @@ func (f *FilterMaps) reset() {
f.renderSnapshots.Purge()
f.lastBlockCache.Purge()
f.lvPointerCache.Purge()
f.baseRowsCache.Purge()
f.indexLock.Unlock()
// deleting the range first ensures that resetDb will be called again at next
// startup and any leftover data will be removed even if it cannot finish now.
@ -403,7 +403,7 @@ func (f *FilterMaps) init() error {
batch := f.db.NewBatch()
for epoch := range bestLen {
cp := checkpoints[bestIdx][epoch]
f.storeLastBlockOfMap(batch, (uint32(epoch+1)<<f.logMapsPerEpoch)-1, cp.BlockNumber, cp.BlockId)
f.storeLastBlockOfMap(batch, f.lastEpochMap(uint32(epoch)), cp.BlockNumber, cp.BlockId)
f.storeBlockLvPointer(batch, cp.BlockNumber, cp.FirstIndex)
}
fmr := filterMapsRange{
@ -412,7 +412,7 @@ func (f *FilterMaps) init() error {
if bestLen > 0 {
cp := checkpoints[bestIdx][bestLen-1]
fmr.blocks = common.NewRange(cp.BlockNumber+1, 0)
fmr.maps = common.NewRange(uint32(bestLen)<<f.logMapsPerEpoch, 0)
fmr.maps = common.NewRange(f.firstEpochMap(uint32(bestLen)), 0)
}
f.setRange(batch, f.targetView, fmr, false)
return batch.Write()
@ -565,53 +565,81 @@ func (f *FilterMaps) getFilterMap(mapIndex uint32) (filterMap, error) {
}
fm := make(filterMap, f.mapHeight)
for rowIndex := range fm {
var err error
fm[rowIndex], err = f.getFilterMapRow(mapIndex, uint32(rowIndex), false)
rows, err := f.getFilterMapRows([]uint32{mapIndex}, uint32(rowIndex), false)
if err != nil {
return nil, fmt.Errorf("failed to load filter map %d from database: %v", mapIndex, err)
}
fm[rowIndex] = rows[0]
}
f.filterMapCache.Add(mapIndex, fm)
return fm, nil
}
// getFilterMapRow fetches the given filter map row. If baseLayerOnly is true
// then only the first baseRowLength entries are returned.
func (f *FilterMaps) getFilterMapRow(mapIndex, rowIndex uint32, baseLayerOnly bool) (FilterRow, error) {
baseMapRowIndex := f.mapRowIndex(mapIndex&-f.baseRowGroupLength, rowIndex)
baseRows, ok := f.baseRowsCache.Get(baseMapRowIndex)
if !ok {
var err error
baseRows, err = rawdb.ReadFilterMapBaseRows(f.db, baseMapRowIndex, f.baseRowGroupLength, f.logMapWidth)
// getFilterMapRows fetches a set of filter map rows at the corresponding map
// indices and a shared row index. If baseLayerOnly is true then only the first
// baseRowLength entries are returned.
func (f *FilterMaps) getFilterMapRows(mapIndices []uint32, rowIndex uint32, baseLayerOnly bool) ([]FilterRow, error) {
rows := make([]FilterRow, len(mapIndices))
var ptr int
for len(mapIndices) > ptr {
var (
groupIndex = f.mapGroupIndex(mapIndices[ptr])
groupLength = 1
)
for ptr+groupLength < len(mapIndices) && f.mapGroupIndex(mapIndices[ptr+groupLength]) == groupIndex {
groupLength++
}
if err := f.getFilterMapRowsOfGroup(rows[ptr:ptr+groupLength], mapIndices[ptr:ptr+groupLength], rowIndex, baseLayerOnly); err != nil {
return nil, err
}
ptr += groupLength
}
return rows, nil
}
// getFilterMapRowsOfGroup fetches a set of filter map rows at map indices
// belonging to the same base row group.
func (f *FilterMaps) getFilterMapRowsOfGroup(target []FilterRow, mapIndices []uint32, rowIndex uint32, baseLayerOnly bool) error {
var (
groupIndex = f.mapGroupIndex(mapIndices[0])
mapRowIndex = f.mapRowIndex(groupIndex, rowIndex)
)
baseRows, err := rawdb.ReadFilterMapBaseRows(f.db, mapRowIndex, f.baseRowGroupSize, f.logMapWidth)
if err != nil {
return nil, fmt.Errorf("failed to retrieve filter map %d base rows %d: %v", mapIndex, rowIndex, err)
return fmt.Errorf("failed to retrieve base row group %d of row %d: %v", groupIndex, rowIndex, err)
}
f.baseRowsCache.Add(baseMapRowIndex, baseRows)
}
baseRow := slices.Clone(baseRows[mapIndex&(f.baseRowGroupLength-1)])
if baseLayerOnly {
return baseRow, nil
for i, mapIndex := range mapIndices {
if f.mapGroupIndex(mapIndex) != groupIndex {
return fmt.Errorf("maps are not in the same base row group, index: %d, group: %d", mapIndex, groupIndex)
}
row := baseRows[f.mapGroupOffset(mapIndex)]
if !baseLayerOnly {
extRow, err := rawdb.ReadFilterMapExtRow(f.db, f.mapRowIndex(mapIndex, rowIndex), f.logMapWidth)
if err != nil {
return nil, fmt.Errorf("failed to retrieve filter map %d extended row %d: %v", mapIndex, rowIndex, err)
return fmt.Errorf("failed to retrieve filter map %d extended row %d: %v", mapIndex, rowIndex, err)
}
return FilterRow(append(baseRow, extRow...)), nil
row = append(row, extRow...)
}
target[i] = row
}
return nil
}
// storeFilterMapRows stores a set of filter map rows at the corresponding map
// indices and a shared row index.
func (f *FilterMaps) storeFilterMapRows(batch ethdb.Batch, mapIndices []uint32, rowIndex uint32, rows []FilterRow) error {
for len(mapIndices) > 0 {
baseMapIndex := mapIndices[0] & -f.baseRowGroupLength
groupLength := 1
for groupLength < len(mapIndices) && mapIndices[groupLength]&-f.baseRowGroupLength == baseMapIndex {
groupLength++
var (
pos = 1
groupIndex = f.mapGroupIndex(mapIndices[0])
)
for pos < len(mapIndices) && f.mapGroupIndex(mapIndices[pos]) == groupIndex {
pos++
}
if err := f.storeFilterMapRowsOfGroup(batch, mapIndices[:groupLength], rowIndex, rows[:groupLength]); err != nil {
if err := f.storeFilterMapRowsOfGroup(batch, mapIndices[:pos], rowIndex, rows[:pos]); err != nil {
return err
}
mapIndices, rows = mapIndices[groupLength:], rows[groupLength:]
mapIndices, rows = mapIndices[pos:], rows[pos:]
}
return nil
}
@ -619,27 +647,23 @@ func (f *FilterMaps) storeFilterMapRows(batch ethdb.Batch, mapIndices []uint32,
// storeFilterMapRowsOfGroup stores a set of filter map rows at map indices
// belonging to the same base row group.
func (f *FilterMaps) storeFilterMapRowsOfGroup(batch ethdb.Batch, mapIndices []uint32, rowIndex uint32, rows []FilterRow) error {
baseMapIndex := mapIndices[0] & -f.baseRowGroupLength
baseMapRowIndex := f.mapRowIndex(baseMapIndex, rowIndex)
var baseRows [][]uint32
if uint32(len(mapIndices)) != f.baseRowGroupLength { // skip base rows read if all rows are replaced
var ok bool
baseRows, ok = f.baseRowsCache.Get(baseMapRowIndex)
if ok {
baseRows = slices.Clone(baseRows)
} else {
var (
baseRows [][]uint32
groupIndex = f.mapGroupIndex(mapIndices[0])
mapRowIndex = f.mapRowIndex(groupIndex, rowIndex)
)
if uint32(len(mapIndices)) != f.baseRowGroupSize { // skip base rows read if all rows are replaced
var err error
baseRows, err = rawdb.ReadFilterMapBaseRows(f.db, baseMapRowIndex, f.baseRowGroupLength, f.logMapWidth)
baseRows, err = rawdb.ReadFilterMapBaseRows(f.db, mapRowIndex, f.baseRowGroupSize, f.logMapWidth)
if err != nil {
return fmt.Errorf("failed to retrieve filter map %d base rows %d for modification: %v", mapIndices[0]&-f.baseRowGroupLength, rowIndex, err)
}
return fmt.Errorf("failed to retrieve filter map %d base rows %d for modification: %v", groupIndex, rowIndex, err)
}
} else {
baseRows = make([][]uint32, f.baseRowGroupLength)
baseRows = make([][]uint32, f.baseRowGroupSize)
}
for i, mapIndex := range mapIndices {
if mapIndex&-f.baseRowGroupLength != baseMapIndex {
panic("mapIndices are not in the same base row group")
if f.mapGroupIndex(mapIndex) != groupIndex {
return fmt.Errorf("maps are not in the same base row group, index: %d, group: %d", mapIndex, groupIndex)
}
baseRow := []uint32(rows[i])
var extRow FilterRow
@ -647,11 +671,10 @@ func (f *FilterMaps) storeFilterMapRowsOfGroup(batch ethdb.Batch, mapIndices []u
extRow = baseRow[f.baseRowLength:]
baseRow = baseRow[:f.baseRowLength]
}
baseRows[mapIndex&(f.baseRowGroupLength-1)] = baseRow
baseRows[f.mapGroupOffset(mapIndex)] = baseRow
rawdb.WriteFilterMapExtRow(batch, f.mapRowIndex(mapIndex, rowIndex), extRow, f.logMapWidth)
}
f.baseRowsCache.Add(baseMapRowIndex, baseRows)
rawdb.WriteFilterMapBaseRows(batch, baseMapRowIndex, baseRows, f.logMapWidth)
rawdb.WriteFilterMapBaseRows(batch, mapRowIndex, baseRows, f.logMapWidth)
return nil
}
@ -736,12 +759,12 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) {
defer f.indexLock.Unlock()
// determine epoch boundaries
firstMap := epoch << f.logMapsPerEpoch
lastBlock, _, err := f.getLastBlockOfMap(firstMap + f.mapsPerEpoch - 1)
lastBlock, _, err := f.getLastBlockOfMap(f.lastEpochMap(epoch))
if err != nil {
return false, fmt.Errorf("failed to retrieve last block of deleted epoch %d: %v", epoch, err)
}
var firstBlock uint64
firstMap := f.firstEpochMap(epoch)
if epoch > 0 {
firstBlock, _, err = f.getLastBlockOfMap(firstMap - 1)
if err != nil {
@ -752,8 +775,8 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) {
// update rendered range if necessary
var (
fmr = f.indexedRange
firstEpoch = f.indexedRange.maps.First() >> f.logMapsPerEpoch
afterLastEpoch = (f.indexedRange.maps.AfterLast() + f.mapsPerEpoch - 1) >> f.logMapsPerEpoch
firstEpoch = f.mapEpoch(f.indexedRange.maps.First())
afterLastEpoch = f.mapEpoch(f.indexedRange.maps.AfterLast() + f.mapsPerEpoch - 1)
)
if f.indexedRange.tailPartialEpoch != 0 && firstEpoch > 0 {
firstEpoch--
@ -765,7 +788,7 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) {
// first fully or partially rendered epoch and there is at least one
// rendered map in the next epoch; remove from indexed range
fmr.tailPartialEpoch = 0
fmr.maps.SetFirst((epoch + 1) << f.logMapsPerEpoch)
fmr.maps.SetFirst(f.firstEpochMap(epoch + 1))
fmr.blocks.SetFirst(lastBlock + 1)
f.setRange(f.db, f.indexedView, fmr, false)
default:
@ -846,7 +869,7 @@ func (f *FilterMaps) exportCheckpoints() {
w.WriteString("[\n")
comma := ","
for epoch := uint32(0); epoch < epochCount; epoch++ {
lastBlock, lastBlockId, err := f.getLastBlockOfMap((epoch+1)<<f.logMapsPerEpoch - 1)
lastBlock, lastBlockId, err := f.getLastBlockOfMap(f.lastEpochMap(epoch))
if err != nil {
log.Error("Error fetching last block of epoch", "epoch", epoch, "error", err)
return

View file

@ -281,7 +281,7 @@ func (f *FilterMaps) tryIndexHead() error {
// is changed.
func (f *FilterMaps) tryIndexTail() (bool, error) {
for {
firstEpoch := f.indexedRange.maps.First() >> f.logMapsPerEpoch
firstEpoch := f.mapEpoch(f.indexedRange.maps.First())
if firstEpoch == 0 || !f.needTailEpoch(firstEpoch-1) {
break
}
@ -359,7 +359,7 @@ func (f *FilterMaps) tryIndexTail() (bool, error) {
// Note that unindexing is very quick as it only removes continuous ranges of
// data from the database and is also called while running head indexing.
func (f *FilterMaps) tryUnindexTail() (bool, error) {
firstEpoch := f.indexedRange.maps.First() >> f.logMapsPerEpoch
firstEpoch := f.mapEpoch(f.indexedRange.maps.First())
if f.indexedRange.tailPartialEpoch > 0 && firstEpoch > 0 {
firstEpoch--
}
@ -392,11 +392,11 @@ func (f *FilterMaps) tryUnindexTail() (bool, error) {
// needTailEpoch returns true if the given tail epoch needs to be kept
// according to the current tail target, false if it can be removed.
func (f *FilterMaps) needTailEpoch(epoch uint32) bool {
firstEpoch := f.indexedRange.maps.First() >> f.logMapsPerEpoch
firstEpoch := f.mapEpoch(f.indexedRange.maps.First())
if epoch > firstEpoch {
return true
}
if (epoch+1)<<f.logMapsPerEpoch >= f.indexedRange.maps.AfterLast() {
if f.firstEpochMap(epoch+1) >= f.indexedRange.maps.AfterLast() {
return true
}
if epoch+1 < firstEpoch {
@ -405,7 +405,7 @@ func (f *FilterMaps) needTailEpoch(epoch uint32) bool {
var lastBlockOfPrevEpoch uint64
if epoch > 0 {
var err error
lastBlockOfPrevEpoch, _, err = f.getLastBlockOfMap(epoch<<f.logMapsPerEpoch - 1)
lastBlockOfPrevEpoch, _, err = f.getLastBlockOfMap(f.lastEpochMap(epoch - 1))
if err != nil {
log.Error("Could not get last block of previous epoch", "epoch", epoch-1, "error", err)
return epoch >= firstEpoch
@ -414,7 +414,7 @@ func (f *FilterMaps) needTailEpoch(epoch uint32) bool {
if f.historyCutoff > lastBlockOfPrevEpoch {
return false
}
lastBlockOfEpoch, _, err := f.getLastBlockOfMap((epoch+1)<<f.logMapsPerEpoch - 1)
lastBlockOfEpoch, _, err := f.getLastBlockOfMap(f.lastEpochMap(epoch))
if err != nil {
log.Error("Could not get last block of epoch", "epoch", epoch, "error", err)
return epoch >= firstEpoch

View file

@ -41,7 +41,7 @@ var testParams = Params{
logMapWidth: 24,
logMapsPerEpoch: 4,
logValuesPerMap: 4,
baseRowGroupLength: 4,
baseRowGroupSize: 4,
baseRowLengthRatio: 2,
logLayerDiff: 2,
}
@ -370,7 +370,7 @@ func (ts *testSetup) setHistory(history uint64, noHistory bool) {
History: history,
Disabled: noHistory,
}
ts.fm = NewFilterMaps(ts.db, view, 0, 0, ts.params, config)
ts.fm, _ = NewFilterMaps(ts.db, view, 0, 0, ts.params, config)
ts.fm.testDisableSnapshots = ts.testDisableSnapshots
ts.fm.Start()
}
@ -428,13 +428,15 @@ func (ts *testSetup) matcherViewHash() common.Hash {
binary.LittleEndian.PutUint32(enc[:4], r)
for m := uint32(0); m <= headMap; m++ {
binary.LittleEndian.PutUint32(enc[4:8], m)
row, _ := mb.GetFilterMapRow(ctx, m, r, false)
rows, _ := mb.GetFilterMapRows(ctx, []uint32{m}, r, false)
for _, row := range rows {
for _, v := range row {
binary.LittleEndian.PutUint32(enc[8:], v)
hasher.Write(enc[:])
}
}
}
}
var hash common.Hash
hasher.Sum(hash[:0])
for i := 0; i < 50; i++ {
@ -515,7 +517,7 @@ func (tc *testChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
return tc.receipts[hash]
}
func (tc *testChain) GetRawReceiptsByHash(hash common.Hash) types.Receipts {
func (tc *testChain) GetRawReceipts(hash common.Hash, number uint64) types.Receipts {
tc.lock.RLock()
defer tc.lock.RUnlock()

View file

@ -284,7 +284,7 @@ func (r *mapRenderer) run(stopCb func() bool, writeCb func()) (bool, error) {
// map finished
r.finishedMaps[r.currentMap.mapIndex] = r.currentMap
r.finished.SetLast(r.finished.AfterLast())
if len(r.finishedMaps) >= maxMapsPerBatch || r.finished.AfterLast()&(r.f.baseRowGroupLength-1) == 0 {
if len(r.finishedMaps) >= maxMapsPerBatch || r.f.mapGroupOffset(r.finished.AfterLast()) == 0 {
if err := r.writeFinishedMaps(stopCb); err != nil {
return false, err
}

View file

@ -20,7 +20,6 @@ import (
"context"
"errors"
"fmt"
"math"
"sync"
"sync/atomic"
"time"
@ -45,7 +44,7 @@ var ErrMatchAll = errors.New("match all patterns not supported")
type MatcherBackend interface {
GetParams() *Params
GetBlockLvPointer(ctx context.Context, blockNumber uint64) (uint64, error)
GetFilterMapRow(ctx context.Context, mapIndex, rowIndex uint32, baseLayerOnly bool) (FilterRow, error)
GetFilterMapRows(ctx context.Context, mapIndices []uint32, rowIndex uint32, baseLayerOnly bool) ([]FilterRow, error)
GetLogByLvIndex(ctx context.Context, lvIndex uint64) (*types.Log, error)
SyncLogIndex(ctx context.Context) (SyncRange, error)
Close()
@ -365,26 +364,32 @@ func (m *singleMatcherInstance) getMatchesForLayer(ctx context.Context, layerInd
var st int
m.stats.setState(&st, stOther)
params := m.backend.GetParams()
maskedMapIndex, rowIndex := uint32(math.MaxUint32), uint32(0)
for _, mapIndex := range m.mapIndices {
filterRows, ok := m.filterRows[mapIndex]
if !ok {
continue
}
if mm := params.maskedMapIndex(mapIndex, layerIndex); mm != maskedMapIndex {
// only recalculate rowIndex when necessary
maskedMapIndex = mm
rowIndex = params.rowIndex(mapIndex, layerIndex, m.value)
var ptr int
for len(m.mapIndices) > ptr {
// find next group of map indices mapped onto the same row
maskedMapIndex := params.maskedMapIndex(m.mapIndices[ptr], layerIndex)
rowIndex := params.rowIndex(m.mapIndices[ptr], layerIndex, m.value)
groupLength := 1
for ptr+groupLength < len(m.mapIndices) && params.maskedMapIndex(m.mapIndices[ptr+groupLength], layerIndex) == maskedMapIndex {
groupLength++
}
if layerIndex == 0 {
m.stats.setState(&st, stFetchFirst)
} else {
m.stats.setState(&st, stFetchMore)
}
filterRow, err := m.backend.GetFilterMapRow(ctx, mapIndex, rowIndex, layerIndex == 0)
groupRows, err := m.backend.GetFilterMapRows(ctx, m.mapIndices[ptr:ptr+groupLength], rowIndex, layerIndex == 0)
if err != nil {
m.stats.setState(&st, stNone)
return nil, fmt.Errorf("failed to retrieve filter map %d row %d: %v", mapIndex, rowIndex, err)
return nil, fmt.Errorf("failed to retrieve filter map %d row %d: %v", m.mapIndices[ptr], rowIndex, err)
}
m.stats.setState(&st, stOther)
for i := range groupLength {
mapIndex := m.mapIndices[ptr+i]
filterRow := groupRows[i]
filterRows, ok := m.filterRows[mapIndex]
if !ok {
panic("dropped map in mapIndices")
}
if layerIndex == 0 {
matchBaseRowAccessMeter.Mark(1)
@ -394,7 +399,6 @@ func (m *singleMatcherInstance) getMatchesForLayer(ctx context.Context, layerInd
matchExtRowSizeMeter.Mark(int64(len(filterRow)))
}
m.stats.addAmount(st, int64(len(filterRow)))
m.stats.setState(&st, stOther)
filterRows = append(filterRows, filterRow)
if uint32(len(filterRow)) < params.maxRowLength(layerIndex) {
m.stats.setState(&st, stProcess)
@ -410,6 +414,8 @@ func (m *singleMatcherInstance) getMatchesForLayer(ctx context.Context, layerInd
m.filterRows[mapIndex] = filterRows
}
}
ptr += groupLength
}
m.cleanMapIndices()
m.stats.setState(&st, stNone)
return results, nil
@ -838,7 +844,7 @@ func (m *matchSequenceInstance) dropNext(mapIndex uint32) bool {
// results at mapIndex and mapIndex+1. Note that acquiring nextNextRes may be
// skipped and it can be substituted with an empty list if baseRes has no potential
// matches that could be sequence matched with anything that could be in nextNextRes.
func (params *Params) matchResults(mapIndex uint32, offset uint64, baseRes, nextRes potentialMatches) potentialMatches {
func (p *Params) matchResults(mapIndex uint32, offset uint64, baseRes, nextRes potentialMatches) potentialMatches {
if nextRes == nil || (baseRes != nil && len(baseRes) == 0) {
// if nextRes is a wild card or baseRes is empty then the sequence matcher
// result equals baseRes.
@ -848,7 +854,7 @@ func (params *Params) matchResults(mapIndex uint32, offset uint64, baseRes, next
// if baseRes is a wild card or nextRes is empty then the sequence matcher
// result is the items of nextRes with a negative offset applied.
result := make(potentialMatches, 0, len(nextRes))
min := (uint64(mapIndex) << params.logValuesPerMap) + offset
min := (uint64(mapIndex) << p.logValuesPerMap) + offset
for _, v := range nextRes {
if v >= min {
result = append(result, v-offset)

View file

@ -67,18 +67,15 @@ func (fm *FilterMapsMatcherBackend) Close() {
delete(fm.f.matchers, fm)
}
// GetFilterMapRow returns the given row of the given map. If the row is empty
// GetFilterMapRows returns the given row of the given map. If the row is empty
// then a non-nil zero length row is returned. If baseLayerOnly is true then
// only the first baseRowLength entries of the row are guaranteed to be
// returned.
// Note that the returned slices should not be modified, they should be copied
// on write.
// GetFilterMapRow implements MatcherBackend.
func (fm *FilterMapsMatcherBackend) GetFilterMapRow(ctx context.Context, mapIndex, rowIndex uint32, baseLayerOnly bool) (FilterRow, error) {
fm.f.indexLock.RLock()
defer fm.f.indexLock.RUnlock()
return fm.f.getFilterMapRow(mapIndex, rowIndex, baseLayerOnly)
// GetFilterMapRows implements MatcherBackend.
func (fm *FilterMapsMatcherBackend) GetFilterMapRows(ctx context.Context, mapIndices []uint32, rowIndex uint32, baseLayerOnly bool) ([]FilterRow, error) {
return fm.f.getFilterMapRows(mapIndices, rowIndex, baseLayerOnly)
}
// GetBlockLvPointer returns the starting log value index where the log values

View file

@ -19,6 +19,7 @@ package filtermaps
import (
"crypto/sha256"
"encoding/binary"
"fmt"
"hash/fnv"
"math"
"sort"
@ -28,19 +29,36 @@ import (
// Params defines the basic parameters of the log index structure.
type Params struct {
logMapHeight uint // log2(mapHeight)
logMapWidth uint // log2(mapWidth)
logMapsPerEpoch uint // log2(mapsPerEpoch)
logValuesPerMap uint // log2(logValuesPerMap)
baseRowLengthRatio uint // baseRowLength / average row length
logLayerDiff uint // maxRowLength log2 growth per layer
// derived fields
mapHeight uint32 // filter map height (number of rows)
mapsPerEpoch uint32 // number of maps in an epoch
logMapHeight uint // The number of bits required to represent the map height
logMapWidth uint // The number of bits required to represent the map width
logMapsPerEpoch uint // The number of bits required to represent the number of maps per epoch
logValuesPerMap uint // The number of bits required to represent the number of log values per map
// baseRowLengthRatio represents the ratio of base row length
// to the average row length.
baseRowLengthRatio uint
// logLayerDiff defines the logarithmic growth factor (base 2) of
// the maximum row length per layer. It indicates how much the maximum
// row length increases as the layer depth increases.
//
// Specifically:
// - the row length in base layer (layer == 0) is baseRowLength
// - the row length in layer x is baseRowLength << (logLayerDiff * x)
logLayerDiff uint
// These fields can be derived with the information above
mapHeight uint32 // The number of rows in the filter map
mapsPerEpoch uint32 // The number of maps in an epoch
valuesPerMap uint64 // The number of log values marked on each filter map
baseRowLength uint32 // maximum number of log values per row on layer 0
valuesPerMap uint64 // number of log values marked on each filter map
// not affecting consensus
baseRowGroupLength uint32 // length of base row groups in local database
// baseRowGroupSize defines the number of base row entries grouped together
// as a single database entry in the local database to optimize storage
// and retrieval efficiency.
//
// This value can be configured based on the specific implementation.
baseRowGroupSize uint32
}
// DefaultParams is the set of parameters used on mainnet.
@ -49,7 +67,7 @@ var DefaultParams = Params{
logMapWidth: 24,
logMapsPerEpoch: 10,
logValuesPerMap: 16,
baseRowGroupLength: 32,
baseRowGroupSize: 32,
baseRowLengthRatio: 8,
logLayerDiff: 4,
}
@ -60,7 +78,7 @@ var RangeTestParams = Params{
logMapWidth: 24,
logMapsPerEpoch: 0,
logValuesPerMap: 0,
baseRowGroupLength: 32,
baseRowGroupSize: 32,
baseRowLengthRatio: 16, // baseRowLength >= 1
logLayerDiff: 4,
}
@ -91,6 +109,44 @@ func topicValue(topic common.Hash) common.Hash {
return result
}
// sanitize derives any missing fields and validates the parameter values.
func (p *Params) sanitize() error {
p.deriveFields()
if p.logMapWidth%8 != 0 {
return fmt.Errorf("invalid configuration: logMapWidth (%d) must be a multiple of 8", p.logMapWidth)
}
if p.baseRowGroupSize == 0 || (p.baseRowGroupSize&(p.baseRowGroupSize-1)) != 0 {
return fmt.Errorf("invalid configuration: baseRowGroupSize (%d) must be a power of 2", p.baseRowGroupSize)
}
return nil
}
// mapGroupIndex returns the start index of the base row group that contains the
// given map index. Assumes baseRowGroupSize is a power of 2.
func (p *Params) mapGroupIndex(index uint32) uint32 {
return index & ^(p.baseRowGroupSize - 1)
}
// mapGroupOffset returns the offset of the given map index within its base row group.
func (p *Params) mapGroupOffset(index uint32) uint32 {
return index & (p.baseRowGroupSize - 1)
}
// mapEpoch returns the epoch number that the given map index belongs to.
func (p *Params) mapEpoch(index uint32) uint32 {
return index >> p.logMapsPerEpoch
}
// firstEpochMap returns the index of the first map in the specified epoch.
func (p *Params) firstEpochMap(epoch uint32) uint32 {
return epoch << p.logMapsPerEpoch
}
// lastEpochMap returns the index of the last map in the specified epoch.
func (p *Params) lastEpochMap(epoch uint32) uint32 {
return (epoch+1)<<p.logMapsPerEpoch - 1
}
// rowIndex returns the row index in which the given log value should be marked
// on the given map and mapping layer. Note that row assignments are re-shuffled
// with a different frequency on each mapping layer, allowing efficient disk
@ -125,17 +181,20 @@ func (p *Params) columnIndex(lvIndex uint64, logValue *common.Hash) uint32 {
return uint32(lvIndex%p.valuesPerMap)<<hashBits + (uint32(hash>>(64-hashBits)) ^ uint32(hash)>>(32-hashBits))
}
// maxRowLength returns the maximum length filter rows are populated up to
// when using the given mapping layer. A log value can be marked on the map
// according to a given mapping layer if the row mapping on that layer points
// to a row that has not yet reached the maxRowLength belonging to that layer.
// maxRowLength returns the maximum length filter rows are populated up to when
// using the given mapping layer.
//
// A log value can be marked on the map according to a given mapping layer if
// the row mapping on that layer points to a row that has not yet reached the
// maxRowLength belonging to that layer.
//
// This means that a row that is considered full on a given layer may still be
// extended further on a higher order layer.
//
// Each value is marked on the lowest order layer possible, assuming that marks
// are added in ascending log value index order.
// When searching for a log value one should consider all layers and process
// corresponding rows up until the first one where the row mapped to the given
// layer is not full.
// are added in ascending log value index order. When searching for a log value
// one should consider all layers and process corresponding rows up until the
// first one where the row mapped to the given layer is not full.
func (p *Params) maxRowLength(layerIndex uint32) uint32 {
logLayerDiff := uint(layerIndex) * p.logLayerDiff
if logLayerDiff > p.logMapsPerEpoch {

View file

@ -258,7 +258,7 @@ func (e *GenesisMismatchError) Error() string {
// ChainOverrides contains the changes to chain config.
type ChainOverrides struct {
OverridePrague *uint64
OverrideOsaka *uint64
OverrideVerkle *uint64
}
@ -267,8 +267,8 @@ func (o *ChainOverrides) apply(cfg *params.ChainConfig) error {
if o == nil || cfg == nil {
return nil
}
if o.OverridePrague != nil {
cfg.PragueTime = o.OverridePrague
if o.OverrideOsaka != nil {
cfg.OsakaTime = o.OverrideOsaka
}
if o.OverrideVerkle != nil {
cfg.VerkleTime = o.OverrideVerkle

View file

@ -28,7 +28,6 @@ import (
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/triedb"
@ -131,7 +130,7 @@ func testSetupGenesis(t *testing.T, scheme string) {
tdb := triedb.NewDatabase(db, newDbConfig(scheme))
oldcustomg.Commit(db, tdb)
bc, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(scheme), &oldcustomg, nil, ethash.NewFullFaker(), vm.Config{}, nil)
bc, _ := NewBlockChain(db, &oldcustomg, ethash.NewFullFaker(), DefaultConfig().WithStateScheme(scheme))
defer bc.Stop()
_, blocks, _ := GenerateChainWithGenesis(&oldcustomg, ethash.NewFaker(), 4, nil)
@ -257,7 +256,9 @@ func newDbConfig(scheme string) *triedb.Config {
if scheme == rawdb.HashScheme {
return triedb.HashDefaults
}
return &triedb.Config{PathDB: pathdb.Defaults}
config := *pathdb.Defaults
config.NoAsyncFlush = true
return &triedb.Config{PathDB: &config}
}
func TestVerkleGenesisCommit(t *testing.T) {
@ -314,7 +315,14 @@ func TestVerkleGenesisCommit(t *testing.T) {
}
db := rawdb.NewMemoryDatabase()
triedb := triedb.NewDatabase(db, triedb.VerkleDefaults)
config := *pathdb.Defaults
config.NoAsyncFlush = true
triedb := triedb.NewDatabase(db, &triedb.Config{
IsVerkle: true,
PathDB: &config,
})
block := genesis.MustCommit(db, triedb)
if !bytes.Equal(block.Root().Bytes(), expected) {
t.Fatalf("invalid genesis state root, expected %x, got %x", expected, block.Root())

View file

@ -449,9 +449,10 @@ func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue
return data
}
// ReadCanonicalBodyRLP retrieves the block body (transactions and uncles) for the canonical
// block at number, in RLP encoding.
func ReadCanonicalBodyRLP(db ethdb.Reader, number uint64) rlp.RawValue {
// ReadCanonicalBodyRLP retrieves the block body (transactions and uncles) for the
// canonical block at number, in RLP encoding. Optionally it takes the block hash
// to avoid looking it up
func ReadCanonicalBodyRLP(db ethdb.Reader, number uint64, hash *common.Hash) rlp.RawValue {
var data []byte
db.ReadAncients(func(reader ethdb.AncientReaderOp) error {
data, _ = reader.Ancient(ChainFreezerBodiesTable, number)
@ -459,10 +460,14 @@ func ReadCanonicalBodyRLP(db ethdb.Reader, number uint64) rlp.RawValue {
return nil
}
// Block is not in ancients, read from leveldb by hash and number.
if hash != nil {
data, _ = db.Get(blockBodyKey(number, *hash))
} else {
// Note: ReadCanonicalHash cannot be used here because it also
// calls ReadAncients internally.
hash, _ := db.Get(headerHashKey(number))
data, _ = db.Get(blockBodyKey(number, common.BytesToHash(hash)))
hashBytes, _ := db.Get(headerHashKey(number))
data, _ = db.Get(blockBodyKey(number, common.BytesToHash(hashBytes)))
}
return nil
})
return data
@ -544,9 +549,32 @@ func ReadReceiptsRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawVa
return data
}
// ReadCanonicalReceiptsRLP retrieves the receipts RLP for the canonical block at
// number, in RLP encoding. Optionally it takes the block hash to avoid looking it up.
func ReadCanonicalReceiptsRLP(db ethdb.Reader, number uint64, hash *common.Hash) rlp.RawValue {
var data []byte
db.ReadAncients(func(reader ethdb.AncientReaderOp) error {
data, _ = reader.Ancient(ChainFreezerReceiptTable, number)
if len(data) > 0 {
return nil
}
// Block is not in ancients, read from leveldb by hash and number.
if hash != nil {
data, _ = db.Get(blockReceiptsKey(number, *hash))
} else {
// Note: ReadCanonicalHash cannot be used here because it also
// calls ReadAncients internally.
hashBytes, _ := db.Get(headerHashKey(number))
data, _ = db.Get(blockReceiptsKey(number, common.BytesToHash(hashBytes)))
}
return nil
})
return data
}
// ReadRawReceipts retrieves all the transaction receipts belonging to a block.
// The receipt metadata fields are not guaranteed to be populated, so they
// should not be used. Use ReadReceipts instead if the metadata is needed.
// The receipt metadata fields and the Bloom are not guaranteed to be populated,
// so they should not be used. Use ReadReceipts instead if the metadata is needed.
func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Receipts {
// Retrieve the flattened receipt slice
data := ReadReceiptsRLP(db, hash, number)
@ -621,6 +649,14 @@ func WriteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, rec
}
}
// WriteRawReceipts stores all the transaction receipts belonging to a block.
func WriteRawReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, receipts rlp.RawValue) {
// Store the flattened receipt slice
if err := db.Put(blockReceiptsKey(number, hash), receipts); err != nil {
log.Crit("Failed to store block receipts", "err", err)
}
}
// DeleteReceipts removes all receipt data associated with a block hash.
func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
if err := db.Delete(blockReceiptsKey(number, hash)); err != nil {
@ -701,18 +737,11 @@ func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) {
}
// WriteAncientBlocks writes entire block data into ancient store and returns the total written size.
func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts []types.Receipts) (int64, error) {
var stReceipts []*types.ReceiptForStorage
func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts []rlp.RawValue) (int64, error) {
return db.ModifyAncients(func(op ethdb.AncientWriteOp) error {
for i, block := range blocks {
// Convert receipts to storage format and sum up total difficulty.
stReceipts = stReceipts[:0]
for _, receipt := range receipts[i] {
stReceipts = append(stReceipts, (*types.ReceiptForStorage)(receipt))
}
header := block.Header()
if err := writeAncientBlock(op, block, header, stReceipts); err != nil {
if err := writeAncientBlock(op, block, header, receipts[i]); err != nil {
return err
}
}
@ -720,7 +749,7 @@ func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts
})
}
func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *types.Header, receipts []*types.ReceiptForStorage) error {
func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *types.Header, receipts rlp.RawValue) error {
num := block.NumberU64()
if err := op.AppendRaw(ChainFreezerHashTable, num, block.Hash().Bytes()); err != nil {
return fmt.Errorf("can't add block %d hash: %v", num, err)

Some files were not shown because too many files have changed in this diff Show more