Merge branch 'master' into clean-shutdown

This commit is contained in:
Eugene 2025-06-18 10:30:04 -07:00 committed by GitHub
commit 8b2b0afe7c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
51 changed files with 588 additions and 306 deletions

View file

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

View file

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

View file

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

View file

@ -667,7 +667,6 @@ func SafeDeleteRange(db ethdb.KeyValueStore, start, end []byte, hashScheme bool,
var ( var (
count, deleted, skipped int count, deleted, skipped int
buff = crypto.NewKeccakState()
startTime = time.Now() startTime = time.Now()
) )
@ -680,7 +679,7 @@ func SafeDeleteRange(db ethdb.KeyValueStore, start, end []byte, hashScheme bool,
for it.Next() && bytes.Compare(end, it.Key()) > 0 { for it.Next() && bytes.Compare(end, it.Key()) > 0 {
// Prevent deletion for trie nodes in hash mode // Prevent deletion for trie nodes in hash mode
if len(it.Key()) != 32 || crypto.HashData(buff, it.Value()) != common.BytesToHash(it.Key()) { if len(it.Key()) != 32 || crypto.Keccak256Hash(it.Value()) != common.BytesToHash(it.Key()) {
if err := batch.Delete(it.Key()); err != nil { if err := batch.Delete(it.Key()); err != nil {
return err return err
} }

View file

@ -1,17 +0,0 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package rawdb

View file

@ -182,7 +182,11 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []
log.Error("Failed to decode the value returned by iterator", "error", err) log.Error("Failed to decode the value returned by iterator", "error", err)
continue continue
} }
account.Storage[common.BytesToHash(s.trie.GetKey(storageIt.Key))] = common.Bytes2Hex(content) key := s.trie.GetKey(storageIt.Key)
if key == nil {
continue
}
account.Storage[common.BytesToHash(key)] = common.Bytes2Hex(content)
} }
} }
c.OnAccount(address, account) c.OnAccount(address, account)

View file

