Compare commits

..

31 Commits

Author SHA1 Message Date
Péter Szilágyi
73b01f40ce params: release Geth v1.11.2 2023-02-22 14:23:51 +02:00
Péter Szilágyi
f86f048646 common/math: allow HexOrDecimal to accept unquoted decimals too (#26758) 2023-02-22 13:55:09 +02:00
Yier
4034c675be eth/filters: fix a breaking change and return rpctransaction (#26757)
* eth/filters: fix a breaking change and return rpctransaction

* eth/filters: fix test cases

---------

Co-authored-by: Catror <me@catror.com>
2023-02-22 13:06:43 +02:00
rjl493456442
fe01a2f63b all: use unified emptyRootHash and emptyCodeHash (#26718)
The EmptyRootHash and EmptyCodeHash are defined everywhere in the codebase, this PR replaces all of them with unified one defined in core/types package, and also defines constants for TxRoot, WithdrawalsRoot and UncleRoot
2023-02-21 06:12:27 -05:00
Péter Szilágyi
2f20fd31ee core/rawdb: expose chain freezer constructor without internals (#26748) 2023-02-21 13:10:01 +02:00
Martin Holst Swende
6d2d126100 core: fix accessor mismatch for genesis state (#26747) 2023-02-21 12:18:33 +02:00
Péter Szilágyi
90d25514af core, eth: merge snap-sync chain download progress logs (#26676) 2023-02-21 12:17:34 +02:00
Sungwoo Kim
7d4db69607 cmd/geth: clarify dumpconfig options (#26729)
Clarifies the documentation around dumpconfi

Signed-off-by: Sungwoo Kim <git@sung-woo.kim>
2023-02-21 02:35:04 -05:00
rjl493456442
13ef21d467 Revert "core/trie: remove trie tracer (#26665)" (#26732)
This reverts commit 7c749c947a.
2023-02-20 09:54:52 -05:00
Péter Szilágyi
ba4267fcac build: enable Lunar Lobster PPA builds 2023-02-20 13:26:37 +02:00
Péter Szilágyi
41dee2623e build: fix Go 1.19.0 bootstrapper issues on 386 PPA 2023-02-20 12:36:46 +02:00
Péter Szilágyi
4519054816 build: fix (finaly?) the PPA env vars for Go bootstrapping 2023-02-20 11:31:19 +02:00
Péter Szilágyi
c02334be1e build: yet another weird PPA fix 2023-02-20 11:07:33 +02:00
Péter Szilágyi
165268430c internal/build: revert raising the chunk size for PPA 2023-02-20 10:43:55 +02:00
Péter Szilágyi
a43efceaf2 build: add some PPA debug logs, sigh 2023-02-20 10:31:35 +02:00
Péter Szilágyi
4ec4235fc4 build: fix gobootstrap path for the PPA 2023-02-20 10:09:00 +02:00
Péter Szilágyi
e1e2781105 build: fix setting env var, temp early exit 2023-02-20 09:57:37 +02:00
Péter Szilágyi
2166c86041 build: ship bootstrapper Go along with builder for PPA (#26731) 2023-02-20 08:53:15 +02:00
Felix Lange
1db978ca6b rpc: fix unmarshaling of null result in CallContext (#26723)
The change fixes unmarshaling of JSON null results into json.RawMessage.

---------

Co-authored-by: Jason Yuan <jason.yuan@curvegrid.com>
Co-authored-by: Jason Yuan <jason.yuan869@gmail.com>
2023-02-19 14:23:18 -05:00
Martin Holst Swende
7c749c947a core/trie: remove trie tracer (#26665)
This PR contains a small portion of the full pbss PR, namely

    Remove the tracer from trie (and comitter), and instead using an accessList.
    Related changes to the Nodeset.


---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2023-02-19 14:10:19 -05:00
Roman Krasiuk
15e5e6176b eth/catalyst: request too large error (#26722)
The method `GetPayloadBodiesByRangeV1` now returns "-38004: Too large request" error if the requested range is too large, according to spec

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-02-17 13:30:38 -05:00
Marius van der Wijden
6428663faf eth/catalyst: send INVALID instead of INVALID_BLOCK_HASH (#26696)
This change will break one hive test, but pass another and it will be the better way going forward
2023-02-17 05:25:09 -05:00
Martin Holst Swende
b40c10916c params: begin v1.11.2 release cycle 2023-02-16 20:53:16 +01:00
Martin Holst Swende
769610667d params: go-ethereum v1.11.1 stable 2023-02-16 20:51:51 +01:00
Martin Holst Swende
4d3525610e all: remove deprecated uses of math.rand (#26710)
This PR is a (superior) alternative to https://github.com/ethereum/go-ethereum/pull/26708, it handles deprecation, primarily two specific cases. 

`rand.Seed` is typically used in two ways
- `rand.Seed(time.Now().UnixNano())` -- we seed it, just to be sure to get some random, and not always get the same thing on every run. This is not needed, with global seeding, so those are just removed. 
- `rand.Seed(1)` this is typically done to ensure we have a stable test. If we rely on this, we need to fix up the tests to use a deterministic prng-source. A few occurrences like this has been replaced with a proper custom source. 

`rand.Read` has been replaced by `crypto/rand`.`Read` in this PR.
2023-02-16 14:36:58 -05:00
ucwong
e9d42499bb eth/downloader: fix typo (#26716) 2023-02-16 19:40:16 +02:00
Martin Holst Swende
13d7de77f4 eth/downloader: fix empty-body case in queue fetchresult (#26707) 2023-02-16 12:28:01 +02:00
Martin Holst Swende
645e3e86c4 core, eth/downloader: make body validation more strict (#26704) 2023-02-16 12:10:16 +02:00
rjl493456442
08bf8a60c3 core: check genesis state presence by disk read (#26703) 2023-02-16 12:09:41 +02:00
Péter Szilágyi
5ccc99b258 travis, build: update Go to 1.20.1 (#26653)
travis, build: update Go to 1.20
2023-02-16 09:00:45 +02:00
Martin Holst Swende
194b5c9152 params: begin v1.11.1 release cycle 2023-02-15 19:15:31 +01:00
93 changed files with 672 additions and 421 deletions

View File

@@ -8,15 +8,13 @@ jobs:
go: 1.17.x
env:
- azure-osx
- azure-ios
- cocoapods-ios
include:
# This builder only tests code linters on latest version of Go
- stage: lint
os: linux
dist: bionic
go: 1.19.x
go: 1.20.x
env:
- lint
git:
@@ -31,7 +29,7 @@ jobs:
os: linux
arch: amd64
dist: bionic
go: 1.19.x
go: 1.20.x
env:
- docker
services:
@@ -48,7 +46,7 @@ jobs:
os: linux
arch: arm64
dist: bionic
go: 1.19.x
go: 1.20.x
env:
- docker
services:
@@ -65,7 +63,7 @@ jobs:
if: type = push
os: linux
dist: bionic
go: 1.19.x
go: 1.20.x
env:
- ubuntu-ppa
- GO111MODULE=on
@@ -90,7 +88,7 @@ jobs:
os: linux
dist: bionic
sudo: required
go: 1.19.x
go: 1.20.x
env:
- azure-linux
- GO111MODULE=on
@@ -120,12 +118,26 @@ jobs:
- 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
# This builder does the OSX Azure uploads
- stage: build
if: type = push
os: osx
go: 1.20.x
env:
- azure-osx
- GO111MODULE=on
git:
submodules: false # avoid cloning ethereum/tests
script:
- go run build/ci.go install -dlgo
- go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
# These builders run the tests
- stage: build
os: linux
arch: amd64
dist: bionic
go: 1.19.x
go: 1.20.x
env:
- GO111MODULE=on
script:
@@ -136,7 +148,7 @@ jobs:
os: linux
arch: arm64
dist: bionic
go: 1.18.x
go: 1.19.x
env:
- GO111MODULE=on
script:
@@ -145,7 +157,7 @@ jobs:
- stage: build
os: linux
dist: bionic
go: 1.18.x
go: 1.19.x
env:
- GO111MODULE=on
script:
@@ -156,7 +168,7 @@ jobs:
if: type = cron
os: linux
dist: bionic
go: 1.19.x
go: 1.20.x
env:
- azure-purge
- GO111MODULE=on
@@ -170,7 +182,7 @@ jobs:
if: type = cron
os: linux
dist: bionic
go: 1.19.x
go: 1.20.x
env:
- GO111MODULE=on
script:

View File

@@ -4,7 +4,7 @@ ARG VERSION=""
ARG BUILDNUM=""
# Build Geth in a stock Go builder container
FROM golang:1.19-alpine as builder
FROM golang:1.20-alpine as builder
RUN apk add --no-cache gcc musl-dev linux-headers git

View File

@@ -4,7 +4,7 @@ ARG VERSION=""
ARG BUILDNUM=""
# Build Geth in a stock Go builder container
FROM golang:1.19-alpine as builder
FROM golang:1.20-alpine as builder
RUN apk add --no-cache gcc musl-dev linux-headers git

View File

@@ -113,7 +113,6 @@ func TestWatchNewFile(t *testing.T) {
func TestWatchNoDir(t *testing.T) {
t.Parallel()
// Create ks but not the directory that it watches.
rand.Seed(time.Now().UnixNano())
dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-watchnodir-test-%d-%d", os.Getpid(), rand.Int()))
ks := NewKeyStore(dir, LightScryptN, LightScryptP)
list := ks.Accounts()
@@ -322,7 +321,6 @@ func TestUpdatedKeyfileContents(t *testing.T) {
t.Parallel()
// Create a temporary keystore to test with
rand.Seed(time.Now().UnixNano())
dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-updatedkeyfilecontents-test-%d-%d", os.Getpid(), rand.Int()))
ks := NewKeyStore(dir, LightScryptN, LightScryptP)

View File

@@ -74,12 +74,11 @@ var (
// - newPayloadV1: if the payload was accepted, but not processed (side chain)
ACCEPTED = "ACCEPTED"
INVALIDBLOCKHASH = "INVALID_BLOCK_HASH"
GenericServerError = &EngineAPIError{code: -32000, msg: "Server error"}
UnknownPayload = &EngineAPIError{code: -38001, msg: "Unknown payload"}
InvalidForkChoiceState = &EngineAPIError{code: -38002, msg: "Invalid forkchoice state"}
InvalidPayloadAttributes = &EngineAPIError{code: -38003, msg: "Invalid payload attributes"}
TooLargeRequest = &EngineAPIError{code: -38004, msg: "Too large request"}
InvalidParams = &EngineAPIError{code: -32602, msg: "Invalid parameters"}
STATUS_INVALID = ForkChoiceResponse{PayloadStatus: PayloadStatusV1{Status: INVALID}, PayloadID: nil}

View File

@@ -1,19 +1,19 @@
# This file contains sha256 checksums of optional build dependencies.
8e486e8e85a281fc5ce3f0bedc5b9d2dbf6276d7db0b25d3ec034f313da0375f go1.19.5.src.tar.gz
23d22bb6571bbd60197bee8aaa10e702f9802786c2e2ddce5c84527e86b66aa0 go1.19.5.darwin-amd64.tar.gz
4a67f2bf0601afe2177eb58f825adf83509511d77ab79174db0712dc9efa16c8 go1.19.5.darwin-arm64.tar.gz
b18a5e1e60130003896e1d1c8a9e142c7cccf6f5063d52c55dd42006434419c1 go1.19.5.freebsd-386.tar.gz
317996f7427691ff3a7ffd1b6aa089b9c66cd76f32e9107443f2f6aad1bb568a go1.19.5.freebsd-amd64.tar.gz
f68331aa7458a3598060595f5601d5731fd452bb2c62ff23095ddad68854e510 go1.19.5.linux-386.tar.gz
36519702ae2fd573c9869461990ae550c8c0d955cd28d2827a6b159fda81ff95 go1.19.5.linux-amd64.tar.gz
fc0aa29c933cec8d76f5435d859aaf42249aa08c74eb2d154689ae44c08d23b3 go1.19.5.linux-arm64.tar.gz
ec14f04bdaf4a62bdcf8b55b9b6434cc27c2df7d214d0bb7076a7597283b026a go1.19.5.linux-armv6l.tar.gz
e4032e7c52ebc48bad5c58ba8de0759b6091d9b1e59581a8a521c8c9d88dbe93 go1.19.5.linux-ppc64le.tar.gz
764871cbca841a99a24e239b63c68a4aaff4104658e3165e9ca450cac1fcbea3 go1.19.5.linux-s390x.tar.gz
8873f5871d996106b701febd979c5af022e6ea58bdbbb3817a28ab948b22c286 go1.19.5.windows-386.zip
167db91a2e40aeb453d3e59d213ecab06f62e1c4a84d13a06ccda1d999961caa go1.19.5.windows-amd64.zip
85a75555e82d8aa6f486d8d29491c593389682acce9f0c270090d5938eee30ef go1.19.5.windows-arm64.zip
b5c1a3af52c385a6d1c76aed5361cf26459023980d0320de7658bae3915831a2 go1.20.1.src.tar.gz
a300a45e801ab459f3008aae5bb9efbe9a6de9bcd12388f5ca9bbd14f70236de go1.20.1.darwin-amd64.tar.gz
f1a8e06c7f1ba1c008313577f3f58132eb166a41ceb95ce6e9af30bc5a3efca4 go1.20.1.darwin-arm64.tar.gz
57d80349dc4fbf692f8cd85a5971f97841aedafcf211e367e59d3ae812292660 go1.20.1.freebsd-386.tar.gz
6e124d54d5850a15fdb15754f782986f06af23c5ddb6690849417b9c74f05f98 go1.20.1.freebsd-amd64.tar.gz
3a7345036ebd92455b653e4b4f6aaf4f7e1f91f4ced33b23d7059159cec5f4d7 go1.20.1.linux-386.tar.gz
000a5b1fca4f75895f78befeb2eecf10bfff3c428597f3f1e69133b63b911b02 go1.20.1.linux-amd64.tar.gz
5e5e2926733595e6f3c5b5ad1089afac11c1490351855e87849d0e7702b1ec2e go1.20.1.linux-arm64.tar.gz
e4edc05558ab3657ba3dddb909209463cee38df9c1996893dd08cde274915003 go1.20.1.linux-armv6l.tar.gz
85cfd4b89b48c94030783b6e9e619e35557862358b846064636361421d0b0c52 go1.20.1.linux-ppc64le.tar.gz
ba3a14381ed4538216dec3ea72b35731750597edd851cece1eb120edf7d60149 go1.20.1.linux-s390x.tar.gz
61259b5a346193e30b7b3c3f8d108062db25bbb80cf290ee251eeb855965f6ee go1.20.1.windows-386.zip
3b493969196a6de8d9762d09f5bc5ae7a3e5814b0cfbf9cc26838c2bc1314f9c go1.20.1.windows-amd64.zip
62d14ddb44bcda27c9b1f5ad9ffd4463013374ed325d762417e2adefd59a802f go1.20.1.windows-arm64.zip
fba08acc4027f69f07cef48fbff70b8a7ecdfaa1c2aba9ad3fb31d60d9f5d4bc golangci-lint-1.51.1-darwin-amd64.tar.gz
75b8f0ff3a4e68147156be4161a49d4576f1be37a0b506473f8c482140c1e7f2 golangci-lint-1.51.1-darwin-arm64.tar.gz
@@ -41,3 +41,6 @@ c4f58b7e227b9fd41f0e9310dc83f4a4e7d026598e2f6e95b78761081a6d9bd2 golangci-lint-
eb57f9bcb56646f2e3d6ccaf02ec227815fb05077b2e0b1bf9e755805acdc2b9 golangci-lint-1.51.1-windows-arm64.zip
bce02f7232723cb727755ee11f168a700a00896a25d37f87c4b173bce55596b4 golangci-lint-1.51.1-windows-armv6.zip
cf6403f84707ce8c98664736772271bc8874f2e760c2fd0f00cf3e85963507e9 golangci-lint-1.51.1-windows-armv7.zip
# This is the builder on PPA that will build Go itself (inception-y), don't modify!
d7f0013f82e6d7f862cc6cb5c8cdb48eef5f2e239b35baa97e2f1a7466043767 go1.19.6.src.tar.gz

View File

@@ -128,7 +128,7 @@ var (
"focal": "golang-go", // EOL: 04/2030
"jammy": "golang-go", // EOL: 04/2032
"kinetic": "golang-go", // EOL: 07/2023
//"lunar": "golang-go", // EOL: 01/2024
"lunar": "golang-go", // EOL: 01/2024
}
debGoBootPaths = map[string]string{
@@ -136,10 +136,18 @@ var (
"golang-go": "/usr/lib/go",
}
// This is the version of go that will be downloaded by
// This is the version of Go that will be downloaded by
//
// go run ci.go install -dlgo
dlgoVersion = "1.19.5"
dlgoVersion = "1.20.1"
// This is the version of Go that will be used to bootstrap the PPA builder.
//
// This version is fine to be old and full of security holes, we just use it
// to build the latest Go. Don't change it. If it ever becomes insufficient,
// we need to switch over to a recursive builder to jumpt across supported
// versions.
gobootVersion = "1.19.6"
)
var GOBIN, _ = filepath.Abs(filepath.Join("build", "bin"))
@@ -655,10 +663,11 @@ func doDebianSource(cmdline []string) {
gpg.Stdin = bytes.NewReader(key)
build.MustRun(gpg)
}
// Download and verify the Go source package.
gobundle := downloadGoSources(*cachedir)
// Download and verify the Go source packages.
var (
gobootbundle = downloadGoBootstrapSources(*cachedir)
gobundle = downloadGoSources(*cachedir)
)
// Download all the dependencies needed to build the sources and run the ci script
srcdepfetch := tc.Go("mod", "download")
srcdepfetch.Env = append(srcdepfetch.Env, "GOPATH="+filepath.Join(*workdir, "modgopath"))
@@ -675,12 +684,19 @@ func doDebianSource(cmdline []string) {
meta := newDebMetadata(distro, goboot, *signer, env, now, pkg.Name, pkg.Version, pkg.Executables)
pkgdir := stageDebianSource(*workdir, meta)
// Add Go source code
// Add bootstrapper Go source code
if err := build.ExtractArchive(gobootbundle, pkgdir); err != nil {
log.Fatalf("Failed to extract bootstrapper Go sources: %v", err)
}
if err := os.Rename(filepath.Join(pkgdir, "go"), filepath.Join(pkgdir, ".goboot")); err != nil {
log.Fatalf("Failed to rename bootstrapper Go source folder: %v", err)
}
// Add builder Go source code
if err := build.ExtractArchive(gobundle, pkgdir); err != nil {
log.Fatalf("Failed to extract Go sources: %v", err)
log.Fatalf("Failed to extract builder Go sources: %v", err)
}
if err := os.Rename(filepath.Join(pkgdir, "go"), filepath.Join(pkgdir, ".go")); err != nil {
log.Fatalf("Failed to rename Go source folder: %v", err)
log.Fatalf("Failed to rename builder Go source folder: %v", err)
}
// Add all dependency modules in compressed form
os.MkdirAll(filepath.Join(pkgdir, ".mod", "cache"), 0755)
@@ -709,6 +725,19 @@ func doDebianSource(cmdline []string) {
}
}
// downloadGoBootstrapSources downloads the Go source tarball that will be used
// to bootstrap the builder Go.
func downloadGoBootstrapSources(cachedir string) string {
csdb := build.MustLoadChecksums("build/checksums.txt")
file := fmt.Sprintf("go%s.src.tar.gz", gobootVersion)
url := "https://dl.google.com/go/" + file
dst := filepath.Join(cachedir, file)
if err := csdb.DownloadFile(url, dst); err != nil {
log.Fatal(err)
}
return dst
}
// downloadGoSources downloads the Go source tarball.
func downloadGoSources(cachedir string) string {
csdb := build.MustLoadChecksums("build/checksums.txt")

View File

@@ -16,7 +16,11 @@ override_dh_auto_build:
# We can't download a fresh Go within Launchpad, so we're shipping and building
# one on the fly. However, we can't build it inside the go-ethereum folder as
# bootstrapping clashes with go modules, so build in a sibling folder.
(mv .go ../ && cd ../.go/src && ./make.bash)
#
# We're also shipping the bootstrapper as of Go 1.20 as it had minimum version
# requirements opposed to older versions of Go.
(mv .goboot ../ && cd ../.goboot/src && ./make.bash)
(mv .go ../ && cd ../.go/src && GOROOT_BOOTSTRAP=`pwd`/../../.goboot ./make.bash)
# We can't download external go modules within Launchpad, so we're shipping the
# entire dependency source cache with go-ethereum.

View File

@@ -23,6 +23,7 @@ import (
"math/rand"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/protocols/snap"
"github.com/ethereum/go-ethereum/internal/utesting"
@@ -210,13 +211,6 @@ type byteCodesTest struct {
expHashes int
}
var (
// emptyRoot is the known root hash of an empty trie.
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
// emptyCode is the known hash of the empty EVM bytecode.
emptyCode = common.HexToHash("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
)
// TestSnapGetByteCodes various forms of GetByteCodes requests.
func (s *Suite) TestSnapGetByteCodes(t *utesting.T) {
// The halfchain import should yield these bytecodes
@@ -263,15 +257,15 @@ func (s *Suite) TestSnapGetByteCodes(t *utesting.T) {
},
// Empties
{
nBytes: 10000, hashes: []common.Hash{emptyRoot},
nBytes: 10000, hashes: []common.Hash{types.EmptyRootHash},
expHashes: 0,
},
{
nBytes: 10000, hashes: []common.Hash{emptyCode},
nBytes: 10000, hashes: []common.Hash{types.EmptyCodeHash},
expHashes: 1,
},
{
nBytes: 10000, hashes: []common.Hash{emptyCode, emptyCode, emptyCode},
nBytes: 10000, hashes: []common.Hash{types.EmptyCodeHash, types.EmptyCodeHash, types.EmptyCodeHash},
expHashes: 3,
},
// The existing bytecodes
@@ -363,7 +357,7 @@ func (s *Suite) TestSnapTrieNodes(t *utesting.T) {
for i := 1; i <= 65; i++ {
accPaths = append(accPaths, pathTo(i))
}
empty := emptyCode
empty := types.EmptyCodeHash
for i, tc := range []trieNodesTest{
{
root: s.chain.RootAt(999),

View File

@@ -120,8 +120,8 @@ func (i *bbInput) ToBlock() *types.Block {
UncleHash: types.EmptyUncleHash,
Coinbase: common.Address{},
Root: i.Header.Root,
TxHash: types.EmptyRootHash,
ReceiptHash: types.EmptyRootHash,
TxHash: types.EmptyTxsHash,
ReceiptHash: types.EmptyReceiptsHash,
Bloom: i.Header.Bloom,
Difficulty: common.Big0,
Number: i.Header.Number,

View File

@@ -47,10 +47,10 @@ var (
dumpConfigCommand = &cli.Command{
Action: dumpConfig,
Name: "dumpconfig",
Usage: "Show configuration values",
ArgsUsage: "",
Usage: "Export configuration values in a TOML format",
ArgsUsage: "<dumpfile (optional)>",
Flags: flags.Merge(nodeFlags, rpcFlags),
Description: `The dumpconfig command shows configuration values.`,
Description: `Export configuration values in TOML format (to stdout by default).`,
}
configFileFlag = &cli.StringFlag{

View File

@@ -38,14 +38,6 @@ import (
cli "github.com/urfave/cli/v2"
)
var (
// emptyRoot is the known root hash of an empty trie.
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
// emptyCode is the known hash of the empty EVM bytecode.
emptyCode = crypto.Keccak256(nil)
)
var (
snapshotCommand = &cli.Command{
Name: "snapshot",
@@ -308,7 +300,7 @@ func traverseState(ctx *cli.Context) error {
log.Error("Invalid account encountered during traversal", "err", err)
return err
}
if acc.Root != emptyRoot {
if acc.Root != types.EmptyRootHash {
id := trie.StorageTrieID(root, common.BytesToHash(accIter.Key), acc.Root)
storageTrie, err := trie.NewStateTrie(id, triedb)
if err != nil {
@@ -324,7 +316,7 @@ func traverseState(ctx *cli.Context) error {
return storageIter.Err
}
}
if !bytes.Equal(acc.CodeHash, emptyCode) {
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) {
if !rawdb.HasCode(chaindb, common.BytesToHash(acc.CodeHash)) {
log.Error("Code is missing", "hash", common.BytesToHash(acc.CodeHash))
return errors.New("missing code")
@@ -423,7 +415,7 @@ func traverseRawState(ctx *cli.Context) error {
log.Error("Invalid account encountered during traversal", "err", err)
return errors.New("invalid account")
}
if acc.Root != emptyRoot {
if acc.Root != types.EmptyRootHash {
id := trie.StorageTrieID(root, common.BytesToHash(accIter.LeafKey()), acc.Root)
storageTrie, err := trie.NewStateTrie(id, triedb)
if err != nil {
@@ -461,7 +453,7 @@ func traverseRawState(ctx *cli.Context) error {
return storageIter.Error()
}
}
if !bytes.Equal(acc.CodeHash, emptyCode) {
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) {
if !rawdb.HasCode(chaindb, common.BytesToHash(acc.CodeHash)) {
log.Error("Code is missing", "account", common.BytesToHash(accIter.LeafKey()))
return errors.New("missing code")
@@ -536,7 +528,7 @@ func dumpState(ctx *cli.Context) error {
CodeHash: account.CodeHash,
SecureKey: accIt.Hash().Bytes(),
}
if !conf.SkipCode && !bytes.Equal(account.CodeHash, emptyCode) {
if !conf.SkipCode && !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) {
da.Code = rawdb.ReadCode(db, common.BytesToHash(account.CodeHash))
}
if !conf.SkipStorage {

View File

@@ -17,6 +17,7 @@
package lru
import (
crand "crypto/rand"
"fmt"
"io"
"math/rand"
@@ -181,9 +182,9 @@ func BenchmarkLRU(b *testing.B) {
}
for i := range keys {
b := make([]byte, 32)
rand.Read(b)
crand.Read(b)
keys[i] = string(b)
rand.Read(b)
crand.Read(b)
values[i] = b
}

View File

@@ -49,6 +49,17 @@ func NewHexOrDecimal256(x int64) *HexOrDecimal256 {
return &h
}
// UnmarshalJSON implements json.Unmarshaler.
//
// It is similar to UnmarshalText, but allows parsing real decimals too, not just
// quoted decimal strings.
func (i *HexOrDecimal256) UnmarshalJSON(input []byte) error {
if len(input) > 0 && input[0] == '"' {
input = input[1 : len(input)-1]
}
return i.UnmarshalText(input)
}
// UnmarshalText implements encoding.TextUnmarshaler.
func (i *HexOrDecimal256) UnmarshalText(input []byte) error {
bigint, ok := ParseBig256(string(input))

View File

@@ -41,6 +41,17 @@ const (
// HexOrDecimal64 marshals uint64 as hex or decimal.
type HexOrDecimal64 uint64
// UnmarshalJSON implements json.Unmarshaler.
//
// It is similar to UnmarshalText, but allows parsing real decimals too, not just
// quoted decimal strings.
func (i *HexOrDecimal64) UnmarshalJSON(input []byte) error {
if len(input) > 0 && input[0] == '"' {
input = input[1 : len(input)-1]
}
return i.UnmarshalText(input)
}
// UnmarshalText implements encoding.TextUnmarshaler.
func (i *HexOrDecimal64) UnmarshalText(input []byte) error {
int, ok := ParseUint64(string(input))

View File

@@ -56,7 +56,6 @@ func testSetIndex(a interface{}, i int) {
}
func TestLazyQueue(t *testing.T) {
rand.Seed(time.Now().UnixNano())
clock := &mclock.Simulated{}
q := NewLazyQueue(testSetIndex, testPriority, testMaxPriority, clock, testQueueRefresh)

View File

@@ -709,11 +709,11 @@ func TestConcurrentDiskCacheGeneration(t *testing.T) {
block := types.NewBlockWithHeader(&types.Header{
Number: big.NewInt(3311058),
ParentHash: common.HexToHash("0xd783efa4d392943503f28438ad5830b2d5964696ffc285f338585e9fe0a37a05"),
UncleHash: common.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"),
UncleHash: types.EmptyUncleHash,
Coinbase: common.HexToAddress("0xc0ea08a2d404d3172d2add29a45be56da40e2949"),
Root: common.HexToHash("0x77d14e10470b5850332524f8cd6f69ad21f070ce92dca33ab2858300242ef2f1"),
TxHash: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
ReceiptHash: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
TxHash: types.EmptyTxsHash,
ReceiptHash: types.EmptyReceiptsHash,
Difficulty: big.NewInt(167925187834220),
GasLimit: 4015682,
GasUsed: 0,

View File

@@ -17,6 +17,7 @@
package ethash
import (
crand "crypto/rand"
"encoding/binary"
"encoding/json"
"math/big"
@@ -90,16 +91,15 @@ func TestCalcDifficulty(t *testing.T) {
func randSlice(min, max uint32) []byte {
var b = make([]byte, 4)
rand.Read(b)
crand.Read(b)
a := binary.LittleEndian.Uint32(b)
size := min + a%(max-min)
out := make([]byte, size)
rand.Read(out)
crand.Read(out)
return out
}
func TestDifficultyCalculators(t *testing.T) {
rand.Seed(2)
for i := 0; i < 5000; i++ {
// 1 to 300 seconds diff
var timeDelta = uint64(1 + rand.Uint32()%3000)

View File

@@ -252,8 +252,8 @@ func makeChainForBench(db ethdb.Database, full bool, count uint64) {
ParentHash: hash,
Difficulty: big.NewInt(1),
UncleHash: types.EmptyUncleHash,
TxHash: types.EmptyRootHash,
ReceiptHash: types.EmptyRootHash,
TxHash: types.EmptyTxsHash,
ReceiptHash: types.EmptyReceiptsHash,
}
hash = header.Hash()

View File

@@ -76,6 +76,9 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
if hash := types.DeriveSha(block.Withdrawals(), trie.NewStackTrie(nil)); hash != *header.WithdrawalsHash {
return fmt.Errorf("withdrawals root hash mismatch (header value %x, calculated %x)", *header.WithdrawalsHash, hash)
}
} else if block.Withdrawals() != nil {
// Withdrawals are not allowed prior to shanghai fork
return fmt.Errorf("withdrawals present in block body")
}
if !v.bc.HasBlockAndState(block.ParentHash(), block.NumberU64()-1) {

View File

@@ -1278,7 +1278,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
if stats.ignored > 0 {
context = append(context, []interface{}{"ignored", stats.ignored}...)
}
log.Info("Imported new block receipts", context...)
log.Debug("Imported new block receipts", context...)
return 0, nil
}

View File

@@ -18,6 +18,7 @@ package bloombits
import (
"bytes"
crand "crypto/rand"
"math/rand"
"testing"
@@ -78,7 +79,7 @@ func BenchmarkGenerator(b *testing.B) {
}
})
for i := 0; i < types.BloomBitLength; i++ {
rand.Read(input[i][:])
crand.Read(input[i][:])
}
b.Run("random", func(b *testing.B) {
b.ReportAllocs()

View File

@@ -138,7 +138,7 @@ func (ga *GenesisAlloc) deriveHash() (common.Hash, error) {
// flush is very similar with deriveHash, but the main difference is
// all the generated states will be persisted into the given database.
// Also, the genesis state specification will be flushed as well.
func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database) error {
func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database, blockhash common.Hash) error {
statedb, err := state.New(common.Hash{}, state.NewDatabaseWithNodeDB(db, triedb), nil)
if err != nil {
return err
@@ -166,15 +166,15 @@ func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database) error {
if err != nil {
return err
}
rawdb.WriteGenesisStateSpec(db, root, blob)
rawdb.WriteGenesisStateSpec(db, blockhash, blob)
return nil
}
// CommitGenesisState loads the stored genesis state with the given block
// hash and commits it into the provided trie database.
func CommitGenesisState(db ethdb.Database, triedb *trie.Database, hash common.Hash) error {
func CommitGenesisState(db ethdb.Database, triedb *trie.Database, blockhash common.Hash) error {
var alloc GenesisAlloc
blob := rawdb.ReadGenesisStateSpec(db, hash)
blob := rawdb.ReadGenesisStateSpec(db, blockhash)
if len(blob) != 0 {
if err := alloc.UnmarshalJSON(blob); err != nil {
return err
@@ -186,7 +186,7 @@ func CommitGenesisState(db ethdb.Database, triedb *trie.Database, hash common.Ha
// - supported networks(mainnet, testnets), recover with defined allocations
// - private network, can't recover
var genesis *Genesis
switch hash {
switch blockhash {
case params.MainnetGenesisHash:
genesis = DefaultGenesisBlock()
case params.RinkebyGenesisHash:
@@ -202,7 +202,7 @@ func CommitGenesisState(db ethdb.Database, triedb *trie.Database, hash common.Ha
return errors.New("not found")
}
}
return alloc.flush(db, triedb)
return alloc.flush(db, triedb, blockhash)
}
// GenesisAccount is an account in the state of the genesis block.
@@ -317,7 +317,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *trie.Database, gen
// We have the genesis block in database(perhaps in ancient database)
// but the corresponding state is missing.
header := rawdb.ReadHeader(db, stored, 0)
if _, err := state.New(header.Root, state.NewDatabaseWithNodeDB(db, triedb), nil); err != nil {
if header.Root != types.EmptyRootHash && !rawdb.HasLegacyTrieNode(db, header.Root) {
if genesis == nil {
genesis = DefaultGenesisBlock()
}
@@ -467,7 +467,7 @@ func (g *Genesis) ToBlock() *types.Block {
}
var withdrawals []*types.Withdrawal
if g.Config != nil && g.Config.IsShanghai(g.Timestamp) {
head.WithdrawalsHash = &types.EmptyRootHash
head.WithdrawalsHash = &types.EmptyWithdrawalsHash
withdrawals = make([]*types.Withdrawal, 0)
}
return types.NewBlock(head, nil, nil, nil, trie.NewStackTrie(nil)).WithWithdrawals(withdrawals)
@@ -493,7 +493,7 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *trie.Database) (*types.Block
// All the checks has passed, flush the states derived from the genesis
// specification as well as the specification itself into the provided
// database.
if err := g.Alloc.flush(db, triedb); err != nil {
if err := g.Alloc.flush(db, triedb, block.Hash()); err != nil {
return nil, err
}
rawdb.WriteTd(db, block.Hash(), block.NumberU64(), block.Difficulty())

View File

@@ -389,7 +389,7 @@ func (hc *HeaderChain) InsertHeaderChain(chain []*types.Header, start time.Time,
if res.ignored > 0 {
context = append(context, []interface{}{"ignored", res.ignored}...)
}
log.Info("Imported new block headers", context...)
log.Debug("Imported new block headers", context...)
return res.status, err
}

View File

@@ -37,7 +37,7 @@ import (
func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash {
var data []byte
db.ReadAncients(func(reader ethdb.AncientReaderOp) error {
data, _ = reader.Ancient(chainFreezerHashTable, number)
data, _ = reader.Ancient(ChainFreezerHashTable, number)
if len(data) == 0 {
// Get it by hash from leveldb
data, _ = db.Get(headerHashKey(number))
@@ -334,7 +334,7 @@ func ReadHeaderRange(db ethdb.Reader, number uint64, count uint64) []rlp.RawValu
}
// read remaining from ancients
max := count * 700
data, err := db.AncientRange(chainFreezerHeaderTable, i+1-count, count, max)
data, err := db.AncientRange(ChainFreezerHeaderTable, i+1-count, count, max)
if err == nil && uint64(len(data)) == count {
// the data is on the order [h, h+1, .., n] -- reordering needed
for i := range data {
@@ -351,7 +351,7 @@ func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValu
// First try to look up the data in ancient database. Extra hash
// comparison is necessary since ancient database only maintains
// the canonical data.
data, _ = reader.Ancient(chainFreezerHeaderTable, number)
data, _ = reader.Ancient(ChainFreezerHeaderTable, number)
if len(data) > 0 && crypto.Keccak256Hash(data) == hash {
return nil
}
@@ -427,7 +427,7 @@ func deleteHeaderWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number
// isCanon is an internal utility method, to check whether the given number/hash
// is part of the ancient (canon) set.
func isCanon(reader ethdb.AncientReaderOp, number uint64, hash common.Hash) bool {
h, err := reader.Ancient(chainFreezerHashTable, number)
h, err := reader.Ancient(ChainFreezerHashTable, number)
if err != nil {
return false
}
@@ -443,7 +443,7 @@ func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue
db.ReadAncients(func(reader ethdb.AncientReaderOp) error {
// Check if the data is in ancients
if isCanon(reader, number, hash) {
data, _ = reader.Ancient(chainFreezerBodiesTable, number)
data, _ = reader.Ancient(ChainFreezerBodiesTable, number)
return nil
}
// If not, try reading from leveldb
@@ -458,7 +458,7 @@ func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue
func ReadCanonicalBodyRLP(db ethdb.Reader, number uint64) rlp.RawValue {
var data []byte
db.ReadAncients(func(reader ethdb.AncientReaderOp) error {
data, _ = reader.Ancient(chainFreezerBodiesTable, number)
data, _ = reader.Ancient(ChainFreezerBodiesTable, number)
if len(data) > 0 {
return nil
}
@@ -526,7 +526,7 @@ func ReadTdRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
db.ReadAncients(func(reader ethdb.AncientReaderOp) error {
// Check if the data is in ancients
if isCanon(reader, number, hash) {
data, _ = reader.Ancient(chainFreezerDifficultyTable, number)
data, _ = reader.Ancient(ChainFreezerDifficultyTable, number)
return nil
}
// If not, try reading from leveldb
@@ -586,7 +586,7 @@ func ReadReceiptsRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawVa
db.ReadAncients(func(reader ethdb.AncientReaderOp) error {
// Check if the data is in ancients
if isCanon(reader, number, hash) {
data, _ = reader.Ancient(chainFreezerReceiptTable, number)
data, _ = reader.Ancient(ChainFreezerReceiptTable, number)
return nil
}
// If not, try reading from leveldb
@@ -787,19 +787,19 @@ func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts
func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *types.Header, receipts []*types.ReceiptForStorage, td *big.Int) error {
num := block.NumberU64()
if err := op.AppendRaw(chainFreezerHashTable, num, block.Hash().Bytes()); err != nil {
if err := op.AppendRaw(ChainFreezerHashTable, num, block.Hash().Bytes()); err != nil {
return fmt.Errorf("can't add block %d hash: %v", num, err)
}
if err := op.Append(chainFreezerHeaderTable, num, header); err != nil {
if err := op.Append(ChainFreezerHeaderTable, num, header); err != nil {
return fmt.Errorf("can't append block header %d: %v", num, err)
}
if err := op.Append(chainFreezerBodiesTable, num, block.Body()); err != nil {
if err := op.Append(ChainFreezerBodiesTable, num, block.Body()); err != nil {
return fmt.Errorf("can't append block body %d: %v", num, err)
}
if err := op.Append(chainFreezerReceiptTable, num, receipts); err != nil {
if err := op.Append(ChainFreezerReceiptTable, num, receipts); err != nil {
return fmt.Errorf("can't append block %d receipts: %v", num, err)
}
if err := op.Append(chainFreezerDifficultyTable, num, td); err != nil {
if err := op.Append(ChainFreezerDifficultyTable, num, td); err != nil {
return fmt.Errorf("can't append block %d total difficulty: %v", num, err)
}
return nil

View File

@@ -113,8 +113,8 @@ func TestBlockStorage(t *testing.T) {
block := types.NewBlockWithHeader(&types.Header{
Extra: []byte("test block"),
UncleHash: types.EmptyUncleHash,
TxHash: types.EmptyRootHash,
ReceiptHash: types.EmptyRootHash,
TxHash: types.EmptyTxsHash,
ReceiptHash: types.EmptyReceiptsHash,
})
if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil {
t.Fatalf("Non existent block returned: %v", entry)
@@ -161,8 +161,8 @@ func TestPartialBlockStorage(t *testing.T) {
block := types.NewBlockWithHeader(&types.Header{
Extra: []byte("test block"),
UncleHash: types.EmptyUncleHash,
TxHash: types.EmptyRootHash,
ReceiptHash: types.EmptyRootHash,
TxHash: types.EmptyTxsHash,
ReceiptHash: types.EmptyReceiptsHash,
})
// Store a header and check that it's not recognized as a block
WriteHeader(db, block.Header())
@@ -198,8 +198,8 @@ func TestBadBlockStorage(t *testing.T) {
Number: big.NewInt(1),
Extra: []byte("bad block"),
UncleHash: types.EmptyUncleHash,
TxHash: types.EmptyRootHash,
ReceiptHash: types.EmptyRootHash,
TxHash: types.EmptyTxsHash,
ReceiptHash: types.EmptyReceiptsHash,
})
if entry := ReadBadBlock(db, block.Hash()); entry != nil {
t.Fatalf("Non existent block returned: %v", entry)
@@ -216,8 +216,8 @@ func TestBadBlockStorage(t *testing.T) {
Number: big.NewInt(2),
Extra: []byte("bad block two"),
UncleHash: types.EmptyUncleHash,
TxHash: types.EmptyRootHash,
ReceiptHash: types.EmptyRootHash,
TxHash: types.EmptyTxsHash,
ReceiptHash: types.EmptyReceiptsHash,
})
WriteBadBlock(db, blockTwo)
@@ -235,8 +235,8 @@ func TestBadBlockStorage(t *testing.T) {
Number: big.NewInt(int64(n)),
Extra: []byte("bad block"),
UncleHash: types.EmptyUncleHash,
TxHash: types.EmptyRootHash,
ReceiptHash: types.EmptyRootHash,
TxHash: types.EmptyTxsHash,
ReceiptHash: types.EmptyReceiptsHash,
})
WriteBadBlock(db, block)
}
@@ -446,8 +446,8 @@ func TestAncientStorage(t *testing.T) {
Number: big.NewInt(0),
Extra: []byte("test block"),
UncleHash: types.EmptyUncleHash,
TxHash: types.EmptyRootHash,
ReceiptHash: types.EmptyRootHash,
TxHash: types.EmptyTxsHash,
ReceiptHash: types.EmptyReceiptsHash,
})
// Ensure nothing non-existent will be read
hash, number := block.Hash(), block.NumberU64()
@@ -889,8 +889,8 @@ func TestHeadersRLPStorage(t *testing.T) {
Number: big.NewInt(int64(i)),
Extra: []byte("test block"),
UncleHash: types.EmptyUncleHash,
TxHash: types.EmptyRootHash,
ReceiptHash: types.EmptyRootHash,
TxHash: types.EmptyTxsHash,
ReceiptHash: types.EmptyReceiptsHash,
ParentHash: pHash,
})
chain = append(chain, block)

View File

@@ -82,15 +82,15 @@ func WriteChainConfig(db ethdb.KeyValueWriter, hash common.Hash, cfg *params.Cha
}
// ReadGenesisStateSpec retrieves the genesis state specification based on the
// given genesis hash.
func ReadGenesisStateSpec(db ethdb.KeyValueReader, hash common.Hash) []byte {
data, _ := db.Get(genesisStateSpecKey(hash))
// given genesis (block-)hash.
func ReadGenesisStateSpec(db ethdb.KeyValueReader, blockhash common.Hash) []byte {
data, _ := db.Get(genesisStateSpecKey(blockhash))
return data
}
// WriteGenesisStateSpec writes the genesis state specification into the disk.
func WriteGenesisStateSpec(db ethdb.KeyValueWriter, hash common.Hash, data []byte) {
if err := db.Put(genesisStateSpecKey(hash), data); err != nil {
func WriteGenesisStateSpec(db ethdb.KeyValueWriter, blockhash common.Hash, data []byte) {
if err := db.Put(genesisStateSpecKey(blockhash), data); err != nil {
log.Crit("Failed to store genesis state", "err", err)
}
}

View File

@@ -18,30 +18,30 @@ package rawdb
// The list of table names of chain freezer.
const (
// chainFreezerHeaderTable indicates the name of the freezer header table.
chainFreezerHeaderTable = "headers"
// ChainFreezerHeaderTable indicates the name of the freezer header table.
ChainFreezerHeaderTable = "headers"
// chainFreezerHashTable indicates the name of the freezer canonical hash table.
chainFreezerHashTable = "hashes"
// ChainFreezerHashTable indicates the name of the freezer canonical hash table.
ChainFreezerHashTable = "hashes"
// chainFreezerBodiesTable indicates the name of the freezer block body table.
chainFreezerBodiesTable = "bodies"
// ChainFreezerBodiesTable indicates the name of the freezer block body table.
ChainFreezerBodiesTable = "bodies"
// chainFreezerReceiptTable indicates the name of the freezer receipts table.
chainFreezerReceiptTable = "receipts"
// ChainFreezerReceiptTable indicates the name of the freezer receipts table.
ChainFreezerReceiptTable = "receipts"
// chainFreezerDifficultyTable indicates the name of the freezer total difficulty table.
chainFreezerDifficultyTable = "diffs"
// ChainFreezerDifficultyTable indicates the name of the freezer total difficulty table.
ChainFreezerDifficultyTable = "diffs"
)
// chainFreezerNoSnappy configures whether compression is disabled for the ancient-tables.
// Hashes and difficulties don't compress well.
var chainFreezerNoSnappy = map[string]bool{
chainFreezerHeaderTable: false,
chainFreezerHashTable: true,
chainFreezerBodiesTable: false,
chainFreezerReceiptTable: false,
chainFreezerDifficultyTable: true,
ChainFreezerHeaderTable: false,
ChainFreezerHashTable: true,
ChainFreezerBodiesTable: false,
ChainFreezerReceiptTable: false,
ChainFreezerDifficultyTable: true,
}
// The list of identifiers of ancient stores.

View File

@@ -55,8 +55,8 @@ type chainFreezer struct {
}
// newChainFreezer initializes the freezer for ancient chain data.
func newChainFreezer(datadir string, namespace string, readonly bool, maxTableSize uint32, tables map[string]bool) (*chainFreezer, error) {
freezer, err := NewFreezer(datadir, namespace, readonly, maxTableSize, tables)
func newChainFreezer(datadir string, namespace string, readonly bool) (*chainFreezer, error) {
freezer, err := NewChainFreezer(datadir, namespace, readonly)
if err != nil {
return nil, err
}
@@ -280,19 +280,19 @@ func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hash
}
// Write to the batch.
if err := op.AppendRaw(chainFreezerHashTable, number, hash[:]); err != nil {
if err := op.AppendRaw(ChainFreezerHashTable, number, hash[:]); err != nil {
return fmt.Errorf("can't write hash to Freezer: %v", err)
}
if err := op.AppendRaw(chainFreezerHeaderTable, number, header); err != nil {
if err := op.AppendRaw(ChainFreezerHeaderTable, number, header); err != nil {
return fmt.Errorf("can't write header to Freezer: %v", err)
}
if err := op.AppendRaw(chainFreezerBodiesTable, number, body); err != nil {
if err := op.AppendRaw(ChainFreezerBodiesTable, number, body); err != nil {
return fmt.Errorf("can't write body to Freezer: %v", err)
}
if err := op.AppendRaw(chainFreezerReceiptTable, number, receipts); err != nil {
if err := op.AppendRaw(ChainFreezerReceiptTable, number, receipts); err != nil {
return fmt.Errorf("can't write receipts to Freezer: %v", err)
}
if err := op.AppendRaw(chainFreezerDifficultyTable, number, td); err != nil {
if err := op.AppendRaw(ChainFreezerDifficultyTable, number, td); err != nil {
return fmt.Errorf("can't write td to Freezer: %v", err)
}

View File

@@ -50,7 +50,7 @@ func InitDatabaseFromFreezer(db ethdb.Database) {
if i+count > frozen {
count = frozen - i
}
data, err := db.AncientRange(chainFreezerHashTable, i, count, 32*count)
data, err := db.AncientRange(ChainFreezerHashTable, i, count, 32*count)
if err != nil {
log.Crit("Failed to init database from freezer", "err", err)
}

View File

@@ -200,7 +200,7 @@ func resolveChainFreezerDir(ancient string) string {
// where the chain freezer can be opened.
func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace string, readonly bool) (ethdb.Database, error) {
// Create the idle freezer instance
frdb, err := newChainFreezer(resolveChainFreezerDir(ancient), namespace, readonly, freezerTableSize, chainFreezerNoSnappy)
frdb, err := newChainFreezer(resolveChainFreezerDir(ancient), namespace, readonly)
if err != nil {
return nil, err
}
@@ -231,7 +231,7 @@ func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace st
// If the freezer already contains something, ensure that the genesis blocks
// match, otherwise we might mix up freezers across chains and destroy both
// the freezer and the key-value store.
frgenesis, err := frdb.Ancient(chainFreezerHashTable, 0)
frgenesis, err := frdb.Ancient(ChainFreezerHashTable, 0)
if err != nil {
return nil, fmt.Errorf("failed to retrieve genesis from ancient %v", err)
} else if !bytes.Equal(kvgenesis, frgenesis) {

View File

@@ -79,6 +79,12 @@ type Freezer struct {
closeOnce sync.Once
}
// NewChainFreezer is a small utility method around NewFreezer that sets the
// default parameters for the chain storage.
func NewChainFreezer(datadir string, namespace string, readonly bool) (*Freezer, error) {
return NewFreezer(datadir, namespace, readonly, freezerTableSize, chainFreezerNoSnappy)
}
// NewFreezer creates a freezer instance for maintaining immutable ordered
// data according to the given parameters.
//

View File

@@ -27,17 +27,12 @@ import (
"sync/atomic"
"testing"
"testing/quick"
"time"
"github.com/davecgh/go-spew/spew"
"github.com/ethereum/go-ethereum/metrics"
"github.com/stretchr/testify/require"
)
func init() {
rand.Seed(time.Now().Unix())
}
// TestFreezerBasics test initializing a freezertable from scratch, writing to the table,
// and reading it back.
func TestFreezerBasics(t *testing.T) {

View File

@@ -117,7 +117,7 @@ func (it *NodeIterator) step() error {
if !it.dataIt.Next(true) {
it.dataIt = nil
}
if !bytes.Equal(account.CodeHash, emptyCodeHash) {
if !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) {
it.codeHash = common.BytesToHash(account.CodeHash)
addrHash := common.BytesToHash(it.stateIt.LeafKey())
it.code, err = it.state.db.ContractCode(addrHash, common.BytesToHash(account.CodeHash))

View File

@@ -31,7 +31,6 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state/snapshot"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
@@ -55,14 +54,6 @@ const (
rangeCompactionThreshold = 100000
)
var (
// emptyRoot is the known root hash of an empty trie.
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
// emptyCode is the known hash of the empty EVM bytecode.
emptyCode = crypto.Keccak256(nil)
)
// Config includes all the configurations for pruning.
type Config struct {
Datadir string // The directory of the state database
@@ -446,7 +437,7 @@ func extractGenesis(db ethdb.Database, stateBloom *stateBloom) error {
if err := rlp.DecodeBytes(accIter.LeafBlob(), &acc); err != nil {
return err
}
if acc.Root != emptyRoot {
if acc.Root != types.EmptyRootHash {
id := trie.StorageTrieID(genesis.Root(), common.BytesToHash(accIter.LeafKey()), acc.Root)
storageTrie, err := trie.NewStateTrie(id, trie.NewDatabase(db))
if err != nil {
@@ -463,7 +454,7 @@ func extractGenesis(db ethdb.Database, stateBloom *stateBloom) error {
return storageIter.Error()
}
}
if !bytes.Equal(acc.CodeHash, emptyCode) {
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) {
stateBloom.Put(acc.CodeHash, nil)
}
}

View File

@@ -21,6 +21,7 @@ import (
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
)
@@ -41,10 +42,10 @@ func SlimAccount(nonce uint64, balance *big.Int, root common.Hash, codehash []by
Nonce: nonce,
Balance: balance,
}
if root != emptyRoot {
if root != types.EmptyRootHash {
slim.Root = root[:]
}
if !bytes.Equal(codehash, emptyCode[:]) {
if !bytes.Equal(codehash, types.EmptyCodeHash[:]) {
slim.CodeHash = codehash
}
return slim
@@ -68,10 +69,10 @@ func FullAccount(data []byte) (Account, error) {
return Account{}, err
}
if len(account.Root) == 0 {
account.Root = emptyRoot[:]
account.Root = types.EmptyRootHash[:]
}
if len(account.CodeHash) == 0 {
account.CodeHash = emptyCode[:]
account.CodeHash = types.EmptyCodeHash[:]
}
return account, nil
}

View File

@@ -28,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
@@ -74,7 +75,7 @@ func GenerateTrie(snaptree *Tree, root common.Hash, src ethdb.Database, dst ethd
scheme := snaptree.triedb.Scheme()
got, err := generateTrieRoot(dst, scheme, acctIt, common.Hash{}, stackTrieGenerate, func(dst ethdb.KeyValueWriter, accountHash, codeHash common.Hash, stat *generateStats) (common.Hash, error) {
// Migrate the code first, commit the contract code into the tmp db.
if codeHash != emptyCode {
if codeHash != types.EmptyCodeHash {
code := rawdb.ReadCode(src, codeHash)
if len(code) == 0 {
return common.Hash{}, errors.New("failed to read contract code")

View File

@@ -18,6 +18,7 @@ package snapshot
import (
"bytes"
crand "crypto/rand"
"math/rand"
"testing"
@@ -73,7 +74,7 @@ func TestMergeBasics(t *testing.T) {
if rand.Intn(2) == 0 {
accStorage := make(map[common.Hash][]byte)
value := make([]byte, 32)
rand.Read(value)
crand.Read(value)
accStorage[randomHash()] = value
storage[h] = accStorage
}
@@ -294,7 +295,7 @@ func BenchmarkSearchSlot(b *testing.B) {
accStorage := make(map[common.Hash][]byte)
for i := 0; i < 5; i++ {
value := make([]byte, 32)
rand.Read(value)
crand.Read(value)
accStorage[randomHash()] = value
storage[accountKey] = accStorage
}
@@ -330,7 +331,7 @@ func BenchmarkFlatten(b *testing.B) {
accStorage := make(map[common.Hash][]byte)
for i := 0; i < 20; i++ {
value := make([]byte, 32)
rand.Read(value)
crand.Read(value)
accStorage[randomHash()] = value
}
storage[accountKey] = accStorage
@@ -379,7 +380,7 @@ func BenchmarkJournal(b *testing.B) {
accStorage := make(map[common.Hash][]byte)
for i := 0; i < 200; i++ {
value := make([]byte, 32)
rand.Read(value)
crand.Read(value)
accStorage[randomHash()] = value
}
storage[accountKey] = accStorage

View File

@@ -27,7 +27,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
@@ -35,12 +35,6 @@ import (
)
var (
// emptyRoot is the known root hash of an empty trie.
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
// emptyCode is the known hash of the empty EVM bytecode.
emptyCode = crypto.Keccak256Hash(nil)
// accountCheckRange is the upper limit of the number of accounts involved in
// each range check. This is a value estimated based on experience. If this
// range is too large, the failure rate of range proof will increase. Otherwise,
@@ -591,10 +585,10 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er
if accMarker == nil || !bytes.Equal(account[:], accMarker) {
dataLen := len(val) // Approximate size, saves us a round of RLP-encoding
if !write {
if bytes.Equal(acc.CodeHash, emptyCode[:]) {
if bytes.Equal(acc.CodeHash, types.EmptyCodeHash[:]) {
dataLen -= 32
}
if acc.Root == emptyRoot {
if acc.Root == types.EmptyRootHash {
dataLen -= 32
}
snapRecoveredAccountMeter.Mark(1)
@@ -621,7 +615,7 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er
// If the iterated account is the contract, create a further loop to
// verify or regenerate the contract storage.
if acc.Root == emptyRoot {
if acc.Root == types.EmptyRootHash {
ctx.removeStorageAt(account)
} else {
var storeMarker []byte

View File

@@ -25,6 +25,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
@@ -49,9 +50,9 @@ func TestGeneration(t *testing.T) {
var helper = newHelper()
stRoot := helper.makeStorageTrie(common.Hash{}, common.Hash{}, []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, false)
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()})
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
@@ -83,16 +84,16 @@ func TestGenerateExistentState(t *testing.T) {
var helper = newHelper()
stRoot := helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addSnapAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()})
helper.addSnapAccount("acc-2", &Account{Balance: big.NewInt(2), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()})
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
stRoot = helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addSnapAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapStorage("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
root, snap := helper.CommitAndGenerate()
@@ -235,28 +236,28 @@ func TestGenerateExistentStateWithWrongStorage(t *testing.T) {
helper := newHelper()
// Account one, empty root but non-empty database
helper.addAccount("acc-1", &Account{Balance: big.NewInt(1), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()})
helper.addAccount("acc-1", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
// Account two, non empty root but empty database
stRoot := helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-2")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addAccount("acc-2", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addAccount("acc-2", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
// Miss slots
{
// Account three, non empty root but misses slots in the beginning
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addAccount("acc-3", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addAccount("acc-3", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapStorage("acc-3", []string{"key-2", "key-3"}, []string{"val-2", "val-3"})
// Account four, non empty root but misses slots in the middle
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-4")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addAccount("acc-4", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addAccount("acc-4", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapStorage("acc-4", []string{"key-1", "key-3"}, []string{"val-1", "val-3"})
// Account five, non empty root but misses slots in the end
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-5")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addAccount("acc-5", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addAccount("acc-5", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapStorage("acc-5", []string{"key-1", "key-2"}, []string{"val-1", "val-2"})
}
@@ -264,22 +265,22 @@ func TestGenerateExistentStateWithWrongStorage(t *testing.T) {
{
// Account six, non empty root but wrong slots in the beginning
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-6")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addAccount("acc-6", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addAccount("acc-6", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapStorage("acc-6", []string{"key-1", "key-2", "key-3"}, []string{"badval-1", "val-2", "val-3"})
// Account seven, non empty root but wrong slots in the middle
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-7")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addAccount("acc-7", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addAccount("acc-7", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapStorage("acc-7", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "badval-2", "val-3"})
// Account eight, non empty root but wrong slots in the end
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-8")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addAccount("acc-8", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addAccount("acc-8", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapStorage("acc-8", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "badval-3"})
// Account 9, non empty root but rotated slots
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-9")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addAccount("acc-9", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addAccount("acc-9", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapStorage("acc-9", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-3", "val-2"})
}
@@ -287,17 +288,17 @@ func TestGenerateExistentStateWithWrongStorage(t *testing.T) {
{
// Account 10, non empty root but extra slots in the beginning
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-10")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addAccount("acc-10", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addAccount("acc-10", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapStorage("acc-10", []string{"key-0", "key-1", "key-2", "key-3"}, []string{"val-0", "val-1", "val-2", "val-3"})
// Account 11, non empty root but extra slots in the middle
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-11")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addAccount("acc-11", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addAccount("acc-11", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapStorage("acc-11", []string{"key-1", "key-2", "key-2-1", "key-3"}, []string{"val-1", "val-2", "val-2-1", "val-3"})
// Account 12, non empty root but extra slots in the end
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-12")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addAccount("acc-12", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addAccount("acc-12", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapStorage("acc-12", []string{"key-1", "key-2", "key-3", "key-4"}, []string{"val-1", "val-2", "val-3", "val-4"})
}
@@ -337,25 +338,25 @@ func TestGenerateExistentStateWithWrongAccounts(t *testing.T) {
// Missing accounts, only in the trie
{
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()}) // Beginning
helper.addTrieAccount("acc-4", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()}) // Middle
helper.addTrieAccount("acc-6", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()}) // End
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // Beginning
helper.addTrieAccount("acc-4", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // Middle
helper.addTrieAccount("acc-6", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // End
}
// Wrong accounts
{
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapAccount("acc-2", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: common.Hex2Bytes("0x1234")})
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addSnapAccount("acc-3", &Account{Balance: big.NewInt(1), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()})
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapAccount("acc-3", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
}
// Extra accounts, only in the snap
{
helper.addSnapAccount("acc-0", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyRoot.Bytes()}) // before the beginning
helper.addSnapAccount("acc-5", &Account{Balance: big.NewInt(1), Root: emptyRoot.Bytes(), CodeHash: common.Hex2Bytes("0x1234")}) // Middle
helper.addSnapAccount("acc-7", &Account{Balance: big.NewInt(1), Root: emptyRoot.Bytes(), CodeHash: emptyRoot.Bytes()}) // after the end
helper.addSnapAccount("acc-0", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // before the beginning
helper.addSnapAccount("acc-5", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: common.Hex2Bytes("0x1234")}) // Middle
helper.addSnapAccount("acc-7", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // after the end
}
root, snap := helper.CommitAndGenerate()
@@ -384,9 +385,9 @@ func TestGenerateCorruptAccountTrie(t *testing.T) {
// without any storage slots to keep the test smaller.
helper := newHelper()
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()}) // 0xc7a30f39aff471c95d8a837497ad0e49b65be475cc0953540f80cfcdbdcd9074
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()}) // 0x19ead688e907b0fab07176120dceec244a72aff2f0aa51e8b827584e378772f4
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // 0xc7a30f39aff471c95d8a837497ad0e49b65be475cc0953540f80cfcdbdcd9074
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // 0x19ead688e907b0fab07176120dceec244a72aff2f0aa51e8b827584e378772f4
root := helper.Commit() // Root: 0xa04693ea110a31037fb5ee814308a6f1d76bdab0b11676bdf4541d2de55ba978
@@ -419,10 +420,10 @@ func TestGenerateMissingStorageTrie(t *testing.T) {
helper := newHelper()
stRoot := helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
stRoot = helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: emptyCode.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
root := helper.Commit()
@@ -453,10 +454,10 @@ func TestGenerateCorruptStorageTrie(t *testing.T) {
helper := newHelper()
stRoot := helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
stRoot = helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: emptyCode.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
root := helper.Commit()
@@ -488,7 +489,7 @@ func TestGenerateWithExtraAccounts(t *testing.T) {
[]string{"val-1", "val-2", "val-3", "val-4", "val-5"},
true,
)
acc := &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()}
acc := &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}
val, _ := rlp.EncodeToBytes(acc)
helper.accTrie.Update([]byte("acc-1"), val) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
@@ -508,7 +509,7 @@ func TestGenerateWithExtraAccounts(t *testing.T) {
[]string{"val-1", "val-2", "val-3", "val-4", "val-5"},
true,
)
acc := &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()}
acc := &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}
val, _ := rlp.EncodeToBytes(acc)
key := hashData([]byte("acc-2"))
rawdb.WriteAccountSnapshot(helper.diskdb, key, val)
@@ -559,7 +560,7 @@ func TestGenerateWithManyExtraAccounts(t *testing.T) {
[]string{"val-1", "val-2", "val-3"},
true,
)
acc := &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()}
acc := &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}
val, _ := rlp.EncodeToBytes(acc)
helper.accTrie.Update([]byte("acc-1"), val) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
@@ -573,8 +574,7 @@ func TestGenerateWithManyExtraAccounts(t *testing.T) {
{
// 100 accounts exist only in snapshot
for i := 0; i < 1000; i++ {
//acc := &Account{Balance: big.NewInt(int64(i)), Root: stTrie.Hash().Bytes(), CodeHash: emptyCode.Bytes()}
acc := &Account{Balance: big.NewInt(int64(i)), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()}
acc := &Account{Balance: big.NewInt(int64(i)), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}
val, _ := rlp.EncodeToBytes(acc)
key := hashData([]byte(fmt.Sprintf("acc-%d", i)))
rawdb.WriteAccountSnapshot(helper.diskdb, key, val)
@@ -611,7 +611,7 @@ func TestGenerateWithExtraBeforeAndAfter(t *testing.T) {
}
helper := newHelper()
{
acc := &Account{Balance: big.NewInt(1), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()}
acc := &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}
val, _ := rlp.EncodeToBytes(acc)
helper.accTrie.Update(common.HexToHash("0x03").Bytes(), val)
helper.accTrie.Update(common.HexToHash("0x07").Bytes(), val)
@@ -648,7 +648,7 @@ func TestGenerateWithMalformedSnapdata(t *testing.T) {
}
helper := newHelper()
{
acc := &Account{Balance: big.NewInt(1), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()}
acc := &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}
val, _ := rlp.EncodeToBytes(acc)
helper.accTrie.Update(common.HexToHash("0x03").Bytes(), val)
@@ -687,7 +687,7 @@ func TestGenerateFromEmptySnap(t *testing.T) {
for i := 0; i < 400; i++ {
stRoot := helper.makeStorageTrie(common.Hash{}, hashData([]byte(fmt.Sprintf("acc-%d", i))), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addTrieAccount(fmt.Sprintf("acc-%d", i),
&Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
&Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
}
root, snap := helper.CommitAndGenerate()
t.Logf("Root: %#x\n", root) // Root: 0x6f7af6d2e1a1bf2b84a3beb3f8b64388465fbc1e274ca5d5d3fc787ca78f59e4
@@ -724,7 +724,7 @@ func TestGenerateWithIncompleteStorage(t *testing.T) {
for i := 0; i < 8; i++ {
accKey := fmt.Sprintf("acc-%d", i)
stRoot := helper.makeStorageTrie(common.Hash{}, hashData([]byte(accKey)), stKeys, stVals, true)
helper.addAccount(accKey, &Account{Balance: big.NewInt(int64(i)), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addAccount(accKey, &Account{Balance: big.NewInt(int64(i)), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
var moddedKeys []string
var moddedVals []string
for ii := 0; ii < 8; ii++ {
@@ -816,11 +816,11 @@ func TestGenerateCompleteSnapshotWithDanglingStorage(t *testing.T) {
var helper = newHelper()
stRoot := helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addAccount("acc-2", &Account{Balance: big.NewInt(1), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()})
helper.addAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addAccount("acc-2", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addAccount("acc-3", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addAccount("acc-3", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
helper.addSnapStorage("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
@@ -851,11 +851,11 @@ func TestGenerateBrokenSnapshotWithDanglingStorage(t *testing.T) {
var helper = newHelper()
stRoot := helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()})
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: emptyCode.Bytes()})
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
populateDangling(helper.diskdb)

View File

@@ -18,6 +18,7 @@ package snapshot
import (
"bytes"
crand "crypto/rand"
"encoding/binary"
"fmt"
"math/rand"
@@ -47,7 +48,7 @@ func TestAccountIteratorBasics(t *testing.T) {
if rand.Intn(2) == 0 {
accStorage := make(map[common.Hash][]byte)
value := make([]byte, 32)
rand.Read(value)
crand.Read(value)
accStorage[randomHash()] = value
storage[h] = accStorage
}
@@ -79,7 +80,7 @@ func TestStorageIteratorBasics(t *testing.T) {
var nilstorage int
for i := 0; i < 100; i++ {
rand.Read(value)
crand.Read(value)
if rand.Intn(2) == 0 {
accStorage[randomHash()] = common.CopyBytes(value)
} else {

View File

@@ -17,6 +17,7 @@
package snapshot
import (
crand "crypto/rand"
"encoding/binary"
"fmt"
"math/big"
@@ -27,13 +28,14 @@ import (
"github.com/VictoriaMetrics/fastcache"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
)
// randomHash generates a random blob of data and returns it as a hash.
func randomHash() common.Hash {
var hash common.Hash
if n, err := rand.Read(hash[:]); n != common.HashLength || err != nil {
if n, err := crand.Read(hash[:]); n != common.HashLength || err != nil {
panic(err)
}
return hash
@@ -46,7 +48,7 @@ func randomAccount() []byte {
Balance: big.NewInt(rand.Int63()),
Nonce: rand.Uint64(),
Root: root[:],
CodeHash: emptyCode[:],
CodeHash: types.EmptyCodeHash[:],
}
data, _ := rlp.EncodeToBytes(a)
return data

View File

@@ -31,8 +31,6 @@ import (
"github.com/ethereum/go-ethereum/trie"
)
var emptyCodeHash = crypto.Keccak256(nil)
type Code []byte
func (c Code) String() string {
@@ -95,7 +93,7 @@ type stateObject struct {
// empty returns whether the account is considered empty.
func (s *stateObject) empty() bool {
return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash)
return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, types.EmptyCodeHash.Bytes())
}
// newObject creates a state object.
@@ -104,10 +102,10 @@ func newObject(db *StateDB, address common.Address, data types.StateAccount) *st
data.Balance = new(big.Int)
}
if data.CodeHash == nil {
data.CodeHash = emptyCodeHash
data.CodeHash = types.EmptyCodeHash.Bytes()
}
if data.Root == (common.Hash{}) {
data.Root = emptyRoot
data.Root = types.EmptyRootHash
}
return &stateObject{
db: db,
@@ -154,7 +152,7 @@ func (s *stateObject) getTrie(db Database) (Trie, error) {
if s.trie == nil {
// Try fetching from prefetcher first
// We don't prefetch empty tries
if s.data.Root != emptyRoot && s.db.prefetcher != nil {
if s.data.Root != types.EmptyRootHash && s.db.prefetcher != nil {
// When the miner is creating the pending state, there is no
// prefetcher
s.trie = s.db.prefetcher.trie(s.addrHash, s.data.Root)
@@ -270,7 +268,7 @@ func (s *stateObject) finalise(prefetch bool) {
slotsToPrefetch = append(slotsToPrefetch, common.CopyBytes(key[:])) // Copy needed for closure
}
}
if s.db.prefetcher != nil && prefetch && len(slotsToPrefetch) > 0 && s.data.Root != emptyRoot {
if s.db.prefetcher != nil && prefetch && len(slotsToPrefetch) > 0 && s.data.Root != types.EmptyRootHash {
s.db.prefetcher.prefetch(s.addrHash, s.data.Root, slotsToPrefetch)
}
if len(s.dirtyStorage) > 0 {
@@ -454,7 +452,7 @@ func (s *stateObject) Code(db Database) []byte {
if s.code != nil {
return s.code
}
if bytes.Equal(s.CodeHash(), emptyCodeHash) {
if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) {
return nil
}
code, err := db.ContractCode(s.addrHash, common.BytesToHash(s.CodeHash()))
@@ -472,7 +470,7 @@ func (s *stateObject) CodeSize(db Database) int {
if s.code != nil {
return len(s.code)
}
if bytes.Equal(s.CodeHash(), emptyCodeHash) {
if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) {
return 0
}
size, err := db.ContractCodeSize(s.addrHash, common.BytesToHash(s.CodeHash()))

View File

@@ -41,11 +41,6 @@ type revision struct {
journalIndex int
}
var (
// emptyRoot is the known root hash of an empty trie.
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
)
type proofList [][]byte
func (n *proofList) Put(key []byte, value []byte) error {
@@ -580,10 +575,10 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
Root: common.BytesToHash(acc.Root),
}
if len(data.CodeHash) == 0 {
data.CodeHash = emptyCodeHash
data.CodeHash = types.EmptyCodeHash.Bytes()
}
if data.Root == (common.Hash{}) {
data.Root = emptyRoot
data.Root = types.EmptyRootHash
}
}
}
@@ -1066,11 +1061,11 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
s.stateObjectsDestruct = make(map[common.Address]struct{})
}
if root == (common.Hash{}) {
root = emptyRoot
root = types.EmptyRootHash
}
origin := s.originalRoot
if origin == (common.Hash{}) {
origin = emptyRoot
origin = types.EmptyRootHash
}
if root != origin {
start := time.Now()

View File

@@ -134,8 +134,7 @@ func checkStateConsistency(db ethdb.Database, root common.Hash) error {
// Tests that an empty state is not scheduled for syncing.
func TestEmptyStateSync(t *testing.T) {
db := trie.NewDatabase(rawdb.NewMemoryDatabase())
empty := common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
sync := NewStateSync(empty, rawdb.NewMemoryDatabase(), nil, db.Scheme())
sync := NewStateSync(types.EmptyRootHash, rawdb.NewMemoryDatabase(), nil, db.Scheme())
if paths, nodes, codes := sync.Missing(1); len(paths) != 0 || len(nodes) != 0 || len(codes) != 0 {
t.Errorf("content requested for empty state: %v, %v, %v", nodes, paths, codes)
}
@@ -555,7 +554,7 @@ func TestIncompleteStateSync(t *testing.T) {
isCode[crypto.Keccak256Hash(acc.code)] = struct{}{}
}
}
isCode[common.BytesToHash(emptyCodeHash)] = struct{}{}
isCode[types.EmptyCodeHash] = struct{}{}
checkTrieConsistency(db, srcRoot)
// Create a destination state and sync with the scheduler

View File

@@ -404,7 +404,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
header.BaseFee = misc.CalcBaseFee(config, parent.Header())
}
if config.IsShanghai(header.Time) {
header.WithdrawalsHash = &types.EmptyRootHash
header.WithdrawalsHash = &types.EmptyWithdrawalsHash
}
var receipts []*types.Receipt
// The post-state result doesn't need to be correct (this is a bad block), but we do need something there

View File

@@ -18,6 +18,7 @@ package txpool
import (
"crypto/ecdsa"
crand "crypto/rand"
"errors"
"fmt"
"math/big"
@@ -92,7 +93,7 @@ func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ec
func pricedDataTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey, bytes uint64) *types.Transaction {
data := make([]byte, bytes)
rand.Read(data)
crand.Read(data)
tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(0), gaslimit, gasprice, data), types.HomesteadSigner{}, key)
return tx

View File

@@ -31,11 +31,6 @@ import (
"github.com/ethereum/go-ethereum/rlp"
)
var (
EmptyRootHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
EmptyUncleHash = rlpHash([]*Header(nil))
)
// A BlockNonce is a 64-bit hash which proves (combined with the
// mix-hash) that a sufficient amount of computation has been carried
// out on a block.
@@ -155,14 +150,14 @@ func (h *Header) SanityCheck() error {
// that is: no transactions, no uncles and no withdrawals.
func (h *Header) EmptyBody() bool {
if h.WithdrawalsHash == nil {
return h.TxHash == EmptyRootHash && h.UncleHash == EmptyUncleHash
return h.TxHash == EmptyTxsHash && h.UncleHash == EmptyUncleHash
}
return h.TxHash == EmptyRootHash && h.UncleHash == EmptyUncleHash && *h.WithdrawalsHash == EmptyRootHash
return h.TxHash == EmptyTxsHash && h.UncleHash == EmptyUncleHash && *h.WithdrawalsHash == EmptyWithdrawalsHash
}
// EmptyReceipts returns true if there are no receipts for this header/block.
func (h *Header) EmptyReceipts() bool {
return h.ReceiptHash == EmptyRootHash
return h.ReceiptHash == EmptyReceiptsHash
}
// Body is a simple (mutable, non-safe) data container for storing and moving
@@ -210,7 +205,7 @@ func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*
// TODO: panic if len(txs) != len(receipts)
if len(txs) == 0 {
b.header.TxHash = EmptyRootHash
b.header.TxHash = EmptyTxsHash
} else {
b.header.TxHash = DeriveSha(Transactions(txs), hasher)
b.transactions = make(Transactions, len(txs))
@@ -218,7 +213,7 @@ func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*
}
if len(receipts) == 0 {
b.header.ReceiptHash = EmptyRootHash
b.header.ReceiptHash = EmptyReceiptsHash
} else {
b.header.ReceiptHash = DeriveSha(Receipts(receipts), hasher)
b.header.Bloom = CreateBloom(receipts)
@@ -250,7 +245,7 @@ func NewBlockWithWithdrawals(header *Header, txs []*Transaction, uncles []*Heade
if withdrawals == nil {
b.header.WithdrawalsHash = nil
} else if len(withdrawals) == 0 {
b.header.WithdrawalsHash = &EmptyRootHash
b.header.WithdrawalsHash = &EmptyWithdrawalsHash
} else {
h := DeriveSha(Withdrawals(withdrawals), hasher)
b.header.WithdrawalsHash = &h

42
core/types/hashes.go Normal file
View File

@@ -0,0 +1,42 @@
// Copyright 2023 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 types
import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
var (
// EmptyRootHash is the known root hash of an empty trie.
EmptyRootHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
// EmptyUncleHash is the known hash of the empty uncle set.
EmptyUncleHash = rlpHash([]*Header(nil)) // 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347
// EmptyCodeHash is the known hash of the empty EVM bytecode.
EmptyCodeHash = crypto.Keccak256Hash(nil) // c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
// EmptyTxsHash is the known hash of the empty transaction set.
EmptyTxsHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
// EmptyReceiptsHash is the known hash of the empty receipt set.
EmptyReceiptsHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
// EmptyWithdrawalsHash is the known hash of the empty withdrawal set.
EmptyWithdrawalsHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
)

View File

@@ -20,10 +20,9 @@
package signify
import (
"math/rand"
"crypto/rand"
"os"
"testing"
"time"
"github.com/jedisct1/go-minisign"
)
@@ -41,8 +40,6 @@ func TestSignify(t *testing.T) {
defer os.Remove(tmpFile.Name())
defer tmpFile.Close()
rand.Seed(time.Now().UnixNano())
data := make([]byte, 1024)
rand.Read(data)
tmpFile.Write(data)
@@ -85,8 +82,6 @@ func TestSignifyTrustedCommentTooManyLines(t *testing.T) {
defer os.Remove(tmpFile.Name())
defer tmpFile.Close()
rand.Seed(time.Now().UnixNano())
data := make([]byte, 1024)
rand.Read(data)
tmpFile.Write(data)
@@ -110,8 +105,6 @@ func TestSignifyTrustedCommentTooManyLinesLF(t *testing.T) {
defer os.Remove(tmpFile.Name())
defer tmpFile.Close()
rand.Seed(time.Now().UnixNano())
data := make([]byte, 1024)
rand.Read(data)
tmpFile.Write(data)
@@ -135,8 +128,6 @@ func TestSignifyTrustedCommentEmpty(t *testing.T) {
defer os.Remove(tmpFile.Name())
defer tmpFile.Close()
rand.Seed(time.Now().UnixNano())
data := make([]byte, 1024)
rand.Read(data)
tmpFile.Write(data)

View File

@@ -448,7 +448,7 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData) (engine.Payloa
block, err := engine.ExecutableDataToBlock(params)
if err != nil {
log.Debug("Invalid NewPayload params", "params", params, "error", err)
return engine.PayloadStatusV1{Status: engine.INVALIDBLOCKHASH}, nil
return engine.PayloadStatusV1{Status: engine.INVALID}, nil
}
// Stash away the last update to warn the user if the beacon client goes offline
api.lastNewPayloadLock.Lock()
@@ -785,9 +785,12 @@ func (api *ConsensusAPI) GetPayloadBodiesByHashV1(hashes []common.Hash) []*engin
// GetPayloadBodiesByRangeV1 implements engine_getPayloadBodiesByRangeV1 which allows for retrieval of a range
// of block bodies by the engine api.
func (api *ConsensusAPI) GetPayloadBodiesByRangeV1(start, count hexutil.Uint64) ([]*engine.ExecutionPayloadBodyV1, error) {
if start == 0 || count == 0 || count > 1024 {
if start == 0 || count == 0 {
return nil, engine.InvalidParams.With(fmt.Errorf("invalid start or count, start: %v count: %v", start, count))
}
if count > 1024 {
return nil, engine.TooLargeRequest.With(fmt.Errorf("requested count too large: %v", count))
}
// limit count up until current
current := api.eth.BlockChain().CurrentBlock().NumberU64()
last := uint64(start) + uint64(count) - 1

View File

@@ -864,8 +864,8 @@ func TestInvalidBloom(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if status.Status != engine.INVALIDBLOCKHASH {
t.Errorf("invalid status: expected VALID got: %v", status.Status)
if status.Status != engine.INVALID {
t.Errorf("invalid status: expected INVALID got: %v", status.Status)
}
}
@@ -1383,37 +1383,43 @@ func TestGetBlockBodiesByRangeInvalidParams(t *testing.T) {
node, eth, _ := setupBodies(t)
api := NewConsensusAPI(eth)
defer node.Close()
tests := []struct {
start hexutil.Uint64
count hexutil.Uint64
want *engine.EngineAPIError
}{
// Genesis
{
start: 0,
count: 1,
want: engine.InvalidParams,
},
// No block requested
{
start: 1,
count: 0,
want: engine.InvalidParams,
},
// Genesis & no block
{
start: 0,
count: 0,
want: engine.InvalidParams,
},
// More than 1024 blocks
{
start: 1,
count: 1025,
want: engine.TooLargeRequest,
},
}
for _, test := range tests {
result, err := api.GetPayloadBodiesByRangeV1(test.start, test.count)
for i, tc := range tests {
result, err := api.GetPayloadBodiesByRangeV1(tc.start, tc.count)
if err == nil {
t.Fatalf("expected error, got %v", result)
t.Fatalf("test %d: expected error, got %v", i, result)
}
if have, want := err.Error(), tc.want.Error(); have != want {
t.Fatalf("test %d: have %s, want %s", i, have, want)
}
}
}

View File

@@ -154,6 +154,11 @@ type Downloader struct {
bodyFetchHook func([]*types.Header) // Method to call upon starting a block body fetch
receiptFetchHook func([]*types.Header) // Method to call upon starting a receipt fetch
chainInsertHook func([]*fetchResult) // Method to call upon inserting a chain of blocks (possibly in multiple invocations)
// Progress reporting metrics
syncStartBlock uint64 // Head snap block when Geth was started
syncStartTime time.Time // Time instance when chain sync started
syncLogTime time.Time // Time instance when status was last reported
}
// LightChain encapsulates functions required to synchronise a light chain.
@@ -231,7 +236,9 @@ func New(checkpoint uint64, stateDb ethdb.Database, mux *event.TypeMux, chain Bl
quitCh: make(chan struct{}),
SnapSyncer: snap.NewSyncer(stateDb, chain.TrieDB().Scheme()),
stateSyncStart: make(chan *stateSync),
syncStartBlock: chain.CurrentFastBlock().NumberU64(),
}
// Create the post-merge skeleton syncer and start the process
dl.skeleton = newSkeleton(stateDb, dl.peers, dropPeer, newBeaconBackfiller(dl, success))
go dl.stateFetcher()
@@ -1614,6 +1621,7 @@ func (d *Downloader) processSnapSyncContent() error {
if len(results) == 0 {
// If pivot sync is done, stop
if oldPivot == nil {
d.reportSnapSyncProgress(true)
return sync.Cancel()
}
// If sync failed, stop
@@ -1627,6 +1635,8 @@ func (d *Downloader) processSnapSyncContent() error {
if d.chainInsertHook != nil {
d.chainInsertHook(results)
}
d.reportSnapSyncProgress(false)
// If we haven't downloaded the pivot block yet, check pivot staleness
// notifications from the header downloader
d.pivotLock.RLock()
@@ -1739,7 +1749,7 @@ func (d *Downloader) commitSnapSyncData(results []*fetchResult, stateSync *state
}
default:
}
// Retrieve the a batch of results to import
// Retrieve the batch of results to import
first, last := results[0].Header, results[len(results)-1].Header
log.Debug("Inserting snap-sync blocks", "items", len(results),
"firstnum", first.Number, "firsthash", first.Hash(),
@@ -1820,3 +1830,56 @@ func (d *Downloader) readHeaderRange(last *types.Header, count int) []*types.Hea
}
return headers
}
// reportSnapSyncProgress calculates various status reports and provides it to the user.
func (d *Downloader) reportSnapSyncProgress(force bool) {
// Initialize the sync start time if it's the first time we're reporting
if d.syncStartTime.IsZero() {
d.syncStartTime = time.Now().Add(-time.Millisecond) // -1ms offset to avoid division by zero
}
// Don't report all the events, just occasionally
if !force && time.Since(d.syncLogTime) < 8*time.Second {
return
}
// Don't report anything until we have a meaningful progress
var (
headerBytes, _ = d.stateDB.AncientSize(rawdb.ChainFreezerHeaderTable)
bodyBytes, _ = d.stateDB.AncientSize(rawdb.ChainFreezerBodiesTable)
receiptBytes, _ = d.stateDB.AncientSize(rawdb.ChainFreezerReceiptTable)
)
syncedBytes := common.StorageSize(headerBytes + bodyBytes + receiptBytes)
if syncedBytes == 0 {
return
}
var (
header = d.blockchain.CurrentHeader()
block = d.blockchain.CurrentFastBlock()
)
syncedBlocks := block.NumberU64() - d.syncStartBlock
if syncedBlocks == 0 {
return
}
// Retrieve the current chain head and calculate the ETA
latest, _, err := d.skeleton.Bounds()
if err != nil {
// We're going to cheat for non-merged networks, but that's fine
latest = d.pivotHeader
}
if latest == nil {
// This should really never happen, but add some defensive code for now.
// TODO(karalabe): Remove it eventually if we don't see it blow.
log.Error("Nil latest block in sync progress report")
return
}
var (
left = latest.Number.Uint64() - block.NumberU64()
eta = time.Since(d.syncStartTime) / time.Duration(syncedBlocks) * time.Duration(left)
progress = fmt.Sprintf("%.2f%%", float64(block.NumberU64())*100/float64(latest.Number.Uint64()))
headers = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(header.Number.Uint64()), common.StorageSize(headerBytes).TerminalString())
bodies = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(block.NumberU64()), common.StorageSize(bodyBytes).TerminalString())
receipts = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(block.NumberU64()), common.StorageSize(receiptBytes).TerminalString())
)
log.Info("Syncing: chain download in progress", "synced", progress, "chain", syncedBytes, "headers", headers, "bodies", bodies, "receipts", receipts, "eta", common.PrettyDuration(eta))
d.syncLogTime = time.Now()
}

View File

@@ -76,6 +76,8 @@ func newFetchResult(header *types.Header, fastSync bool) *fetchResult {
}
if !header.EmptyBody() {
item.pending |= (1 << bodyType)
} else if header.WithdrawalsHash != nil {
item.Withdrawals = make(types.Withdrawals, 0)
}
if fastSync && !header.EmptyReceipts() {
item.pending |= (1 << receiptType)
@@ -142,7 +144,7 @@ type queue struct {
active *sync.Cond
closed bool
lastStatLog time.Time
logTime time.Time // Time instance when status was last reported
}
// newQueue creates a new download queue for scheduling block retrieval.
@@ -388,11 +390,12 @@ func (q *queue) Results(block bool) []*fetchResult {
}
}
// Log some info at certain times
if time.Since(q.lastStatLog) > 60*time.Second {
q.lastStatLog = time.Now()
if time.Since(q.logTime) >= 60*time.Second {
q.logTime = time.Now()
info := q.Stats()
info = append(info, "throttle", throttleThreshold)
log.Info("Downloader queue stats", info...)
log.Debug("Downloader queue stats", info...)
}
return results
}
@@ -781,15 +784,18 @@ func (q *queue) DeliverBodies(id string, txLists [][]*types.Transaction, txListH
return errInvalidBody
}
if header.WithdrawalsHash == nil {
// discard any withdrawals if we don't have a withdrawal hash set
withdrawalLists[index] = nil
} else if *header.WithdrawalsHash == types.EmptyRootHash && withdrawalLists[index] == nil {
// if the withdrawal hash is the emptyRootHash,
// we expect withdrawals to be [] instead of nil
withdrawalLists[index] = make([]*types.Withdrawal, 0)
} else if withdrawalListHashes[index] != *header.WithdrawalsHash {
// nil hash means that withdrawals should not be present in body
if withdrawalLists[index] != nil {
return errInvalidBody
}
} else { // non-nil hash: body must have withdrawals
if withdrawalLists[index] == nil {
return errInvalidBody
}
if withdrawalListHashes[index] != *header.WithdrawalsHash {
return errInvalidBody
}
}
return nil
}

View File

@@ -599,7 +599,7 @@ func (f *BlockFetcher) loop() {
announce.time = task.time
// If the block is empty (header only), short circuit into the final import queue
if header.TxHash == types.EmptyRootHash && header.UncleHash == types.EmptyUncleHash {
if header.TxHash == types.EmptyTxsHash && header.UncleHash == types.EmptyUncleHash {
log.Trace("Block empty, skipping body retrieval", "peer", announce.origin, "number", header.Number, "hash", header.Hash())
block := types.NewBlockWithHeader(header)

View File

@@ -39,6 +39,7 @@ type filter struct {
typ Type
deadline *time.Timer // filter is inactive when deadline triggers
hashes []common.Hash
fullTx bool
txs []*types.Transaction
crit FilterCriteria
logs []*types.Log
@@ -103,14 +104,14 @@ func (api *FilterAPI) timeoutLoop(timeout time.Duration) {
//
// It is part of the filter package because this filter can be used through the
// `eth_getFilterChanges` polling method that is also used for log filters.
func (api *FilterAPI) NewPendingTransactionFilter() rpc.ID {
func (api *FilterAPI) NewPendingTransactionFilter(fullTx *bool) rpc.ID {
var (
pendingTxs = make(chan []*types.Transaction)
pendingTxSub = api.events.SubscribePendingTxs(pendingTxs)
)
api.filtersMu.Lock()
api.filters[pendingTxSub.ID] = &filter{typ: PendingTransactionsSubscription, deadline: time.NewTimer(api.timeout), txs: make([]*types.Transaction, 0), s: pendingTxSub}
api.filters[pendingTxSub.ID] = &filter{typ: PendingTransactionsSubscription, fullTx: fullTx != nil && *fullTx, deadline: time.NewTimer(api.timeout), txs: make([]*types.Transaction, 0), s: pendingTxSub}
api.filtersMu.Unlock()
go func() {
@@ -412,6 +413,9 @@ func (api *FilterAPI) GetFilterChanges(id rpc.ID) (interface{}, error) {
api.filtersMu.Lock()
defer api.filtersMu.Unlock()
chainConfig := api.sys.backend.ChainConfig()
latest := api.sys.backend.CurrentHeader()
if f, found := api.filters[id]; found {
if !f.deadline.Stop() {
// timer expired but filter is not yet removed in timeout loop
@@ -426,9 +430,21 @@ func (api *FilterAPI) GetFilterChanges(id rpc.ID) (interface{}, error) {
f.hashes = nil
return returnHashes(hashes), nil
case PendingTransactionsSubscription:
txs := f.txs
if f.fullTx {
txs := make([]*ethapi.RPCTransaction, 0, len(f.txs))
for _, tx := range f.txs {
txs = append(txs, ethapi.NewRPCPendingTransaction(tx, latest, chainConfig))
}
f.txs = nil
return txs, nil
} else {
hashes := make([]common.Hash, 0, len(f.txs))
for _, tx := range f.txs {
hashes = append(hashes, tx.Hash())
}
f.txs = nil
return hashes, nil
}
case LogsSubscription, MinedAndPendingLogsSubscription:
logs := f.logs
f.logs = nil

View File

@@ -37,6 +37,7 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
)
@@ -52,11 +53,12 @@ type testBackend struct {
}
func (b *testBackend) ChainConfig() *params.ChainConfig {
panic("implement me")
return params.TestChainConfig
}
func (b *testBackend) CurrentHeader() *types.Header {
panic("implement me")
hdr, _ := b.HeaderByNumber(context.TODO(), rpc.LatestBlockNumber)
return hdr
}
func (b *testBackend) ChainDb() ethdb.Database {
@@ -256,10 +258,10 @@ func TestPendingTxFilter(t *testing.T) {
types.NewTransaction(4, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
}
txs []*types.Transaction
hashes []common.Hash
)
fid0 := api.NewPendingTransactionFilter()
fid0 := api.NewPendingTransactionFilter(nil)
time.Sleep(1 * time.Second)
backend.txFeed.Send(core.NewTxsEvent{Txs: transactions})
@@ -271,7 +273,64 @@ func TestPendingTxFilter(t *testing.T) {
t.Fatalf("Unable to retrieve logs: %v", err)
}
tx := results.([]*types.Transaction)
h := results.([]common.Hash)
hashes = append(hashes, h...)
if len(hashes) >= len(transactions) {
break
}
// check timeout
if time.Now().After(timeout) {
break
}
time.Sleep(100 * time.Millisecond)
}
if len(hashes) != len(transactions) {
t.Errorf("invalid number of transactions, want %d transactions(s), got %d", len(transactions), len(hashes))
return
}
for i := range hashes {
if hashes[i] != transactions[i].Hash() {
t.Errorf("hashes[%d] invalid, want %x, got %x", i, transactions[i].Hash(), hashes[i])
}
}
}
// TestPendingTxFilterFullTx tests whether pending tx filters retrieve all pending transactions that are posted to the event mux.
func TestPendingTxFilterFullTx(t *testing.T) {
t.Parallel()
var (
db = rawdb.NewMemoryDatabase()
backend, sys = newTestFilterSystem(t, db, Config{})
api = NewFilterAPI(sys, false)
transactions = []*types.Transaction{
types.NewTransaction(0, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
types.NewTransaction(1, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
types.NewTransaction(2, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
types.NewTransaction(3, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
types.NewTransaction(4, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
}
txs []*ethapi.RPCTransaction
)
fullTx := true
fid0 := api.NewPendingTransactionFilter(&fullTx)
time.Sleep(1 * time.Second)
backend.txFeed.Send(core.NewTxsEvent{Txs: transactions})
timeout := time.Now().Add(1 * time.Second)
for {
results, err := api.GetFilterChanges(fid0)
if err != nil {
t.Fatalf("Unable to retrieve logs: %v", err)
}
tx := results.([]*ethapi.RPCTransaction)
txs = append(txs, tx...)
if len(txs) >= len(transactions) {
break
@@ -289,8 +348,8 @@ func TestPendingTxFilter(t *testing.T) {
return
}
for i := range txs {
if txs[i].Hash() != transactions[i].Hash() {
t.Errorf("hashes[%d] invalid, want %x, got %x", i, transactions[i].Hash(), txs[i].Hash())
if txs[i].Hash != transactions[i].Hash() {
t.Errorf("hashes[%d] invalid, want %x, got %x", i, transactions[i].Hash(), txs[i].Hash)
}
}
}
@@ -854,15 +913,15 @@ func TestPendingTxFilterDeadlock(t *testing.T) {
// timeout either in 100ms or 200ms
fids := make([]rpc.ID, 20)
for i := 0; i < len(fids); i++ {
fid := api.NewPendingTransactionFilter()
fid := api.NewPendingTransactionFilter(nil)
fids[i] = fid
// Wait for at least one tx to arrive in filter
for {
txs, err := api.GetFilterChanges(fid)
hashes, err := api.GetFilterChanges(fid)
if err != nil {
t.Fatalf("Filter should exist: %v\n", err)
}
if len(txs.([]*types.Transaction)) > 0 {
if len(hashes.([]common.Hash)) > 0 {
break
}
runtime.Gosched()

View File

@@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/light"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
@@ -464,7 +465,7 @@ func ServiceGetByteCodesQuery(chain *core.BlockChain, req *GetByteCodesPacket) [
bytes uint64
)
for _, hash := range req.Hashes {
if hash == emptyCode {
if hash == types.EmptyCodeHash {
// Peers should not request the empty code, but if they do, at
// least sent them back a correct response without db lookups
codes = append(codes, []byte{})

View File

@@ -46,14 +46,6 @@ import (
"golang.org/x/crypto/sha3"
)
var (
// emptyRoot is the known root hash of an empty trie.
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
// emptyCode is the known hash of the empty EVM bytecode.
emptyCode = crypto.Keccak256Hash(nil)
)
const (
// minRequestSize is the minimum number of bytes to request from a remote peer.
// This number is used as the low cap for account and storage range requests.
@@ -1833,7 +1825,7 @@ func (s *Syncer) processAccountResponse(res *accountResponse) {
res.task.pend = 0
for i, account := range res.accounts {
// Check if the account is a contract with an unknown code
if !bytes.Equal(account.CodeHash, emptyCode[:]) {
if !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) {
if !rawdb.HasCodeWithPrefix(s.db, common.BytesToHash(account.CodeHash)) {
res.task.codeTasks[common.BytesToHash(account.CodeHash)] = struct{}{}
res.task.needCode[i] = true
@@ -1841,7 +1833,7 @@ func (s *Syncer) processAccountResponse(res *accountResponse) {
}
}
// Check if the account is a contract with an unknown storage trie
if account.Root != emptyRoot {
if account.Root != types.EmptyRootHash {
if !rawdb.HasTrieNode(s.db, res.hashes[i], nil, account.Root, s.scheme) {
// If there was a previous large state retrieval in progress,
// don't restart it from scratch. This happens if a sync cycle

View File

@@ -1354,7 +1354,7 @@ func getCodeHash(i uint64) []byte {
// getCodeByHash convenience function to lookup the code from the code hash
func getCodeByHash(hash common.Hash) []byte {
if hash == emptyCode {
if hash == types.EmptyCodeHash {
return nil
}
for i, h := range codehashes {
@@ -1376,7 +1376,7 @@ func makeAccountTrieNoStorage(n int) (string, *trie.Trie, entrySlice) {
value, _ := rlp.EncodeToBytes(&types.StateAccount{
Nonce: i,
Balance: big.NewInt(int64(i)),
Root: emptyRoot,
Root: types.EmptyRootHash,
CodeHash: getCodeHash(i),
})
key := key32(i)
@@ -1427,7 +1427,7 @@ func makeBoundaryAccountTrie(n int) (string, *trie.Trie, entrySlice) {
value, _ := rlp.EncodeToBytes(&types.StateAccount{
Nonce: uint64(0),
Balance: big.NewInt(int64(i)),
Root: emptyRoot,
Root: types.EmptyRootHash,
CodeHash: getCodeHash(uint64(i)),
})
elem := &kv{boundaries[i].Bytes(), value}
@@ -1439,7 +1439,7 @@ func makeBoundaryAccountTrie(n int) (string, *trie.Trie, entrySlice) {
value, _ := rlp.EncodeToBytes(&types.StateAccount{
Nonce: i,
Balance: big.NewInt(int64(i)),
Root: emptyRoot,
Root: types.EmptyRootHash,
CodeHash: getCodeHash(i),
})
elem := &kv{key32(i), value}
@@ -1472,7 +1472,7 @@ func makeAccountTrieWithStorageWithUniqueStorage(accounts, slots int, code bool)
// Create n accounts in the trie
for i := uint64(1); i <= uint64(accounts); i++ {
key := key32(i)
codehash := emptyCode[:]
codehash := types.EmptyCodeHash.Bytes()
if code {
codehash = getCodeHash(i)
}
@@ -1527,7 +1527,7 @@ func makeAccountTrieWithStorage(accounts, slots int, code, boundary bool) (strin
// Create n accounts in the trie
for i := uint64(1); i <= uint64(accounts); i++ {
key := key32(i)
codehash := emptyCode[:]
codehash := types.EmptyCodeHash.Bytes()
if code {
codehash = getCodeHash(i)
}
@@ -1678,7 +1678,7 @@ func verifyTrie(db ethdb.KeyValueStore, root common.Hash, t *testing.T) {
log.Crit("Invalid account encountered during snapshot creation", "err", err)
}
accounts++
if acc.Root != emptyRoot {
if acc.Root != types.EmptyRootHash {
id := trie.StorageTrieID(root, common.BytesToHash(accIt.Key), acc.Root)
storeTrie, err := trie.NewStateTrie(id, triedb)
if err != nil {

View File

@@ -131,10 +131,10 @@ func (ec *Client) getBlock(ctx context.Context, method string, args ...interface
if head.UncleHash != types.EmptyUncleHash && len(body.UncleHashes) == 0 {
return nil, fmt.Errorf("server returned empty uncle list but block header indicates uncles")
}
if head.TxHash == types.EmptyRootHash && len(body.Transactions) > 0 {
if head.TxHash == types.EmptyTxsHash && len(body.Transactions) > 0 {
return nil, fmt.Errorf("server returned non-empty transaction list but block header indicates no transactions")
}
if head.TxHash != types.EmptyRootHash && len(body.Transactions) == 0 {
if head.TxHash != types.EmptyTxsHash && len(body.Transactions) == 0 {
return nil, fmt.Errorf("server returned empty transaction list but block header indicates transactions")
}
// Load uncles because they are not included in the block response.

View File

@@ -18,7 +18,7 @@ package dbtest
import (
"bytes"
"math/rand"
"crypto/rand"
"reflect"
"sort"
"testing"

View File

@@ -100,7 +100,6 @@ func TestSubscribeDuplicateType(t *testing.T) {
}
func TestMuxConcurrent(t *testing.T) {
rand.Seed(time.Now().Unix())
mux := new(TypeMux)
defer mux.Stop()

View File

@@ -18,6 +18,7 @@ package les
import (
"context"
crand "crypto/rand"
"errors"
"flag"
"math/rand"
@@ -326,7 +327,7 @@ func getHead(ctx context.Context, t *testing.T, client *rpc.Client) (uint64, com
func testRequest(ctx context.Context, t *testing.T, client *rpc.Client) bool {
var res string
var addr common.Address
rand.Read(addr[:])
crand.Read(addr[:])
c, cancel := context.WithTimeout(ctx, time.Second*12)
defer cancel()
err := client.CallContext(c, &res, "eth_getBalance", addr, "latest")

View File

@@ -17,6 +17,7 @@
package les
import (
crand "crypto/rand"
"encoding/binary"
"fmt"
"math/big"
@@ -114,7 +115,7 @@ func (b *benchmarkProofsOrCode) init(h *serverHandler, count int) error {
func (b *benchmarkProofsOrCode) request(peer *serverPeer, index int) error {
key := make([]byte, 32)
rand.Read(key)
crand.Read(key)
if b.code {
return peer.requestCode(0, []CodeReq{{BHash: b.headHash, AccKey: key}})
}
@@ -176,7 +177,7 @@ func (b *benchmarkTxSend) init(h *serverHandler, count int) error {
for i := range b.txs {
data := make([]byte, txSizeCostLimit)
rand.Read(data)
crand.Read(data)
tx, err := types.SignTx(types.NewTransaction(0, addr, new(big.Int), 0, new(big.Int), data), signer, key)
if err != nil {
panic(err)
@@ -200,7 +201,7 @@ func (b *benchmarkTxStatus) init(h *serverHandler, count int) error {
func (b *benchmarkTxStatus) request(peer *serverPeer, index int) error {
var hash common.Hash
rand.Read(hash[:])
crand.Read(hash[:])
return peer.requestTxStatus(0, []common.Hash{hash})
}
@@ -278,7 +279,7 @@ func (h *serverHandler) measure(setup *benchmarkSetup, count int) error {
clientMeteredPipe := &meteredPipe{rw: clientPipe}
serverMeteredPipe := &meteredPipe{rw: serverPipe}
var id enode.ID
rand.Read(id[:])
crand.Read(id[:])
peer1 := newServerPeer(lpv2, NetworkId, false, p2p.NewPeer(id, "client", nil), clientMeteredPipe)
peer2 := newClientPeer(lpv2, NetworkId, p2p.NewPeer(id, "server", nil), serverMeteredPipe)

View File

@@ -548,7 +548,7 @@ func (f *BlockFetcher) loop() {
announce.time = task.time
// If the block is empty (header only), short circuit into the final import queue
if header.TxHash == types.EmptyRootHash && header.UncleHash == types.EmptyUncleHash {
if header.TxHash == types.EmptyTxsHash && header.UncleHash == types.EmptyUncleHash {
log.Trace("Block empty, skipping body retrieval", "peer", announce.origin, "number", header.Number, "hash", header.Hash())
block := types.NewBlockWithHeader(header)

View File

@@ -348,7 +348,7 @@ func handleGetReceipts(msg Decoder) (serveRequestFn, uint64, uint64, error) {
// Retrieve the requested block's receipts, skipping if unknown to us
results := bc.GetReceiptsByHash(hash)
if results == nil {
if header := bc.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyRootHash {
if header := bc.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyReceiptsHash {
p.bumpInvalid()
continue
}

View File

@@ -17,7 +17,7 @@
package utils
import (
"math/rand"
"crypto/rand"
"testing"
"github.com/ethereum/go-ethereum/p2p/enode"

View File

@@ -17,7 +17,7 @@
package client
import (
"math/rand"
"crypto/rand"
"testing"
"time"

View File

@@ -135,7 +135,6 @@ func alwaysTrueFn() bool {
}
func testClientPool(t *testing.T, activeLimit, clientCount, paidCount int, randomDisconnect bool) {
rand.Seed(time.Now().UnixNano())
var (
clock mclock.Simulated
db = rawdb.NewMemoryDatabase()

View File

@@ -253,8 +253,8 @@ func makeHeaderChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.
Number: big.NewInt(int64(i + 1)),
Difficulty: big.NewInt(int64(difficulty)),
UncleHash: types.EmptyUncleHash,
TxHash: types.EmptyRootHash,
ReceiptHash: types.EmptyRootHash,
TxHash: types.EmptyTxsHash,
ReceiptHash: types.EmptyReceiptsHash,
}
if i == 0 {
header.ParentHash = genesis.Hash()

View File

@@ -41,6 +41,7 @@ type ExpDecaySample struct {
reservoirSize int
t0, t1 time.Time
values *expDecaySampleHeap
rand *rand.Rand
}
// NewExpDecaySample constructs a new exponentially-decaying sample with the
@@ -59,6 +60,12 @@ func NewExpDecaySample(reservoirSize int, alpha float64) Sample {
return s
}
// SetRand sets the random source (useful in tests)
func (s *ExpDecaySample) SetRand(prng *rand.Rand) Sample {
s.rand = prng
return s
}
// Clear clears all samples.
func (s *ExpDecaySample) Clear() {
s.mutex.Lock()
@@ -168,8 +175,14 @@ func (s *ExpDecaySample) update(t time.Time, v int64) {
if s.values.Size() == s.reservoirSize {
s.values.Pop()
}
var f64 float64
if s.rand != nil {
f64 = s.rand.Float64()
} else {
f64 = rand.Float64()
}
s.values.Push(expDecaySample{
k: math.Exp(t.Sub(s.t0).Seconds()*s.alpha) / rand.Float64(),
k: math.Exp(t.Sub(s.t0).Seconds()*s.alpha) / f64,
v: v,
})
if t.After(s.t1) {
@@ -402,6 +415,7 @@ type UniformSample struct {
mutex sync.Mutex
reservoirSize int
values []int64
rand *rand.Rand
}
// NewUniformSample constructs a new uniform sample with the given reservoir
@@ -416,6 +430,12 @@ func NewUniformSample(reservoirSize int) Sample {
}
}
// SetRand sets the random source (useful in tests)
func (s *UniformSample) SetRand(prng *rand.Rand) Sample {
s.rand = prng
return s
}
// Clear clears all samples.
func (s *UniformSample) Clear() {
s.mutex.Lock()
@@ -511,7 +531,12 @@ func (s *UniformSample) Update(v int64) {
if len(s.values) < s.reservoirSize {
s.values = append(s.values, v)
} else {
r := rand.Int63n(s.count)
var r int64
if s.rand != nil {
r = s.rand.Int63n(s.count)
} else {
r = rand.Int63n(s.count)
}
if r < int64(len(s.values)) {
s.values[int(r)] = v
}

View File

@@ -80,7 +80,6 @@ func BenchmarkUniformSample1028(b *testing.B) {
}
func TestExpDecaySample10(t *testing.T) {
rand.Seed(1)
s := NewExpDecaySample(100, 0.99)
for i := 0; i < 10; i++ {
s.Update(int64(i))
@@ -102,7 +101,6 @@ func TestExpDecaySample10(t *testing.T) {
}
func TestExpDecaySample100(t *testing.T) {
rand.Seed(1)
s := NewExpDecaySample(1000, 0.01)
for i := 0; i < 100; i++ {
s.Update(int64(i))
@@ -124,7 +122,6 @@ func TestExpDecaySample100(t *testing.T) {
}
func TestExpDecaySample1000(t *testing.T) {
rand.Seed(1)
s := NewExpDecaySample(100, 0.99)
for i := 0; i < 1000; i++ {
s.Update(int64(i))
@@ -150,7 +147,6 @@ func TestExpDecaySample1000(t *testing.T) {
// The priority becomes +Inf quickly after starting if this is done,
// effectively freezing the set of samples until a rescale step happens.
func TestExpDecaySampleNanosecondRegression(t *testing.T) {
rand.Seed(1)
s := NewExpDecaySample(100, 0.99)
for i := 0; i < 100; i++ {
s.Update(10)
@@ -183,8 +179,7 @@ func TestExpDecaySampleRescale(t *testing.T) {
func TestExpDecaySampleSnapshot(t *testing.T) {
now := time.Now()
rand.Seed(1)
s := NewExpDecaySample(100, 0.99)
s := NewExpDecaySample(100, 0.99).(*ExpDecaySample).SetRand(rand.New(rand.NewSource(1)))
for i := 1; i <= 10000; i++ {
s.(*ExpDecaySample).update(now.Add(time.Duration(i)), int64(i))
}
@@ -195,8 +190,7 @@ func TestExpDecaySampleSnapshot(t *testing.T) {
func TestExpDecaySampleStatistics(t *testing.T) {
now := time.Now()
rand.Seed(1)
s := NewExpDecaySample(100, 0.99)
s := NewExpDecaySample(100, 0.99).(*ExpDecaySample).SetRand(rand.New(rand.NewSource(1)))
for i := 1; i <= 10000; i++ {
s.(*ExpDecaySample).update(now.Add(time.Duration(i)), int64(i))
}
@@ -204,7 +198,6 @@ func TestExpDecaySampleStatistics(t *testing.T) {
}
func TestUniformSample(t *testing.T) {
rand.Seed(1)
s := NewUniformSample(100)
for i := 0; i < 1000; i++ {
s.Update(int64(i))
@@ -226,7 +219,6 @@ func TestUniformSample(t *testing.T) {
}
func TestUniformSampleIncludesTail(t *testing.T) {
rand.Seed(1)
s := NewUniformSample(100)
max := 100
for i := 0; i < max; i++ {
@@ -244,7 +236,7 @@ func TestUniformSampleIncludesTail(t *testing.T) {
}
func TestUniformSampleSnapshot(t *testing.T) {
s := NewUniformSample(100)
s := NewUniformSample(100).(*UniformSample).SetRand(rand.New(rand.NewSource(1)))
for i := 1; i <= 10000; i++ {
s.Update(int64(i))
}
@@ -254,8 +246,7 @@ func TestUniformSampleSnapshot(t *testing.T) {
}
func TestUniformSampleStatistics(t *testing.T) {
rand.Seed(1)
s := NewUniformSample(100)
s := NewUniformSample(100).(*UniformSample).SetRand(rand.New(rand.NewSource(1)))
for i := 1; i <= 10000; i++ {
s.Update(int64(i))
}

View File

@@ -19,6 +19,7 @@ package main
import (
"crypto/ecdsa"
crand "crypto/rand"
"math/big"
"math/rand"
"os"
@@ -162,7 +163,7 @@ func makeTransaction(nonce uint64, privKey *ecdsa.PrivateKey, signer types.Signe
// Feecap and feetip are limited to 32 bytes. Offer a sightly
// larger buffer for creating both valid and invalid transactions.
var buf = make([]byte, 32+5)
rand.Read(buf)
crand.Read(buf)
gasTipCap := new(big.Int).SetBytes(buf)
// If the given base fee is nil(the 1559 is still not available),
@@ -173,7 +174,7 @@ func makeTransaction(nonce uint64, privKey *ecdsa.PrivateKey, signer types.Signe
// Generate the feecap, 75% valid feecap and 25% unguaranteed.
var gasFeeCap *big.Int
if rand.Intn(4) == 0 {
rand.Read(buf)
crand.Read(buf)
gasFeeCap = new(big.Int).SetBytes(buf)
} else {
gasFeeCap = new(big.Int).Add(baseFee, gasTipCap)

View File

@@ -17,9 +17,9 @@
package miner
import (
"crypto/rand"
"errors"
"math/big"
"math/rand"
"sync/atomic"
"testing"
"time"
@@ -105,8 +105,6 @@ func init() {
GasPrice: big.NewInt(params.InitialBaseFee),
})
newTxs = append(newTxs, tx2)
rand.Seed(time.Now().UnixNano())
}
// testWorkerBackend implements worker.Backend interfaces and wraps all information needed during the testing.

View File

@@ -165,7 +165,6 @@ func TestUDPv4_responseTimeouts(t *testing.T) {
test := newUDPTest(t)
defer test.close()
rand.Seed(time.Now().UnixNano())
randomDuration := func(max time.Duration) time.Duration {
return time.Duration(rand.Int63n(int64(max)))
}

View File

@@ -17,7 +17,7 @@
package enode
import (
"math/rand"
"crypto/rand"
"net"
"testing"

View File

@@ -17,8 +17,8 @@
package netutil
import (
crand "crypto/rand"
"fmt"
mrand "math/rand"
"testing"
"time"
@@ -123,8 +123,8 @@ func TestIPTrackerForceGC(t *testing.T) {
for i := 0; i < 5*max; i++ {
e1 := make([]byte, 4)
e2 := make([]byte, 4)
mrand.Read(e1)
mrand.Read(e2)
crand.Read(e1)
crand.Read(e2)
it.AddStatement(string(e1), string(e2))
it.AddContact(string(e1))
clock.Run(rate)

View File

@@ -23,7 +23,7 @@ import (
const (
VersionMajor = 1 // Major version component of the current release
VersionMinor = 11 // Minor version component of the current release
VersionPatch = 0 // Patch version component of the current release
VersionPatch = 2 // Patch version component of the current release
VersionMeta = "stable" // Version metadata to append to the version string
)

View File

@@ -345,7 +345,10 @@ func (c *Client) CallContext(ctx context.Context, result interface{}, method str
case len(resp.Result) == 0:
return ErrNoResult
default:
return json.Unmarshal(resp.Result, &result)
if result == nil {
return nil
}
return json.Unmarshal(resp.Result, result)
}
}

View File

@@ -69,6 +69,26 @@ func TestClientResponseType(t *testing.T) {
}
}
// This test checks calling a method that returns 'null'.
func TestClientNullResponse(t *testing.T) {
server := newTestServer()
defer server.Stop()
client := DialInProc(server)
defer client.Close()
var result json.RawMessage
if err := client.Call(&result, "test_null"); err != nil {
t.Fatal(err)
}
if result == nil {
t.Fatal("Expected non-nil result")
}
if !reflect.DeepEqual(result, json.RawMessage("null")) {
t.Errorf("Expected null, got %s", result)
}
}
// This test checks that server-returned errors with code and data come out of Client.Call.
func TestClientErrorData(t *testing.T) {
server := newTestServer()

View File

@@ -45,7 +45,7 @@ func TestServerRegisterName(t *testing.T) {
t.Fatalf("Expected service calc to be registered")
}
wantCallbacks := 12
wantCallbacks := 13
if len(svc.callbacks) != wantCallbacks {
t.Errorf("Expected %d callbacks for service 'service', got %d", wantCallbacks, len(svc.callbacks))
}

View File

@@ -78,6 +78,10 @@ func (o *MarshalErrObj) MarshalText() ([]byte, error) {
func (s *testService) NoArgsRets() {}
func (s *testService) Null() any {
return nil
}
func (s *testService) Echo(str string, i int, args *echoArgs) echoResult {
return echoResult{str, i, args}
}

View File

@@ -808,7 +808,7 @@ func (db *Database) Update(nodes *MergedNodeSet) error {
if err := rlp.DecodeBytes(n.blob, &account); err != nil {
return err
}
if account.Root != emptyRoot {
if account.Root != types.EmptyRootHash {
db.reference(account.Root, n.parent)
}
}

View File

@@ -18,6 +18,7 @@ package trie
import (
"bytes"
crand "crypto/rand"
"encoding/hex"
"math/rand"
"testing"
@@ -97,7 +98,7 @@ func TestHexToCompactInPlaceRandom(t *testing.T) {
for i := 0; i < 10000; i++ {
l := rand.Intn(128)
key := make([]byte, l)
rand.Read(key)
crand.Read(key)
hexBytes := keybytesToHex(key)
hexOrig := []byte(string(hexBytes))
exp := hexToCompact(hexBytes)

View File

@@ -22,6 +22,7 @@ import (
"errors"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
)
// NodeResolver is used for looking up trie nodes before reaching into the real
@@ -160,7 +161,7 @@ func (e seekError) Error() string {
}
func newNodeIterator(trie *Trie, start []byte) NodeIterator {
if trie.Hash() == emptyRoot {
if trie.Hash() == types.EmptyRootHash {
return &nodeIterator{
trie: trie,
err: errIteratorEnd,
@@ -302,7 +303,7 @@ func (it *nodeIterator) seek(prefix []byte) error {
func (it *nodeIterator) init() (*nodeIteratorState, error) {
root := it.trie.Hash()
state := &nodeIteratorState{node: it.trie.root, index: -1}
if root != emptyRoot {
if root != types.EmptyRootHash {
state.hash = root
}
return state, state.resolve(it, nil)

View File

@@ -23,7 +23,6 @@ import (
mrand "math/rand"
"sort"
"testing"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
@@ -31,10 +30,6 @@ import (
"github.com/ethereum/go-ethereum/ethdb/memorydb"
)
func init() {
mrand.Seed(time.Now().Unix())
}
// makeProvers creates Merkle trie provers based on different implementations to
// test all variations.
func makeProvers(trie *Trie) []func(key []byte) *memorydb.Database {

View File

@@ -25,6 +25,7 @@ import (
"sync"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
)
@@ -407,7 +408,7 @@ func (st *StackTrie) hashRec(hasher *hasher, path []byte) {
return
case emptyNode:
st.val = emptyRoot.Bytes()
st.val = types.EmptyRootHash.Bytes()
st.key = st.key[:0]
st.nodeType = hashedNode
return

View File

@@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/prque"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
)
@@ -184,7 +185,7 @@ func NewSync(root common.Hash, database ethdb.KeyValueReader, callback LeafCallb
// hex format and contain all the parent path if it's layered trie node.
func (s *Sync) AddSubTrie(root common.Hash, path []byte, parent common.Hash, parentPath []byte, callback LeafCallback) {
// Short circuit if the trie is empty or already known
if root == emptyRoot {
if root == types.EmptyRootHash {
return
}
if s.membatch.hasNode(path) {
@@ -217,7 +218,7 @@ func (s *Sync) AddSubTrie(root common.Hash, path []byte, parent common.Hash, par
// as is.
func (s *Sync) AddCodeEntry(hash common.Hash, path []byte, parent common.Hash, parentPath []byte) {
// Short circuit if the entry is empty or already known
if hash == emptyState {
if hash == types.EmptyCodeHash {
return
}
if s.membatch.hasCode(hash) {

View File

@@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb/memorydb"
)
@@ -104,7 +105,7 @@ func TestEmptySync(t *testing.T) {
dbA := NewDatabase(rawdb.NewMemoryDatabase())
dbB := NewDatabase(rawdb.NewMemoryDatabase())
emptyA, _ := New(TrieID(common.Hash{}), dbA)
emptyB, _ := New(TrieID(emptyRoot), dbB)
emptyB, _ := New(TrieID(types.EmptyRootHash), dbB)
for i, trie := range []*Trie{emptyA, emptyB} {
sync := NewSync(trie.Hash(), memorydb.New(), nil, []*Database{dbA, dbB}[i].Scheme())

View File

@@ -23,18 +23,10 @@ import (
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
)
var (
// emptyRoot is the known root hash of an empty trie.
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
// emptyState is the known hash of an empty state trie entry.
emptyState = crypto.Keccak256Hash(nil)
)
// Trie is a Merkle Patricia Trie. Use New to create a trie that sits on
// top of a database. Whenever trie performs a commit operation, the generated
// nodes will be gathered and returned in a set. Once the trie is committed,
@@ -91,7 +83,7 @@ func New(id *ID, db NodeReader) (*Trie, error) {
reader: reader,
//tracer: newTracer(),
}
if id.Root != (common.Hash{}) && id.Root != emptyRoot {
if id.Root != (common.Hash{}) && id.Root != types.EmptyRootHash {
rootnode, err := trie.resolveAndTrack(id.Root[:], nil)
if err != nil {
return nil, err
@@ -576,7 +568,7 @@ func (t *Trie) Commit(collectLeaf bool) (common.Hash, *NodeSet) {
// Wrap tracked deletions as the return
set := NewNodeSet(t.owner)
t.tracer.markDeletions(set)
return emptyRoot, set
return types.EmptyRootHash, set
}
// Derive the hash for all dirty nodes first. We hold the assumption
// in the following procedure that all nodes are hashed.
@@ -599,7 +591,7 @@ func (t *Trie) Commit(collectLeaf bool) (common.Hash, *NodeSet) {
// hashRoot calculates the root hash of the given trie
func (t *Trie) hashRoot() (node, node, error) {
if t.root == nil {
return hashNode(emptyRoot.Bytes()), nil, nil
return hashNode(types.EmptyRootHash.Bytes()), nil, nil
}
// If the number of changes is below 100, we let one thread handle it
h := newHasher(t.unhashed >= 100)

View File

@@ -18,6 +18,7 @@ package trie
import (
"bytes"
crand "crypto/rand"
"encoding/binary"
"errors"
"fmt"
@@ -46,7 +47,7 @@ func init() {
func TestEmptyTrie(t *testing.T) {
trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
res := trie.Hash()
exp := emptyRoot
exp := types.EmptyRootHash
if res != exp {
t.Errorf("expected %x got %x", exp, res)
}
@@ -430,7 +431,7 @@ func runRandTest(rt randTest) bool {
}
case opProve:
hash := tr.Hash()
if hash == emptyRoot {
if hash == types.EmptyRootHash {
continue
}
proofDb := rawdb.NewMemoryDatabase()
@@ -717,7 +718,7 @@ func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) {
for i := 0; i < len(accounts); i++ {
var (
nonce = uint64(random.Int63())
root = emptyRoot
root = types.EmptyRootHash
code = crypto.Keccak256(nil)
)
// The big.Rand function is not deterministic with regards to 64 vs 32 bit systems,
@@ -1127,8 +1128,8 @@ func TestDecodeNode(t *testing.T) {
elems = make([]byte, 20)
)
for i := 0; i < 5000000; i++ {
rand.Read(hash)
rand.Read(elems)
crand.Read(hash)
crand.Read(elems)
decodeNode(hash, elems)
}
}

View File

@@ -22,6 +22,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
)
// Tests if the trie diffs are tracked correctly.
@@ -286,7 +287,7 @@ func TestDeleteAll(t *testing.T) {
trie.Delete([]byte(val.k))
}
root, set = trie.Commit(false)
if root != emptyRoot {
if root != types.EmptyRootHash {
t.Fatalf("Invalid trie root %v", root)
}
for path, blob := range set.deletes {