@ -206,7 +206,6 @@ func (r *flatReader) Storage(addr common.Address, key common.Hash) (common.Hash,
type trieReader struct { type trieReader struct {
root common.Hash // State root which uniquely represent a state root common.Hash // State root which uniquely represent a state
db *triedb.Database // Database for loading trie db *triedb.Database // Database for loading trie
buff crypto.KeccakState // Buffer for keccak256 hashing
// Main trie, resolved in constructor. Note either the Merkle-Patricia-tree // Main trie, resolved in constructor. Note either the Merkle-Patricia-tree
// or Verkle-tree is not safe for concurrent read. // or Verkle-tree is not safe for concurrent read.
@ -235,7 +234,6 @@ func newTrieReader(root common.Hash, db *triedb.Database, cache *utils.PointCach
return &trieReader{ return &trieReader{
root: root, root: root,
db: db, db: db,
buff: crypto.NewKeccakState(),
mainTrie: tr, mainTrie: tr,
subRoots: make(map[common.Address]common.Hash), subRoots: make(map[common.Address]common.Hash),
subTries: make(map[common.Address]Trie), subTries: make(map[common.Address]Trie),
@ -298,7 +296,7 @@ func (r *trieReader) Storage(addr common.Address, key common.Hash) (common.Hash,
root = r.subRoots[addr] root = r.subRoots[addr]
} }
var err error var err error
tr, err = trie.NewStateTrie(trie.StorageTrieID(r.root, crypto.HashData(r.buff, addr.Bytes()), root), r.db) tr, err = trie.NewStateTrie(trie.StorageTrieID(r.root, crypto.Keccak256Hash(addr.Bytes()), root), r.db)
if err != nil { if err != nil {
return common.Hash{}, err return common.Hash{}, err
} }

View file

@ -377,7 +377,6 @@ func (s *stateObject) updateRoot() {
// fulfills the storage diffs into the given accountUpdate struct. // fulfills the storage diffs into the given accountUpdate struct.
func (s *stateObject) commitStorage(op *accountUpdate) { func (s *stateObject) commitStorage(op *accountUpdate) {
var ( var (
buf = crypto.NewKeccakState()
encode = func(val common.Hash) []byte { encode = func(val common.Hash) []byte {
if val == (common.Hash{}) { if val == (common.Hash{}) {
return nil return nil
@ -394,7 +393,7 @@ func (s *stateObject) commitStorage(op *accountUpdate) {
if val == s.originStorage[key] { if val == s.originStorage[key] {
continue continue
} }
hash := crypto.HashData(buf, key[:]) hash := crypto.Keccak256Hash(key[:])
if op.storages == nil { if op.storages == nil {
op.storages = make(map[common.Hash][]byte) op.storages = make(map[common.Hash][]byte)
} }

View file

@ -1064,7 +1064,6 @@ func (s *StateDB) deleteStorage(addr common.Address, addrHash common.Hash, root
func (s *StateDB) handleDestruction(noStorageWiping bool) (map[common.Hash]*accountDelete, []*trienode.NodeSet, error) { func (s *StateDB) handleDestruction(noStorageWiping bool) (map[common.Hash]*accountDelete, []*trienode.NodeSet, error) {
var ( var (
nodes []*trienode.NodeSet nodes []*trienode.NodeSet
buf = crypto.NewKeccakState()
deletes = make(map[common.Hash]*accountDelete) deletes = make(map[common.Hash]*accountDelete)
) )
for addr, prevObj := range s.stateObjectsDestruct { for addr, prevObj := range s.stateObjectsDestruct {
@ -1079,7 +1078,7 @@ func (s *StateDB) handleDestruction(noStorageWiping bool) (map[common.Hash]*acco
continue continue
} }
// The account was existent, it can be either case (c) or (d). // The account was existent, it can be either case (c) or (d).
addrHash := crypto.HashData(buf, addr.Bytes()) addrHash := crypto.Keccak256Hash(addr.Bytes())
op := &accountDelete{ op := &accountDelete{
address: addr, address: addr,
origin: types.SlimAccountRLP(*prev), origin: types.SlimAccountRLP(*prev),

View file

@ -459,6 +459,8 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 {
minPrice = 500 minPrice = 500
if maxLenOver32 { if maxLenOver32 {
gas.Add(gas, gas) gas.Add(gas, gas)
} else {
gas = big.NewInt(16)
} }
} }

View file

@ -1,3 +1,7 @@
// mul multiplies two 256-bit numbers in little-endian order.
// The inputs are (R1,R2,R3,R4) times (R5,R6,R7,R8)
// and the product is stored in (c0,c1,c2,c3,c4,c5,c6,c7).
// Note that the input registers (R1,R2,R3) are overwritten.
#define mul(c0,c1,c2,c3,c4,c5,c6,c7) \ #define mul(c0,c1,c2,c3,c4,c5,c6,c7) \
MUL R1, R5, c0 \ MUL R1, R5, c0 \
UMULH R1, R5, c1 \ UMULH R1, R5, c1 \
@ -16,54 +20,54 @@
UMULH R2, R5, R26 \ UMULH R2, R5, R26 \
MUL R2, R6, R0 \ MUL R2, R6, R0 \
ADDS R0, R26 \ ADDS R0, R26 \
UMULH R2, R6, R27 \ UMULH R2, R6, c6 \
MUL R2, R7, R0 \ MUL R2, R7, R0 \
ADCS R0, R27 \ ADCS R0, c6 \
UMULH R2, R7, R29 \ UMULH R2, R7, c7 \
MUL R2, R8, R0 \ MUL R2, R8, R0 \
ADCS R0, R29 \ ADCS R0, c7 \
UMULH R2, R8, c5 \ UMULH R2, R8, c5 \
ADCS ZR, c5 \ ADCS ZR, c5 \
ADDS R1, c1 \ ADDS R1, c1 \
ADCS R26, c2 \ ADCS R26, c2 \
ADCS R27, c3 \ ADCS c6, c3 \
ADCS R29, c4 \ ADCS c7, c4 \
ADCS ZR, c5 \ ADCS ZR, c5 \
\ \
MUL R3, R5, R1 \ MUL R3, R5, R1 \
UMULH R3, R5, R26 \ UMULH R3, R5, R26 \
MUL R3, R6, R0 \ MUL R3, R6, R0 \
ADDS R0, R26 \ ADDS R0, R26 \
UMULH R3, R6, R27 \ UMULH R3, R6, R2 \
MUL R3, R7, R0 \ MUL R3, R7, R0 \
ADCS R0, R27 \ ADCS R0, R2 \
UMULH R3, R7, R29 \ UMULH R3, R7, c7 \
MUL R3, R8, R0 \ MUL R3, R8, R0 \
ADCS R0, R29 \ ADCS R0, c7 \
UMULH R3, R8, c6 \ UMULH R3, R8, c6 \
ADCS ZR, c6 \ ADCS ZR, c6 \
ADDS R1, c2 \ ADDS R1, c2 \
ADCS R26, c3 \ ADCS R26, c3 \
ADCS R27, c4 \ ADCS R2, c4 \
ADCS R29, c5 \ ADCS c7, c5 \
ADCS ZR, c6 \ ADCS ZR, c6 \
\ \
MUL R4, R5, R1 \ MUL R4, R5, R1 \
UMULH R4, R5, R26 \ UMULH R4, R5, R26 \
MUL R4, R6, R0 \ MUL R4, R6, R0 \
ADDS R0, R26 \ ADDS R0, R26 \
UMULH R4, R6, R27 \ UMULH R4, R6, R2 \
MUL R4, R7, R0 \ MUL R4, R7, R0 \
ADCS R0, R27 \ ADCS R0, R2 \
UMULH R4, R7, R29 \ UMULH R4, R7, R3 \
MUL R4, R8, R0 \ MUL R4, R8, R0 \
ADCS R0, R29 \ ADCS R0, R3 \
UMULH R4, R8, c7 \ UMULH R4, R8, c7 \
ADCS ZR, c7 \ ADCS ZR, c7 \
ADDS R1, c3 \ ADDS R1, c3 \
ADCS R26, c4 \ ADCS R26, c4 \
ADCS R27, c5 \ ADCS R2, c5 \
ADCS R29, c6 \ ADCS R3, c6 \
ADCS ZR, c7 ADCS ZR, c7
#define gfpReduce() \ #define gfpReduce() \

View file

@ -1,6 +1,7 @@
package bn256 package bn256
import ( import (
"errors"
"math/big" "math/big"
"github.com/consensys/gnark-crypto/ecc/bn254" "github.com/consensys/gnark-crypto/ecc/bn254"
@ -31,21 +32,62 @@ func (g *G1) ScalarMult(a *G1, scalar *big.Int) {
// Unmarshal deserializes `buf` into `g` // Unmarshal deserializes `buf` into `g`
// //
// Note: whether the deserialization is of a compressed // The input is expected to be in the EVM format:
// or an uncompressed point, is encoded in the bytes. // 64 bytes: [32-byte x coordinate][32-byte y coordinate]
// // where each coordinate is in big-endian format.
// For our purpose, the point will always be serialized
// as uncompressed, ie 64 bytes.
// //
// This method also checks whether the point is on the // This method also checks whether the point is on the
// curve and in the prime order subgroup. // curve and in the prime order subgroup.
func (g *G1) Unmarshal(buf []byte) (int, error) { func (g *G1) Unmarshal(buf []byte) (int, error) {
return g.inner.SetBytes(buf) if len(buf) < 64 {
return 0, errors.New("invalid G1 point size")
}
if allZeroes(buf[:64]) {
// point at infinity
g.inner.X.SetZero()
g.inner.Y.SetZero()
return 64, nil
}
if err := g.inner.X.SetBytesCanonical(buf[:32]); err != nil {
return 0, err
}
if err := g.inner.Y.SetBytesCanonical(buf[32:64]); err != nil {
return 0, err
}
if !g.inner.IsOnCurve() {
return 0, errors.New("point is not on curve")
}
if !g.inner.IsInSubGroup() {
return 0, errors.New("point is not in correct subgroup")
}
return 64, nil
} }
// Marshal serializes the point into a byte slice. // Marshal serializes the point into a byte slice.
// //
// Note: The point is serialized as uncompressed. // The output is in EVM format: 64 bytes total.
// [32-byte x coordinate][32-byte y coordinate]
// where each coordinate is a big-endian integer padded to 32 bytes.
func (p *G1) Marshal() []byte { func (p *G1) Marshal() []byte {
return p.inner.Marshal() output := make([]byte, 64)
xBytes := p.inner.X.Bytes()
copy(output[:32], xBytes[:])
yBytes := p.inner.Y.Bytes()
copy(output[32:64], yBytes[:])
return output
}
func allZeroes(buf []byte) bool {
for i := range buf {
if buf[i] != 0 {
return false
}
}
return true
} }

View file

@ -1,6 +1,8 @@
package bn256 package bn256
import ( import (
"errors"
"github.com/consensys/gnark-crypto/ecc/bn254" "github.com/consensys/gnark-crypto/ecc/bn254"
) )
@ -18,21 +20,66 @@ type G2 struct {
// Unmarshal deserializes `buf` into `g` // Unmarshal deserializes `buf` into `g`
// //
// Note: whether the deserialization is of a compressed // The input is expected to be in the EVM format:
// or an uncompressed point, is encoded in the bytes. // 128 bytes: [32-byte x.0][32-byte x.1][32-byte y.0][32-byte y.1]
// // where each value is a big-endian integer.
// For our purpose, the point will always be serialized
// as uncompressed, ie 128 bytes.
// //
// This method also checks whether the point is on the // This method also checks whether the point is on the
// curve and in the prime order subgroup. // curve and in the prime order subgroup.
func (g *G2) Unmarshal(buf []byte) (int, error) { func (g *G2) Unmarshal(buf []byte) (int, error) {
return g.inner.SetBytes(buf) if len(buf) < 128 {
return 0, errors.New("invalid G2 point size")
}
if allZeroes(buf[:128]) {
// point at infinity
g.inner.X.A0.SetZero()
g.inner.X.A1.SetZero()
g.inner.Y.A0.SetZero()
g.inner.Y.A1.SetZero()
return 128, nil
}
if err := g.inner.X.A0.SetBytesCanonical(buf[0:32]); err != nil {
return 0, err
}
if err := g.inner.X.A1.SetBytesCanonical(buf[32:64]); err != nil {
return 0, err
}
if err := g.inner.Y.A0.SetBytesCanonical(buf[64:96]); err != nil {
return 0, err
}
if err := g.inner.Y.A1.SetBytesCanonical(buf[96:128]); err != nil {
return 0, err
}
if !g.inner.IsOnCurve() {
return 0, errors.New("point is not on curve")
}
if !g.inner.IsInSubGroup() {
return 0, errors.New("point is not in correct subgroup")
}
return 128, nil
} }
// Marshal serializes the point into a byte slice. // Marshal serializes the point into a byte slice.
// //
// Note: The point is serialized as uncompressed. // The output is in EVM format: 128 bytes total.
// [32-byte x.0][32-byte x.1][32-byte y.0][32-byte y.1]
// where each value is a big-endian integer.
func (g *G2) Marshal() []byte { func (g *G2) Marshal() []byte {
return g.inner.Marshal() output := make([]byte, 128)
xA0Bytes := g.inner.X.A0.Bytes()
copy(output[:32], xA0Bytes[:])
xA1Bytes := g.inner.X.A1.Bytes()
copy(output[32:64], xA1Bytes[:])
yA0Bytes := g.inner.Y.A0.Bytes()
copy(output[64:96], yA0Bytes[:])
yA1Bytes := g.inner.Y.A1.Bytes()
copy(output[96:128], yA1Bytes[:])
return output
} }

View file

@ -0,0 +1,42 @@
package bn256
import (
"testing"
"github.com/consensys/gnark-crypto/ecc/bn254"
)
func TestNativeGnarkFormatIncompatibility(t *testing.T) {
// Use official gnark serialization
_, _, g1Gen, _ := bn254.Generators()
wrongSer := g1Gen.Bytes()
var evmG1 G1
_, err := evmG1.Unmarshal(wrongSer[:])
if err == nil {
t.Fatalf("points serialized using the official bn254 serialization algorithm, should not work with the evm format")
}
}
func TestSerRoundTrip(t *testing.T) {
_, _, g1Gen, g2Gen := bn254.Generators()
expectedG1 := G1{inner: g1Gen}
bytesG1 := expectedG1.Marshal()
expectedG2 := G2{inner: g2Gen}
bytesG2 := expectedG2.Marshal()
var gotG1 G1
gotG1.Unmarshal(bytesG1)
var gotG2 G2
gotG2.Unmarshal(bytesG2)
if !expectedG1.inner.Equal(&gotG1.inner) {
t.Errorf("serialization roundtrip failed for G1")
}
if !expectedG2.inner.Equal(&gotG2.inner) {
t.Errorf("serialization roundtrip failed for G2")
}
}

View file

@ -128,7 +128,7 @@ func (e *G1) Marshal() []byte {
func (e *G1) Unmarshal(m []byte) ([]byte, error) { func (e *G1) Unmarshal(m []byte) ([]byte, error) {
// Each value is a 256-bit number. // Each value is a 256-bit number.
const numBytes = 256 / 8 const numBytes = 256 / 8
if len(m) != 2*numBytes { if len(m) < 2*numBytes {
return nil, errors.New("bn256: not enough data") return nil, errors.New("bn256: not enough data")
} }
// Unmarshal the points and check their caps // Unmarshal the points and check their caps
@ -253,7 +253,7 @@ func (n *G2) Marshal() []byte {
func (e *G2) Unmarshal(m []byte) ([]byte, error) { func (e *G2) Unmarshal(m []byte) ([]byte, error) {
// Each value is a 256-bit number. // Each value is a 256-bit number.
const numBytes = 256 / 8 const numBytes = 256 / 8
if len(m) != 4*numBytes { if len(m) < 4*numBytes {
return nil, errors.New("bn256: not enough data") return nil, errors.New("bn256: not enough data")
} }
// Unmarshal the points and check their caps // Unmarshal the points and check their caps

View file

@ -19,6 +19,7 @@ package crypto
import ( import (
"bytes" "bytes"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/rand"
"encoding/hex" "encoding/hex"
"math/big" "math/big"
"os" "os"
@ -297,3 +298,38 @@ func TestPythonIntegration(t *testing.T) {
t.Logf("msg: %x, privkey: %s sig: %x\n", msg0, kh, sig0) t.Logf("msg: %x, privkey: %s sig: %x\n", msg0, kh, sig0)
t.Logf("msg: %x, privkey: %s sig: %x\n", msg1, kh, sig1) t.Logf("msg: %x, privkey: %s sig: %x\n", msg1, kh, sig1)
} }
// goos: darwin
// goarch: arm64
// pkg: github.com/ethereum/go-ethereum/crypto
// cpu: Apple M1 Pro
// BenchmarkKeccak256Hash
// BenchmarkKeccak256Hash-8 931095 1270 ns/op 32 B/op 1 allocs/op
func BenchmarkKeccak256Hash(b *testing.B) {
var input [512]byte
rand.Read(input[:])
b.ReportAllocs()
for i := 0; i < b.N; i++ {
Keccak256Hash(input[:])
}
}
// goos: darwin
// goarch: arm64
// pkg: github.com/ethereum/go-ethereum/crypto
// cpu: Apple M1 Pro
// BenchmarkHashData
// BenchmarkHashData-8 793386 1278 ns/op 32 B/op 1 allocs/op
func BenchmarkHashData(b *testing.B) {
var (
input [512]byte
buffer = NewKeccakState()
)
rand.Read(input[:])
b.ReportAllocs()
for i := 0; i < b.N; i++ {
HashData(buffer, input[:])
}
}

View file

@ -283,9 +283,15 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl
// that should be fixed, not papered over. // that should be fixed, not papered over.
header := api.remoteBlocks.get(update.HeadBlockHash) header := api.remoteBlocks.get(update.HeadBlockHash)
if header == nil { if header == nil {
log.Warn("Forkchoice requested unknown head", "hash", update.HeadBlockHash) log.Warn("Fetching the unknown forkchoice head from network", "hash", update.HeadBlockHash)
retrievedHead, err := api.eth.Downloader().GetHeader(update.HeadBlockHash)
if err != nil {
log.Warn("Could not retrieve unknown head from peers")
return engine.STATUS_SYNCING, nil return engine.STATUS_SYNCING, nil
} }
api.remoteBlocks.put(retrievedHead.Hash(), retrievedHead)
header = retrievedHead
}
// If the finalized hash is known, we can direct the downloader to move // If the finalized hash is known, we can direct the downloader to move
// potentially more data to the freezer from the get go. // potentially more data to the freezer from the get go.
finalized := api.remoteBlocks.get(update.FinalizedBlockHash) finalized := api.remoteBlocks.get(update.FinalizedBlockHash)

View file

@ -21,6 +21,7 @@ import (
"time" "time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
) )
@ -48,34 +49,39 @@ func (d *Downloader) BeaconDevSync(mode SyncMode, hash common.Hash, stop chan st
return errors.New("stop requested") return errors.New("stop requested")
default: default:
} }
// Pick a random peer to sync from and keep retrying if none are yet header, err := d.GetHeader(hash)
// available due to fresh startup if err != nil {
d.peers.lock.RLock()
var peer *peerConnection
for _, peer = range d.peers.peers {
break
}
d.peers.lock.RUnlock()
if peer == nil {
time.Sleep(time.Second) time.Sleep(time.Second)
continue continue
} }
return d.BeaconSync(mode, header, header)
}
}
// GetHeader tries to retrieve the header with a given hash from a random peer.
func (d *Downloader) GetHeader(hash common.Hash) (*types.Header, error) {
// Pick a random peer to sync from and keep retrying if none are yet
// available due to fresh startup
d.peers.lock.RLock()
defer d.peers.lock.RUnlock()
for _, peer := range d.peers.peers {
if peer == nil {
return nil, errors.New("could not find peer")
}
// Found a peer, attempt to retrieve the header whilst blocking and // Found a peer, attempt to retrieve the header whilst blocking and
// retry if it fails for whatever reason // retry if it fails for whatever reason
log.Info("Attempting to retrieve sync target", "peer", peer.id) log.Debug("Attempting to retrieve sync target", "peer", peer.id, "hash", hash)
headers, metas, err := d.fetchHeadersByHash(peer, hash, 1, 0, false) headers, metas, err := d.fetchHeadersByHash(peer, hash, 1, 0, false)
if err != nil || len(headers) != 1 { if err != nil || len(headers) != 1 {
log.Warn("Failed to fetch sync target", "headers", len(headers), "err", err)
time.Sleep(time.Second)
continue continue
} }
// Head header retrieved, if the hash matches, start the actual sync // Head header retrieved, if the hash matches, start the actual sync
if metas[0] != hash { if metas[0] != hash {
log.Error("Received invalid sync target", "want", hash, "have", metas[0]) log.Warn("Received invalid sync target", "peer", peer.id, "want", hash, "have", metas[0])
time.Sleep(time.Second)
continue continue
} }
return d.BeaconSync(mode, headers[0], headers[0]) return headers[0], nil
} }
return nil, errors.New("failed to fetch sync target")
} }

View file

@ -321,7 +321,7 @@ func TestInternals(t *testing.T) {
byte(vm.LOG0), byte(vm.LOG0),
}, },
tracer: mkTracer("prestateTracer", nil), tracer: mkTracer("prestateTracer", nil),
want: fmt.Sprintf(`{"0x0000000000000000000000000000000000000000":{"balance":"0x0"},"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600164ffffffffff60016000f560ff6000a0"},"%s":{"balance":"0x1c6bf52634000"}}`, originHex), want: fmt.Sprintf(`{"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600164ffffffffff60016000f560ff6000a0"},"%s":{"balance":"0x1c6bf52634000"}}`, originHex),
}, },
{ {
// CREATE2 which requires padding memory by prestate tracer // CREATE2 which requires padding memory by prestate tracer
@ -340,7 +340,7 @@ func TestInternals(t *testing.T) {
byte(vm.LOG0), byte(vm.LOG0),
}, },
tracer: mkTracer("prestateTracer", nil), tracer: mkTracer("prestateTracer", nil),
want: fmt.Sprintf(`{"0x0000000000000000000000000000000000000000":{"balance":"0x0"},"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600160ff60016000f560ff6000a0"},"%s":{"balance":"0x1c6bf52634000"}}`, originHex), want: fmt.Sprintf(`{"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600160ff60016000f560ff6000a0"},"%s":{"balance":"0x1c6bf52634000"}}`, originHex),
}, },
} { } {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {

View file

@ -59,8 +59,8 @@
}, },
"result": { "result": {
"0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": { "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
"balance": "0x0", "balance":"0x0",
"nonce": 22 "nonce":22
}, },
"0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
"balance": "0x4d87094125a369d9bd5", "balance": "0x4d87094125a369d9bd5",
@ -75,9 +75,6 @@
"0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
"balance": "0x1780d77678137ac1b775", "balance": "0x1780d77678137ac1b775",
"nonce": 29072 "nonce": 29072
},
"0x1585936b53834b021f68cc13eeefdec2efc8e724": {
"balance": "0x0"
} }
} }
} }

View file

@ -70,9 +70,6 @@
"0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
"balance": "0x1780d77678137ac1b775", "balance": "0x1780d77678137ac1b775",
"nonce": 29072 "nonce": 29072
},
"0x1585936b53834b021f68cc13eeefdec2efc8e724": {
"balance": "0x0"
} }
} }
} }

View file

@ -70,9 +70,6 @@
"0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
"balance": "0x1780d77678137ac1b775", "balance": "0x1780d77678137ac1b775",
"nonce": 29072 "nonce": 29072
},
"0x1585936b53834b021f68cc13eeefdec2efc8e724": {
"balance": "0x0"
} }
} }
} }

View file

@ -0,0 +1,61 @@
{
"context": {
"difficulty": "3755480783",
"gasLimit": "5401723",
"miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511",
"number": "2294702",
"timestamp": "1513676146"
},
"genesis": {
"alloc": {
"0x13e4acefe6a6700604929946e70e6443e4e73447": {
"balance": "0xcf3e0938579f000",
"code": "0x",
"nonce": "9",
"storage": {}
}
},
"config": {
"byzantiumBlock": 1700000,
"chainId": 3,
"daoForkSupport": true,
"eip150Block": 0,
"eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
"eip155Block": 10,
"eip158Block": 10,
"ethash": {},
"homesteadBlock": 0
},
"difficulty": "3757315409",
"extraData": "0x566961425443",
"gasLimit": "5406414",
"hash": "0xae107f592eebdd9ff8d6ba00363676096e6afb0e1007a7d3d0af88173077378d",
"miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511",
"mixHash": "0xc927aa05a38bc3de864e95c33b3ae559d3f39c4ccd51cef6f113f9c50ba0caf1",
"nonce": "0x93363bbd2c95f410",
"number": "2294701",
"stateRoot": "0x6b6737d5bde8058990483e915866bd1578014baeff57bd5e4ed228a2bfad635c",
"timestamp": "1513676127"
},
"input": "0xf907ef098504e3b29200830897be8080b9079c606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a1129a01060f46676a5dff6f407f0f51eb6f37f5c8c54e238c70221e18e65fc29d3ea65a0557b01c50ff4ffaac8ed6e5d31237a4ecbac843ab1bfe8bb0165a0060df7c54f",
"tracerConfig": {
"includeEmpty": true
},
"result": {
"0x13e4acefe6a6700604929946e70e6443e4e73447": {
"balance": "0xcf3e0938579f000",
"nonce": 9
},
"0x7dc9c9730689ff0b0fd506c67db815f12d90a448": {
"balance": "0x0",
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000",
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000000",
"0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"0xd049bfd667cb46aa3ef5df0da3e57db3be39e511": {
"balance": "0x0"
}
}
}

View file

@ -28,7 +28,7 @@
"0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
"balance": "0x1780d77678137ac1b775", "balance": "0x1780d77678137ac1b775",
"code": "0x", "code": "0x",
"nonce": "29072", "nonce": 29072,
"storage": {} "storage": {}
} }
}, },
@ -74,9 +74,6 @@
"0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
"balance": "0x1780d77678137ac1b775", "balance": "0x1780d77678137ac1b775",
"nonce": 29072 "nonce": 29072
},
"0x1585936b53834b021f68cc13eeefdec2efc8e724": {
"balance": "0x0"
} }
} }
} }

View file

@ -64,9 +64,6 @@
"balance": "0x0", "balance": "0x0",
"nonce": 22 "nonce": 22
}, },
"0x1585936b53834b021f68cc13eeefdec2efc8e724": {
"balance": "0x0"
},
"0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
"balance": "0x4d87094125a369d9bd5", "balance": "0x4d87094125a369d9bd5",
"nonce": 1, "nonce": 1,

View file

@ -63,9 +63,6 @@
"balance": "0x0", "balance": "0x0",
"nonce": 22 "nonce": 22
}, },
"0x1585936b53834b021f68cc13eeefdec2efc8e724": {
"balance": "0x0"
},
"0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
"balance": "0x4d87094125a369d9bd5", "balance": "0x4d87094125a369d9bd5",
"nonce": 1, "nonce": 1,

View file

@ -19,6 +19,7 @@ package native
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"errors"
"math/big" "math/big"
"sync/atomic" "sync/atomic"
@ -75,6 +76,7 @@ type prestateTracerConfig struct {
DiffMode bool `json:"diffMode"` // If true, this tracer will return state modifications DiffMode bool `json:"diffMode"` // If true, this tracer will return state modifications
DisableCode bool `json:"disableCode"` // If true, this tracer will not return the contract code DisableCode bool `json:"disableCode"` // If true, this tracer will not return the contract code
DisableStorage bool `json:"disableStorage"` // If true, this tracer will not return the contract storage DisableStorage bool `json:"disableStorage"` // If true, this tracer will not return the contract storage
IncludeEmpty bool `json:"includeEmpty"` // If true, this tracer will return empty state objects
} }
func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*tracers.Tracer, error) { func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*tracers.Tracer, error) {
@ -82,6 +84,11 @@ func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *p
if err := json.Unmarshal(cfg, &config); err != nil { if err := json.Unmarshal(cfg, &config); err != nil {
return nil, err return nil, err
} }
// Diff mode has special semantics around account creating and deletion which
// requires it to include empty accounts and storage.
if config.DiffMode && config.IncludeEmpty {
return nil, errors.New("cannot use diffMode with includeEmpty")
}
t := &prestateTracer{ t := &prestateTracer{
pre: stateMap{}, pre: stateMap{},
post: stateMap{}, post: stateMap{},
@ -177,11 +184,14 @@ func (t *prestateTracer) OnTxEnd(receipt *types.Receipt, err error) {
if t.config.DiffMode { if t.config.DiffMode {
t.processDiffState() t.processDiffState()
} }
// the new created contracts' prestate were empty, so delete them // Remove accounts that were empty prior to execution. Unless
for a := range t.created { // user requested to include empty accounts.
// the created contract maybe exists in statedb before the creating tx if t.config.IncludeEmpty {
if s := t.pre[a]; s != nil && s.empty { return
delete(t.pre, a) }
for addr, s := range t.pre {
if s.empty {
delete(t.pre, addr)
} }
} }
} }

View file

@ -280,6 +280,17 @@ func New(file string, cache int, handles int, namespace string, readonly bool) (
// By setting the WALBytesPerSync, the cached WAL writes will be periodically // By setting the WALBytesPerSync, the cached WAL writes will be periodically
// flushed at the background if the accumulated size exceeds this threshold. // flushed at the background if the accumulated size exceeds this threshold.
WALBytesPerSync: 5 * ethdb.IdealBatchSize, WALBytesPerSync: 5 * ethdb.IdealBatchSize,
// L0CompactionThreshold specifies the number of L0 read-amplification
// necessary to trigger an L0 compaction. It essentially refers to the
// number of sub-levels at the L0. For each sub-level, it contains several
// L0 files which are non-overlapping with each other, typically produced
// by a single memory-table flush.
//
// The default value in Pebble is 4, which is a bit too large to have
// the compaction debt as around 10GB. By reducing it to 2, the compaction
// debt will be less than 1GB, but with more frequent compactions scheduled.
L0CompactionThreshold: 2,
} }
// Disable seek compaction explicitly. Check https://github.com/ethereum/go-ethereum/pull/20130 // Disable seek compaction explicitly. Check https://github.com/ethereum/go-ethereum/pull/20130
// for more details. // for more details.

15
go.mod
View file

@ -13,7 +13,7 @@ require (
github.com/cespare/cp v0.1.0 github.com/cespare/cp v0.1.0
github.com/cloudflare/cloudflare-go v0.114.0 github.com/cloudflare/cloudflare-go v0.114.0
github.com/cockroachdb/pebble v1.1.5 github.com/cockroachdb/pebble v1.1.5
github.com/consensys/gnark-crypto v0.16.0 github.com/consensys/gnark-crypto v0.18.0
github.com/crate-crypto/go-eth-kzg v1.3.0 github.com/crate-crypto/go-eth-kzg v1.3.0
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a
github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew v1.1.1
@ -64,11 +64,11 @@ require (
github.com/urfave/cli/v2 v2.27.5 github.com/urfave/cli/v2 v2.27.5
go.uber.org/automaxprocs v1.5.2 go.uber.org/automaxprocs v1.5.2
go.uber.org/goleak v1.3.0 go.uber.org/goleak v1.3.0
golang.org/x/crypto v0.35.0 golang.org/x/crypto v0.36.0
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df
golang.org/x/sync v0.11.0 golang.org/x/sync v0.12.0
golang.org/x/sys v0.30.0 golang.org/x/sys v0.31.0
golang.org/x/text v0.22.0 golang.org/x/text v0.23.0
golang.org/x/time v0.9.0 golang.org/x/time v0.9.0
golang.org/x/tools v0.29.0 golang.org/x/tools v0.29.0
google.golang.org/protobuf v1.34.2 google.golang.org/protobuf v1.34.2
@ -98,7 +98,6 @@ require (
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/redact v1.1.5 // indirect
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
github.com/consensys/bavard v0.1.27 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/deepmap/oapi-codegen v1.6.0 // indirect github.com/deepmap/oapi-codegen v1.6.0 // indirect
github.com/dlclark/regexp2 v1.7.0 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect
@ -123,7 +122,6 @@ require (
github.com/minio/sha256-simd v1.0.0 // indirect github.com/minio/sha256-simd v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/mitchellh/pointerstructure v1.2.0 // indirect
github.com/mmcloughlin/addchain v0.4.0 // indirect
github.com/naoina/go-stringutil v0.1.0 // indirect github.com/naoina/go-stringutil v0.1.0 // indirect
github.com/opentracing/opentracing-go v1.1.0 // indirect github.com/opentracing/opentracing-go v1.1.0 // indirect
github.com/pion/dtls/v2 v2.2.7 // indirect github.com/pion/dtls/v2 v2.2.7 // indirect
@ -143,7 +141,6 @@ require (
github.com/tklauser/numcpus v0.6.1 // indirect github.com/tklauser/numcpus v0.6.1 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
golang.org/x/mod v0.22.0 // indirect golang.org/x/mod v0.22.0 // indirect
golang.org/x/net v0.36.0 // indirect golang.org/x/net v0.38.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
) )

32
go.sum
View file

@ -74,10 +74,8 @@ github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwP
github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo=
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ=
github.com/consensys/bavard v0.1.27 h1:j6hKUrGAy/H+gpNrpLU3I26n1yc+VMGmd6ID5+gAhOs= github.com/consensys/gnark-crypto v0.18.0 h1:vIye/FqI50VeAr0B3dx+YjeIvmc3LWz4yEfbWBpTUf0=
github.com/consensys/bavard v0.1.27/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= github.com/consensys/gnark-crypto v0.18.0/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c=
github.com/consensys/gnark-crypto v0.16.0 h1:8Dl4eYmUWK9WmlP1Bj6je688gBRJCJbT8Mw4KoTAawo=
github.com/consensys/gnark-crypto v0.16.0/go.mod h1:Ke3j06ndtPTVvo++PhGNgvm+lgpLvzbcE2MqljY7diU=
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/crate-crypto/go-eth-kzg v1.3.0 h1:05GrhASN9kDAidaFJOda6A4BEvgvuXbazXg/0E3OOdI= github.com/crate-crypto/go-eth-kzg v1.3.0 h1:05GrhASN9kDAidaFJOda6A4BEvgvuXbazXg/0E3OOdI=
@ -177,7 +175,6 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U=
github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
@ -264,9 +261,6 @@ github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxd
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A=
github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4=
github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY=
github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU=
github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks= github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks=
github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcouEdwIeOtOGA/ELRUw/GwvxwfT+0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcouEdwIeOtOGA/ELRUw/GwvxwfT+0=
@ -381,8 +375,8 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME=
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@ -406,8 +400,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -416,8 +410,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -451,8 +445,8 @@ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@ -470,8 +464,8 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
@ -517,5 +511,3 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=
rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=

View file

@ -7,10 +7,7 @@ import (
// GetOrRegisterCounter returns an existing Counter or constructs and registers // GetOrRegisterCounter returns an existing Counter or constructs and registers
// a new Counter. // a new Counter.
func GetOrRegisterCounter(name string, r Registry) *Counter { func GetOrRegisterCounter(name string, r Registry) *Counter {
if r == nil { return getOrRegister(name, NewCounter, r)
r = DefaultRegistry
}
return r.GetOrRegister(name, NewCounter).(*Counter)
} }
// NewCounter constructs a new Counter. // NewCounter constructs a new Counter.

View file

@ -8,10 +8,7 @@ import (
// GetOrRegisterCounterFloat64 returns an existing *CounterFloat64 or constructs and registers // GetOrRegisterCounterFloat64 returns an existing *CounterFloat64 or constructs and registers
// a new CounterFloat64. // a new CounterFloat64.
func GetOrRegisterCounterFloat64(name string, r Registry) *CounterFloat64 { func GetOrRegisterCounterFloat64(name string, r Registry) *CounterFloat64 {
if nil == r { return getOrRegister(name, NewCounterFloat64, r)
r = DefaultRegistry
}
return r.GetOrRegister(name, NewCounterFloat64).(*CounterFloat64)
} }
// NewCounterFloat64 constructs a new CounterFloat64. // NewCounterFloat64 constructs a new CounterFloat64.

View file

@ -11,10 +11,7 @@ func (g GaugeSnapshot) Value() int64 { return int64(g) }
// GetOrRegisterGauge returns an existing Gauge or constructs and registers a // GetOrRegisterGauge returns an existing Gauge or constructs and registers a
// new Gauge. // new Gauge.
func GetOrRegisterGauge(name string, r Registry) *Gauge { func GetOrRegisterGauge(name string, r Registry) *Gauge {
if r == nil { return getOrRegister(name, NewGauge, r)
r = DefaultRegistry
}
return r.GetOrRegister(name, NewGauge).(*Gauge)
} }
// NewGauge constructs a new Gauge. // NewGauge constructs a new Gauge.

View file

@ -8,10 +8,7 @@ import (
// GetOrRegisterGaugeFloat64 returns an existing GaugeFloat64 or constructs and registers a // GetOrRegisterGaugeFloat64 returns an existing GaugeFloat64 or constructs and registers a
// new GaugeFloat64. // new GaugeFloat64.
func GetOrRegisterGaugeFloat64(name string, r Registry) *GaugeFloat64 { func GetOrRegisterGaugeFloat64(name string, r Registry) *GaugeFloat64 {
if nil == r { return getOrRegister(name, NewGaugeFloat64, r)
r = DefaultRegistry
}
return r.GetOrRegister(name, NewGaugeFloat64()).(*GaugeFloat64)
} }
// GaugeFloat64Snapshot is a read-only copy of a GaugeFloat64. // GaugeFloat64Snapshot is a read-only copy of a GaugeFloat64.

View file

@ -16,10 +16,7 @@ func (val GaugeInfoValue) String() string {
// GetOrRegisterGaugeInfo returns an existing GaugeInfo or constructs and registers a // GetOrRegisterGaugeInfo returns an existing GaugeInfo or constructs and registers a
// new GaugeInfo. // new GaugeInfo.
func GetOrRegisterGaugeInfo(name string, r Registry) *GaugeInfo { func GetOrRegisterGaugeInfo(name string, r Registry) *GaugeInfo {
if nil == r { return getOrRegister(name, NewGaugeInfo, r)
r = DefaultRegistry
}
return r.GetOrRegister(name, NewGaugeInfo()).(*GaugeInfo)
} }
// NewGaugeInfo constructs a new GaugeInfo. // NewGaugeInfo constructs a new GaugeInfo.

View file

@ -23,19 +23,13 @@ type Histogram interface {
// GetOrRegisterHistogram returns an existing Histogram or constructs and // GetOrRegisterHistogram returns an existing Histogram or constructs and
// registers a new StandardHistogram. // registers a new StandardHistogram.
func GetOrRegisterHistogram(name string, r Registry, s Sample) Histogram { func GetOrRegisterHistogram(name string, r Registry, s Sample) Histogram {
if nil == r { return getOrRegister(name, func() Histogram { return NewHistogram(s) }, r)
r = DefaultRegistry
}
return r.GetOrRegister(name, func() Histogram { return NewHistogram(s) }).(Histogram)
} }
// GetOrRegisterHistogramLazy returns an existing Histogram or constructs and // GetOrRegisterHistogramLazy returns an existing Histogram or constructs and
// registers a new StandardHistogram. // registers a new StandardHistogram.
func GetOrRegisterHistogramLazy(name string, r Registry, s func() Sample) Histogram { func GetOrRegisterHistogramLazy(name string, r Registry, s func() Sample) Histogram {
if nil == r { return getOrRegister(name, func() Histogram { return NewHistogram(s()) }, r)
r = DefaultRegistry
}
return r.GetOrRegister(name, func() Histogram { return NewHistogram(s()) }).(Histogram)
} }
// NewHistogram constructs a new StandardHistogram from a Sample. // NewHistogram constructs a new StandardHistogram from a Sample.

View file

@ -12,10 +12,7 @@ import (
// Be sure to unregister the meter from the registry once it is of no use to // Be sure to unregister the meter from the registry once it is of no use to
// allow for garbage collection. // allow for garbage collection.
func GetOrRegisterMeter(name string, r Registry) *Meter { func GetOrRegisterMeter(name string, r Registry) *Meter {
if r == nil { return getOrRegister(name, NewMeter, r)
r = DefaultRegistry
}
return r.GetOrRegister(name, NewMeter).(*Meter)
} }
// NewMeter constructs a new Meter and launches a goroutine. // NewMeter constructs a new Meter and launches a goroutine.

View file

@ -3,7 +3,6 @@ package metrics
import ( import (
"errors" "errors"
"fmt" "fmt"
"reflect"
"sort" "sort"
"strings" "strings"
"sync" "sync"
@ -30,10 +29,9 @@ type Registry interface {
// GetAll metrics in the Registry. // GetAll metrics in the Registry.
GetAll() map[string]map[string]interface{} GetAll() map[string]map[string]interface{}
// GetOrRegister gets an existing metric or registers the given one. // GetOrRegister returns an existing metric or registers the one returned
// The interface can be the metric to register if not found in registry, // by the given constructor.
// or a function returning the metric for lazy instantiation. GetOrRegister(string, func() interface{}) interface{}
GetOrRegister(string, interface{}) interface{}
// Register the given metric under the given name. // Register the given metric under the given name.
Register(string, interface{}) error Register(string, interface{}) error
@ -95,19 +93,13 @@ func (r *StandardRegistry) Get(name string) interface{} {
// alternative to calling Get and Register on failure. // alternative to calling Get and Register on failure.
// The interface can be the metric to register if not found in registry, // The interface can be the metric to register if not found in registry,
// or a function returning the metric for lazy instantiation. // or a function returning the metric for lazy instantiation.
func (r *StandardRegistry) GetOrRegister(name string, i interface{}) interface{} { func (r *StandardRegistry) GetOrRegister(name string, ctor func() interface{}) interface{} {
// fast path // fast path
cached, ok := r.metrics.Load(name) cached, ok := r.metrics.Load(name)
if ok { if ok {
return cached return cached
} }
if v := reflect.ValueOf(i); v.Kind() == reflect.Func { item, _, _ := r.loadOrRegister(name, ctor())
i = v.Call(nil)[0].Interface()
}
item, _, ok := r.loadOrRegister(name, i)
if !ok {
return i
}
return item return item
} }
@ -120,9 +112,6 @@ func (r *StandardRegistry) Register(name string, i interface{}) error {
return fmt.Errorf("%w: %v", ErrDuplicateMetric, name) return fmt.Errorf("%w: %v", ErrDuplicateMetric, name)
} }
if v := reflect.ValueOf(i); v.Kind() == reflect.Func {
i = v.Call(nil)[0].Interface()
}
_, loaded, _ := r.loadOrRegister(name, i) _, loaded, _ := r.loadOrRegister(name, i)
if loaded { if loaded {
return fmt.Errorf("%w: %v", ErrDuplicateMetric, name) return fmt.Errorf("%w: %v", ErrDuplicateMetric, name)
@ -295,9 +284,9 @@ func (r *PrefixedRegistry) Get(name string) interface{} {
// GetOrRegister gets an existing metric or registers the given one. // GetOrRegister gets an existing metric or registers the given one.
// The interface can be the metric to register if not found in registry, // The interface can be the metric to register if not found in registry,
// or a function returning the metric for lazy instantiation. // or a function returning the metric for lazy instantiation.
func (r *PrefixedRegistry) GetOrRegister(name string, metric interface{}) interface{} { func (r *PrefixedRegistry) GetOrRegister(name string, ctor func() interface{}) interface{} {
realName := r.prefix + name realName := r.prefix + name
return r.underlying.GetOrRegister(realName, metric) return r.underlying.GetOrRegister(realName, ctor)
} }
// Register the given metric under the given name. The name will be prefixed. // Register the given metric under the given name. The name will be prefixed.
@ -338,10 +327,17 @@ func Get(name string) interface{} {
// GetOrRegister gets an existing metric or creates and registers a new one. Threadsafe // GetOrRegister gets an existing metric or creates and registers a new one. Threadsafe
// alternative to calling Get and Register on failure. // alternative to calling Get and Register on failure.
func GetOrRegister(name string, i interface{}) interface{} { func GetOrRegister(name string, i func() interface{}) interface{} {
return DefaultRegistry.GetOrRegister(name, i) return DefaultRegistry.GetOrRegister(name, i)
} }
func getOrRegister[T any](name string, ctor func() T, r Registry) T {
if r == nil {
r = DefaultRegistry
}
return r.GetOrRegister(name, func() any { return ctor() }).(T)
}
// Register the given metric under the given name. Returns a ErrDuplicateMetric // Register the given metric under the given name. Returns a ErrDuplicateMetric
// if a metric by the given name is already registered. // if a metric by the given name is already registered.
func Register(name string, i interface{}) error { func Register(name string, i interface{}) error {

View file

@ -30,7 +30,7 @@ func benchmarkRegistryGetOrRegisterParallel(b *testing.B, amount int) {
wg.Add(1) wg.Add(1)
go func() { go func() {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
r.GetOrRegister("foo", NewMeter) GetOrRegisterMeter("foo", r)
} }
wg.Done() wg.Done()
}() }()
@ -98,10 +98,10 @@ func TestRegistryGetOrRegister(t *testing.T) {
r := NewRegistry() r := NewRegistry()
// First metric wins with GetOrRegister // First metric wins with GetOrRegister
_ = r.GetOrRegister("foo", NewCounter()) c1 := GetOrRegisterCounter("foo", r)
m := r.GetOrRegister("foo", NewGauge()) c2 := GetOrRegisterCounter("foo", r)
if _, ok := m.(*Counter); !ok { if c1 != c2 {
t.Fatal(m) t.Fatal("counters should've matched")
} }
i := 0 i := 0
@ -123,10 +123,10 @@ func TestRegistryGetOrRegisterWithLazyInstantiation(t *testing.T) {
r := NewRegistry() r := NewRegistry()
// First metric wins with GetOrRegister // First metric wins with GetOrRegister
_ = r.GetOrRegister("foo", NewCounter) c1 := GetOrRegisterCounter("foo", r)
m := r.GetOrRegister("foo", NewGauge) c2 := GetOrRegisterCounter("foo", r)
if _, ok := m.(*Counter); !ok { if c1 != c2 {
t.Fatal(m) t.Fatal("counters should've matched")
} }
i := 0 i := 0
@ -165,7 +165,7 @@ func TestPrefixedChildRegistryGetOrRegister(t *testing.T) {
r := NewRegistry() r := NewRegistry()
pr := NewPrefixedChildRegistry(r, "prefix.") pr := NewPrefixedChildRegistry(r, "prefix.")
_ = pr.GetOrRegister("foo", NewCounter()) _ = GetOrRegisterCounter("foo", pr)
i := 0 i := 0
r.Each(func(name string, m interface{}) { r.Each(func(name string, m interface{}) {
@ -182,7 +182,7 @@ func TestPrefixedChildRegistryGetOrRegister(t *testing.T) {
func TestPrefixedRegistryGetOrRegister(t *testing.T) { func TestPrefixedRegistryGetOrRegister(t *testing.T) {
r := NewPrefixedRegistry("prefix.") r := NewPrefixedRegistry("prefix.")
_ = r.GetOrRegister("foo", NewCounter()) _ = GetOrRegisterCounter("foo", r)
i := 0 i := 0
r.Each(func(name string, m interface{}) { r.Each(func(name string, m interface{}) {

View file

@ -8,10 +8,7 @@ import (
// GetOrRegisterResettingTimer returns an existing ResettingTimer or constructs and registers a // GetOrRegisterResettingTimer returns an existing ResettingTimer or constructs and registers a
// new ResettingTimer. // new ResettingTimer.
func GetOrRegisterResettingTimer(name string, r Registry) *ResettingTimer { func GetOrRegisterResettingTimer(name string, r Registry) *ResettingTimer {
if nil == r { return getOrRegister(name, NewResettingTimer, r)
r = DefaultRegistry
}
return r.GetOrRegister(name, NewResettingTimer).(*ResettingTimer)
} }
// NewRegisteredResettingTimer constructs and registers a new ResettingTimer. // NewRegisteredResettingTimer constructs and registers a new ResettingTimer.

View file

@ -8,11 +8,8 @@ import (
) )
func getOrRegisterRuntimeHistogram(name string, scale float64, r Registry) *runtimeHistogram { func getOrRegisterRuntimeHistogram(name string, scale float64, r Registry) *runtimeHistogram {
if r == nil {
r = DefaultRegistry
}
constructor := func() Histogram { return newRuntimeHistogram(scale) } constructor := func() Histogram { return newRuntimeHistogram(scale) }
return r.GetOrRegister(name, constructor).(*runtimeHistogram) return getOrRegister(name, constructor, r).(*runtimeHistogram)
} }
// runtimeHistogram wraps a runtime/metrics histogram. // runtimeHistogram wraps a runtime/metrics histogram.

View file

@ -10,10 +10,7 @@ import (
// Be sure to unregister the meter from the registry once it is of no use to // Be sure to unregister the meter from the registry once it is of no use to
// allow for garbage collection. // allow for garbage collection.
func GetOrRegisterTimer(name string, r Registry) *Timer { func GetOrRegisterTimer(name string, r Registry) *Timer {
if nil == r { return getOrRegister(name, NewTimer, r)
r = DefaultRegistry
}
return r.GetOrRegister(name, NewTimer).(*Timer)
} }
// NewCustomTimer constructs a new Timer from a Histogram and a Meter. // NewCustomTimer constructs a new Timer from a Histogram and a Meter.

View file

@ -62,6 +62,7 @@ type rpcEndpointConfig struct {
type rpcHandler struct { type rpcHandler struct {
http.Handler http.Handler
prefix string
server *rpc.Server server *rpc.Server
} }
@ -79,11 +80,11 @@ type httpServer struct {
// HTTP RPC handler things. // HTTP RPC handler things.
httpConfig httpConfig httpConfig httpConfig
httpHandler atomic.Value // *rpcHandler httpHandler atomic.Pointer[rpcHandler]
// WebSocket handler things. // WebSocket handler things.
wsConfig wsConfig wsConfig wsConfig
wsHandler atomic.Value // *rpcHandler wsHandler atomic.Pointer[rpcHandler]
// These are set by setListenAddr. // These are set by setListenAddr.
endpoint string endpoint string
@ -99,9 +100,6 @@ const (
func newHTTPServer(log log.Logger, timeouts rpc.HTTPTimeouts, shutdownDelay time.Duration) *httpServer { func newHTTPServer(log log.Logger, timeouts rpc.HTTPTimeouts, shutdownDelay time.Duration) *httpServer {
h := &httpServer{log: log, timeouts: timeouts, handlerNames: make(map[string]string), shutdownDelay: shutdownDelay} h := &httpServer{log: log, timeouts: timeouts, handlerNames: make(map[string]string), shutdownDelay: shutdownDelay}
h.httpHandler.Store((*rpcHandler)(nil))
h.wsHandler.Store((*rpcHandler)(nil))
return h return h
} }
@ -217,16 +215,16 @@ func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
} }
// check if ws request and serve if ws enabled // check if ws request and serve if ws enabled
ws := h.wsHandler.Load().(*rpcHandler) ws := h.wsHandler.Load()
if ws != nil && isWebsocket(r) { if ws != nil && isWebsocket(r) {
if checkPath(r, h.wsConfig.prefix) { if checkPath(r, ws.prefix) {
ws.ServeHTTP(w, r) ws.ServeHTTP(w, r)
} }
return return
} }
// if http-rpc is enabled, try to serve request // if http-rpc is enabled, try to serve request
rpc := h.httpHandler.Load().(*rpcHandler) rpc := h.httpHandler.Load()
if rpc != nil { if rpc != nil {
// First try to route in the mux. // First try to route in the mux.
// Requests to a path below root are handled by the mux, // Requests to a path below root are handled by the mux,
@ -238,7 +236,7 @@ func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return return
} }
if checkPath(r, h.httpConfig.prefix) { if checkPath(r, rpc.prefix) {
rpc.ServeHTTP(w, r) rpc.ServeHTTP(w, r)
return return
} }
@ -298,14 +296,14 @@ func (h *httpServer) doStop() {
} }
// Shut down the server. // Shut down the server.
httpHandler := h.httpHandler.Load().(*rpcHandler) httpHandler := h.httpHandler.Load()
wsHandler := h.wsHandler.Load().(*rpcHandler) wsHandler := h.wsHandler.Load()
if httpHandler != nil { if httpHandler != nil {
h.httpHandler.Store((*rpcHandler)(nil)) h.httpHandler.Store(nil)
httpHandler.server.Stop() httpHandler.server.Stop()
} }
if wsHandler != nil { if wsHandler != nil {
h.wsHandler.Store((*rpcHandler)(nil)) h.wsHandler.Store(nil)
wsHandler.server.Stop() wsHandler.server.Stop()
} }
@ -346,6 +344,7 @@ func (h *httpServer) enableRPC(apis []rpc.API, config httpConfig) error {
h.httpConfig = config h.httpConfig = config
h.httpHandler.Store(&rpcHandler{ h.httpHandler.Store(&rpcHandler{
Handler: NewHTTPHandlerStack(srv, config.CorsAllowedOrigins, config.Vhosts, config.jwtSecret), Handler: NewHTTPHandlerStack(srv, config.CorsAllowedOrigins, config.Vhosts, config.jwtSecret),
prefix: config.prefix,
server: srv, server: srv,
}) })
return nil return nil
@ -353,9 +352,9 @@ func (h *httpServer) enableRPC(apis []rpc.API, config httpConfig) error {
// disableRPC stops the HTTP RPC handler. This is internal, the caller must hold h.mu. // disableRPC stops the HTTP RPC handler. This is internal, the caller must hold h.mu.
func (h *httpServer) disableRPC() bool { func (h *httpServer) disableRPC() bool {
handler := h.httpHandler.Load().(*rpcHandler) handler := h.httpHandler.Load()
if handler != nil { if handler != nil {
h.httpHandler.Store((*rpcHandler)(nil)) h.httpHandler.Store(nil)
handler.server.Stop() handler.server.Stop()
} }
return handler != nil return handler != nil
@ -381,6 +380,7 @@ func (h *httpServer) enableWS(apis []rpc.API, config wsConfig) error {
h.wsConfig = config h.wsConfig = config
h.wsHandler.Store(&rpcHandler{ h.wsHandler.Store(&rpcHandler{
Handler: NewWSHandlerStack(srv.WebsocketHandler(config.Origins), config.jwtSecret), Handler: NewWSHandlerStack(srv.WebsocketHandler(config.Origins), config.jwtSecret),
prefix: config.prefix,
server: srv, server: srv,
}) })
return nil return nil
@ -400,9 +400,9 @@ func (h *httpServer) stopWS() {
// disableWS disables the WebSocket handler. This is internal, the caller must hold h.mu. // disableWS disables the WebSocket handler. This is internal, the caller must hold h.mu.
func (h *httpServer) disableWS() bool { func (h *httpServer) disableWS() bool {
ws := h.wsHandler.Load().(*rpcHandler) ws := h.wsHandler.Load()
if ws != nil { if ws != nil {
h.wsHandler.Store((*rpcHandler)(nil)) h.wsHandler.Store(nil)
ws.server.Stop() ws.server.Stop()
} }
return ws != nil return ws != nil
@ -410,12 +410,12 @@ func (h *httpServer) disableWS() bool {
// rpcAllowed returns true when JSON-RPC over HTTP is enabled. // rpcAllowed returns true when JSON-RPC over HTTP is enabled.
func (h *httpServer) rpcAllowed() bool { func (h *httpServer) rpcAllowed() bool {
return h.httpHandler.Load().(*rpcHandler) != nil return h.httpHandler.Load() != nil
} }
// wsAllowed returns true when JSON-RPC over WebSocket is enabled. // wsAllowed returns true when JSON-RPC over WebSocket is enabled.
func (h *httpServer) wsAllowed() bool { func (h *httpServer) wsAllowed() bool {
return h.wsHandler.Load().(*rpcHandler) != nil return h.wsHandler.Load() != nil
} }
// isWebsocket checks the header of an http request for a websocket upgrade request. // isWebsocket checks the header of an http request for a websocket upgrade request.

View file

@ -152,6 +152,14 @@ compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bn256 \
FuzzPair fuzzBn256Pair \ FuzzPair fuzzBn256Pair \
$repo/tests/fuzzers/bn256/bn256_test.go $repo/tests/fuzzers/bn256/bn256_test.go
compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bn256 \
FuzzUnmarshalG1 fuzzBn256UnmarshalG1 \
$repo/tests/fuzzers/bn256/bn256_test.go
compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bn256 \
FuzzUnmarshalG2 fuzzBn256UnmarshalG2 \
$repo/tests/fuzzers/bn256/bn256_test.go
compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/txfetcher \ compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/txfetcher \
Fuzz fuzzTxfetcher \ Fuzz fuzzTxfetcher \
$repo/tests/fuzzers/txfetcher/txfetcher_test.go $repo/tests/fuzzers/txfetcher/txfetcher_test.go

View file

@ -161,6 +161,60 @@ func fuzzPair(data []byte) int {
return 1 return 1
} }
func fuzzUnmarshalG1(input []byte) int {
rc := new(cloudflare.G1)
_, errC := rc.Unmarshal(input)
rg := new(google.G1)
_, errG := rg.Unmarshal(input)
rs := new(gnark.G1)
_, errS := rs.Unmarshal(input)
if errC != nil && errG != nil && errS != nil {
return 0 // bad input
}
if errC == nil && errG == nil && errS == nil {
//make sure we unmarshalled the same points:
if !bytes.Equal(rc.Marshal(), rg.Marshal()) {
panic("marshaling mismatch: cloudflare/google")
}
if !bytes.Equal(rc.Marshal(), rs.Marshal()) {
panic("marshaling mismatch: cloudflare/gnark")
}
return 1
} else {
panic(fmt.Sprintf("error missmatch: cf: %v g: %v gn: %v", errC, errG, errS))
}
}
func fuzzUnmarshalG2(input []byte) int {
rc := new(cloudflare.G2)
_, errC := rc.Unmarshal(input)
rg := new(google.G2)
_, errG := rg.Unmarshal(input)
rs := new(gnark.G2)
_, errS := rs.Unmarshal(input)
if errC != nil && errG != nil && errS != nil {
return 0 // bad input
}
if errC == nil && errG == nil && errS == nil {
//make sure we unmarshalled the same points:
if !bytes.Equal(rc.Marshal(), rg.Marshal()) {
panic("marshaling mismatch: cloudflare/google")
}
if !bytes.Equal(rc.Marshal(), rs.Marshal()) {
panic("marshaling mismatch: cloudflare/gnark")
}
return 1
} else {
panic(fmt.Sprintf("error missmatch: cf: %v g: %v gn: %v", errC, errG, errS))
}
}
// normalizeGTToGnark scales a Cloudflare/Google GT element by `s` // normalizeGTToGnark scales a Cloudflare/Google GT element by `s`
// so that it can be compared with a gnark GT point. // so that it can be compared with a gnark GT point.
// //

View file

@ -35,3 +35,15 @@ func FuzzPair(f *testing.F) {
fuzzPair(data) fuzzPair(data)
}) })
} }
func FuzzUnmarshalG1(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzUnmarshalG1(data)
})
}
func FuzzUnmarshalG2(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzUnmarshalG2(data)
})
}

View file

@ -86,6 +86,10 @@ func (db *testDb) InsertPreimage(preimages map[common.Hash][]byte) {
rawdb.WritePreimages(db.disk, preimages) rawdb.WritePreimages(db.disk, preimages)
} }
func (db *testDb) PreimageEnabled() bool {
return true
}
func (db *testDb) Scheme() string { return db.scheme } func (db *testDb) Scheme() string { return db.scheme }
func (db *testDb) Update(root common.Hash, parent common.Hash, nodes *trienode.MergedNodeSet) error { func (db *testDb) Update(root common.Hash, parent common.Hash, nodes *trienode.MergedNodeSet) error {

View file

@ -33,6 +33,9 @@ type preimageStore interface {
// InsertPreimage commits a set of preimages along with their hashes. // InsertPreimage commits a set of preimages along with their hashes.
InsertPreimage(preimages map[common.Hash][]byte) InsertPreimage(preimages map[common.Hash][]byte)
// PreimageEnabled returns true if the preimage store is enabled.
PreimageEnabled() bool
} }
// SecureTrie is the old name of StateTrie. // SecureTrie is the old name of StateTrie.
@ -84,8 +87,7 @@ func NewStateTrie(id *ID, db database.NodeDatabase) (*StateTrie, error) {
tr := &StateTrie{trie: *trie, db: db} tr := &StateTrie{trie: *trie, db: db}
// link the preimage store if it's supported // link the preimage store if it's supported
preimages, ok := db.(preimageStore) if preimages, ok := db.(preimageStore); ok && preimages.PreimageEnabled() {
if ok {
tr.preimages = preimages tr.preimages = preimages
} }
return tr, nil return tr, nil
@ -159,7 +161,9 @@ func (t *StateTrie) GetNode(path []byte) ([]byte, int, error) {
func (t *StateTrie) MustUpdate(key, value []byte) { func (t *StateTrie) MustUpdate(key, value []byte) {
hk := crypto.Keccak256(key) hk := crypto.Keccak256(key)
t.trie.MustUpdate(hk, value) t.trie.MustUpdate(hk, value)
if t.preimages != nil {
t.getSecKeyCache()[common.Hash(hk)] = common.CopyBytes(key) t.getSecKeyCache()[common.Hash(hk)] = common.CopyBytes(key)
}
} }
// UpdateStorage associates key with value in the trie. Subsequent calls to // UpdateStorage associates key with value in the trie. Subsequent calls to
@ -177,7 +181,9 @@ func (t *StateTrie) UpdateStorage(_ common.Address, key, value []byte) error {
if err != nil { if err != nil {
return err return err
} }
if t.preimages != nil {
t.getSecKeyCache()[common.Hash(hk)] = common.CopyBytes(key) t.getSecKeyCache()[common.Hash(hk)] = common.CopyBytes(key)
}
return nil return nil
} }
@ -191,7 +197,9 @@ func (t *StateTrie) UpdateAccount(address common.Address, acc *types.StateAccoun
if err := t.trie.Update(hk, data); err != nil { if err := t.trie.Update(hk, data); err != nil {
return err return err
} }
if t.preimages != nil {
t.getSecKeyCache()[common.Hash(hk)] = address.Bytes() t.getSecKeyCache()[common.Hash(hk)] = address.Bytes()
}
return nil return nil
} }
@ -203,7 +211,9 @@ func (t *StateTrie) UpdateContractCode(_ common.Address, _ common.Hash, _ []byte
// will omit any encountered error but just print out an error message. // will omit any encountered error but just print out an error message.
func (t *StateTrie) MustDelete(key []byte) { func (t *StateTrie) MustDelete(key []byte) {
hk := crypto.Keccak256(key) hk := crypto.Keccak256(key)
if t.preimages != nil {
delete(t.getSecKeyCache(), common.Hash(hk)) delete(t.getSecKeyCache(), common.Hash(hk))
}
t.trie.MustDelete(hk) t.trie.MustDelete(hk)
} }
@ -212,26 +222,30 @@ func (t *StateTrie) MustDelete(key []byte) {
// If a node is not found in the database, a MissingNodeError is returned. // If a node is not found in the database, a MissingNodeError is returned.
func (t *StateTrie) DeleteStorage(_ common.Address, key []byte) error { func (t *StateTrie) DeleteStorage(_ common.Address, key []byte) error {
hk := crypto.Keccak256(key) hk := crypto.Keccak256(key)
if t.preimages != nil {
delete(t.getSecKeyCache(), common.Hash(hk)) delete(t.getSecKeyCache(), common.Hash(hk))
}
return t.trie.Delete(hk) return t.trie.Delete(hk)
} }
// DeleteAccount abstracts an account deletion from the trie. // DeleteAccount abstracts an account deletion from the trie.
func (t *StateTrie) DeleteAccount(address common.Address) error { func (t *StateTrie) DeleteAccount(address common.Address) error {
hk := crypto.Keccak256(address.Bytes()) hk := crypto.Keccak256(address.Bytes())
if t.preimages != nil {
delete(t.getSecKeyCache(), common.Hash(hk)) delete(t.getSecKeyCache(), common.Hash(hk))
}
return t.trie.Delete(hk) return t.trie.Delete(hk)
} }
// GetKey returns the sha3 preimage of a hashed key that was // GetKey returns the sha3 preimage of a hashed key that was
// previously used to store a value. // previously used to store a value.
func (t *StateTrie) GetKey(shaKey []byte) []byte { func (t *StateTrie) GetKey(shaKey []byte) []byte {
if key, ok := t.getSecKeyCache()[common.BytesToHash(shaKey)]; ok {
return key
}
if t.preimages == nil { if t.preimages == nil {
return nil return nil
} }
if key, ok := t.getSecKeyCache()[common.BytesToHash(shaKey)]; ok {
return key
}
return t.preimages.Preimage(common.BytesToHash(shaKey)) return t.preimages.Preimage(common.BytesToHash(shaKey))
} }

View file

@ -213,6 +213,11 @@ func (db *Database) InsertPreimage(preimages map[common.Hash][]byte) {
db.preimages.insertPreimage(preimages) db.preimages.insertPreimage(preimages)
} }
// PreimageEnabled returns the indicator if the pre-image store is enabled.
func (db *Database) PreimageEnabled() bool {
return db.preimages != nil
}
// Cap iteratively flushes old but still referenced trie nodes until the total // Cap iteratively flushes old but still referenced trie nodes until the total
// memory usage goes below the given threshold. The held pre-images accumulated // memory usage goes below the given threshold. The held pre-images accumulated
// up to this point will be flushed in case the size exceeds the threshold. // up to this point will be flushed in case the size exceeds the threshold.

View file

@ -86,9 +86,7 @@ func apply(db database.NodeDatabase, prevRoot common.Hash, postRoot common.Hash,
func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address) error { func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address) error {
// The account was present in prev-state, decode it from the // The account was present in prev-state, decode it from the
// 'slim-rlp' format bytes. // 'slim-rlp' format bytes.
h := crypto.NewKeccakState() addrHash := crypto.Keccak256Hash(addr.Bytes())
addrHash := crypto.HashData(h, addr.Bytes())
prev, err := types.FullAccount(ctx.accounts[addr]) prev, err := types.FullAccount(ctx.accounts[addr])
if err != nil { if err != nil {
return err return err
@ -113,7 +111,7 @@ func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address)
for key, val := range ctx.storages[addr] { for key, val := range ctx.storages[addr] {
tkey := key tkey := key
if ctx.rawStorageKey { if ctx.rawStorageKey {
tkey = crypto.HashData(h, key.Bytes()) tkey = crypto.Keccak256Hash(key.Bytes())
} }
var err error var err error
if len(val) == 0 { if len(val) == 0 {
@ -149,9 +147,7 @@ func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address)
// account and storage is wiped out correctly. // account and storage is wiped out correctly.
func deleteAccount(ctx *context, db database.NodeDatabase, addr common.Address) error { func deleteAccount(ctx *context, db database.NodeDatabase, addr common.Address) error {
// The account must be existent in post-state, load the account. // The account must be existent in post-state, load the account.
h := crypto.NewKeccakState() addrHash := crypto.Keccak256Hash(addr.Bytes())
addrHash := crypto.HashData(h, addr.Bytes())
blob, err := ctx.accountTrie.Get(addrHash.Bytes()) blob, err := ctx.accountTrie.Get(addrHash.Bytes())
if err != nil { if err != nil {
return err return err
@ -173,7 +169,7 @@ func deleteAccount(ctx *context, db database.NodeDatabase, addr common.Address)
} }
tkey := key tkey := key
if ctx.rawStorageKey { if ctx.rawStorageKey {
tkey = crypto.HashData(h, key.Bytes()) tkey = crypto.Keccak256Hash(key.Bytes())
} }
if err := st.Delete(tkey.Bytes()); err != nil { if err := st.Delete(tkey.Bytes()); err != nil {
return err return err

View file

@ -278,12 +278,11 @@ func newHistory(root common.Hash, parent common.Hash, block uint64, accounts map
// and the hash of the storage slot key. // and the hash of the storage slot key.
func (h *history) stateSet() (map[common.Hash][]byte, map[common.Hash]map[common.Hash][]byte) { func (h *history) stateSet() (map[common.Hash][]byte, map[common.Hash]map[common.Hash][]byte) {
var ( var (
buff = crypto.NewKeccakState()
accounts = make(map[common.Hash][]byte) accounts = make(map[common.Hash][]byte)
storages = make(map[common.Hash]map[common.Hash][]byte) storages = make(map[common.Hash]map[common.Hash][]byte)
) )
for addr, blob := range h.accounts { for addr, blob := range h.accounts {
addrHash := crypto.HashData(buff, addr.Bytes()) addrHash := crypto.Keccak256Hash(addr.Bytes())
accounts[addrHash] = blob accounts[addrHash] = blob
storage, exist := h.storages[addr] storage, exist := h.storages[addr]
@ -295,7 +294,7 @@ func (h *history) stateSet() (map[common.Hash][]byte, map[common.Hash]map[common
} else { } else {
subset := make(map[common.Hash][]byte) subset := make(map[common.Hash][]byte)
for key, slot := range storage { for key, slot := range storage {
subset[crypto.HashData(buff, key.Bytes())] = slot subset[crypto.Keccak256Hash(key.Bytes())] = slot
} }
storages[addrHash] = subset storages[addrHash] = subset
} }