diff --git a/Makefile b/Makefile index f4932165a4..f3d7f48f2f 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # with Go source code. If you know what GOPATH is then you probably # don't need to bother with make. -.PHONY: geth all test lint fmt clean devtools help +.PHONY: geth evm all test lint fmt clean devtools help GOBIN = ./build/bin GO ?= latest @@ -14,6 +14,12 @@ geth: @echo "Done building." @echo "Run \"$(GOBIN)/geth\" to launch geth." +#? evm: Build evm. +evm: + $(GORUN) build/ci.go install ./cmd/evm + @echo "Done building." + @echo "Run \"$(GOBIN)/evm\" to launch evm." + #? all: Build all packages and executables. all: $(GORUN) build/ci.go install diff --git a/accounts/manager.go b/accounts/manager.go index ac21ecd985..a2218e54dd 100644 --- a/accounts/manager.go +++ b/accounts/manager.go @@ -93,9 +93,6 @@ func NewManager(config *Config, backends ...Backend) *Manager { // Close terminates the account manager's internal notification processes. func (am *Manager) Close() error { - for _, w := range am.wallets { - w.Close() - } errc := make(chan error) am.quit <- errc return <-errc @@ -149,6 +146,10 @@ func (am *Manager) update() { am.lock.Unlock() close(event.processed) case errc := <-am.quit: + // Close all owned wallets + for _, w := range am.wallets { + w.Close() + } // Manager terminating, return errc <- nil // Signals event emitters the loop is not receiving values diff --git a/build/checksums.txt b/build/checksums.txt index cf52172c2e..663bf9ed63 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -5,54 +5,54 @@ # https://github.com/ethereum/execution-spec-tests/releases/download/v4.5.0/ 58afb92a0075a2cb7c4dec1281f7cb88b21b02afbedad096b580f3f8cc14c54c fixtures_develop.tar.gz -# version:golang 1.24.3 +# version:golang 1.24.4 # https://go.dev/dl/ -229c08b600b1446798109fae1f569228102c8473caba8104b6418cb5bc032878 go1.24.3.src.tar.gz -6f6901497547db3b77c14f7f953fbcef9fa5fb84199ee2ee14a5686e66bed5a6 go1.24.3.aix-ppc64.tar.gz -a05fa7e4043a4fec66897135219e3b8ab2202b5ef351c60c2fbb531dfb8f2900 go1.24.3.darwin-amd64.pkg -13e6fe3fcf65689d77d40e633de1e31c6febbdbcb846eb05fc2434ed2213e92b go1.24.3.darwin-amd64.tar.gz -97055ff4214043b39dc32e043fdd5c565df7c0a4e2fc0174e779a134c347ae0e go1.24.3.darwin-arm64.pkg -64a3fa22142f627e78fac3018ce3d4aeace68b743eff0afda8aae0411df5e4fb go1.24.3.darwin-arm64.tar.gz -32de3fd44d5055973978436a7f1f0ffbaae85c1b603ec6105e5c38d8a674c721 go1.24.3.dragonfly-amd64.tar.gz -9fe6101b3797919bd7337ee5ce591954f85d59db7ae88983904db29fd64c3dd1 go1.24.3.freebsd-386.tar.gz -6ccf4cca287e90cc28cd7954b6172f5d177a17e20b072b65f7f39636c325e2fb go1.24.3.freebsd-amd64.tar.gz -ce45ebf389066f82a7b056b66dd650efb51fde6f8bf92a2a3ab6990f02788ebf go1.24.3.freebsd-arm.tar.gz -8f6494a12a874d0ea57c67987829359e016960ce3ba0673273609d6ac2af589a go1.24.3.freebsd-arm64.tar.gz -f9db392560cf0851f0bc8f2190e1978e01b4603038c27fecfc8658a695b71616 go1.24.3.freebsd-riscv64.tar.gz -01717fff64c5d98457272002fa825d0a15e307bf6e189f2b0c23817fa033b61c go1.24.3.illumos-amd64.tar.gz -41b1051063e68cbd2b919bf12326764fe33937cf1d32b5c529dd1a4f43dce578 go1.24.3.linux-386.tar.gz -3333f6ea53afa971e9078895eaa4ac7204a8c6b5c68c10e6bc9a33e8e391bdd8 go1.24.3.linux-amd64.tar.gz -a463cb59382bd7ae7d8f4c68846e73c4d589f223c589ac76871b66811ded7836 go1.24.3.linux-arm64.tar.gz -17a392d7e826625dd12a32099df0b00b85c32d8132ed86fe917183ee5c3f88ed go1.24.3.linux-armv6l.tar.gz -e4b003c04c902edc140153d279b42167f1ad7c229f48f1f729bbef5e65e88d1f go1.24.3.linux-loong64.tar.gz -1c79d89edf835edf9d4336ccea7cb89bc5c0ca82b12b36b218d599a5400d60fe go1.24.3.linux-mips.tar.gz -0b64fe147d69f4d681d8e8a035c760477531432f83d831f18d37cb9bf3652488 go1.24.3.linux-mips64.tar.gz -396b784c255b64512dc00c302c053e43a3cbfc77518664c6ac5569aafad4d1e6 go1.24.3.linux-mips64le.tar.gz -93898313887f14e8efbe9d7386d5da4792b2d6c492bee562993fd4c9daa75c6d go1.24.3.linux-mipsle.tar.gz -873ae3a6a6655a7b6f820e095d9965507e8dfd3cf76bc92d75c564ecbca385f6 go1.24.3.linux-ppc64.tar.gz -341a749d168f47b1d4dad25e32cae70849b7ceed7c290823b853c9e6b0df0856 go1.24.3.linux-ppc64le.tar.gz -fa482f53ccb4ba280316b8c5751ea67291507280d9166f2a38fe4d9b5d5fb64b go1.24.3.linux-riscv64.tar.gz -a87b0c2a079a0bece1620fb29a00e02b4dba17507850f837e754af7d57cda282 go1.24.3.linux-s390x.tar.gz -63155382308db1306200aff7821aa26bf2a2dda23537dd637a9704b485b6ddf0 go1.24.3.netbsd-386.tar.gz -fe2c5c79482958b867c08a4fc2a10a998de9c0206b08d5b3ebcb2232e8d2777c go1.24.3.netbsd-amd64.tar.gz -e8ff77aef21521b5dd94e44282a3243309b80717414cf12f72835a45886a049f go1.24.3.netbsd-arm.tar.gz -b337fbaf82822685940ffaa76fbcf4be5d2f0258bc819cd80bc408b491f45c04 go1.24.3.netbsd-arm64.tar.gz -c1bb9dd8418480aa7f65452b08de3759da3bf89702be71b5a9fc084836b24ad5 go1.24.3.openbsd-386.tar.gz -531218de748b0caaf6d1ad18921206fc12baaa89bf483a0a5e60a571c206fe6f go1.24.3.openbsd-amd64.tar.gz -bcd0dc959986fc346969b5d4111c3c8031882d8bf8d87a2c2ecf1328962a91f2 go1.24.3.openbsd-arm.tar.gz -00ee6f8f1c41fd2e28ad386bd7e39acce7cab84af6de835855b29d1c597335c4 go1.24.3.openbsd-arm64.tar.gz -9f4ec0a9203ed3c54ce1a2a390ad3d45838cdb7efd85baeff857e37dfde04edd go1.24.3.openbsd-ppc64.tar.gz -da4d6f80e2373250d8c31c32dcd1e08775c327c0d610923604660cc0e07e8cba go1.24.3.openbsd-riscv64.tar.gz -f5d02149132eedda6c2d46b360d7da462b8a5f9e3f8567db100c2d7bff0ddcd7 go1.24.3.plan9-386.tar.gz -175f3d79f4762a3c545d2c6393bf6b8bac24e838026869dafab06b930735c94f go1.24.3.plan9-amd64.tar.gz -d1e4ac15095da1611659261c2228c2058756cf87d61d9fad262f76755ef26849 go1.24.3.plan9-arm.tar.gz -e644220a6ced3c07a7acc1364193cb709a97737dd8b6792a07a8ec6d9996713e go1.24.3.solaris-amd64.tar.gz -0d7e7dc0a31ba0cdd487415709d03b02fc9490ef111e8dfd22788a6d63316f37 go1.24.3.windows-386.msi -c27c463a61ab849266baa0c17a6c5c4256a574ab642f609ba25c96ec965dc184 go1.24.3.windows-386.zip -d5b7637e7e138be877d96a4501709d480e050d86a8f402bc950e72112b5aedc5 go1.24.3.windows-amd64.msi -be9787cb08998b1860fe3513e48a5fe5b96302d358a321b58e651184fa9638b3 go1.24.3.windows-amd64.zip -7efde2e5e8468e9caf2c7fc94f4da78a726a5031a1ed63acff7899527cdddff6 go1.24.3.windows-arm64.msi -eec9fa736056b54dd88ecb669db2bfad39b0c48f6f9080f036dfa1ca42dc4bb5 go1.24.3.windows-arm64.zip +5a86a83a31f9fa81490b8c5420ac384fd3d95a3e71fba665c7b3f95d1dfef2b4 go1.24.4.src.tar.gz +0d2af78e3b6e08f8013dbbdb26ae33052697b6b72e03ec17d496739c2a1aed68 go1.24.4.aix-ppc64.tar.gz +69bef555e114b4a2252452b6e7049afc31fbdf2d39790b669165e89525cd3f5c go1.24.4.darwin-amd64.tar.gz +c4d74453a26f488bdb4b0294da4840d9020806de4661785334eb6d1803ee5c27 go1.24.4.darwin-amd64.pkg +27973684b515eaf461065054e6b572d9390c05e69ba4a423076c160165336470 go1.24.4.darwin-arm64.tar.gz +2fe1f8746745c4bfebd494583aaef24cad42594f6d25ed67856879d567ee66e7 go1.24.4.darwin-arm64.pkg +70b2de9c1cafe5af7be3eb8f80753cce0501ef300db3f3bd59be7ccc464234e1 go1.24.4.dragonfly-amd64.tar.gz +8d529839db29ee171505b89dc9c3de76003a4ab56202d84bddbbecacbfb6d7c9 go1.24.4.freebsd-386.tar.gz +6cbc3ad6cc21bdcc7283824d3ac0e85512c02022f6a35eb2e844882ea6e8448c go1.24.4.freebsd-amd64.tar.gz +d49ae050c20aff646a7641dd903f03eb674570790b90ffb298076c4d41e36655 go1.24.4.freebsd-arm.tar.gz +e31924abef2a28456b7103c0a5d333dcc11ecf19e76d5de1a383ad5fe0b42457 go1.24.4.freebsd-arm64.tar.gz +b5bca135eae8ebddf22972611ac1c58ae9fbb5979fd953cc5245c5b1b2517546 go1.24.4.freebsd-riscv64.tar.gz +7d5efda511ff7e3114b130acee5d0bffbb078fedbfa9b2c1b6a807107e1ca23a go1.24.4.illumos-amd64.tar.gz +130c9b061082eca15513e595e9952a2ded32e737e609dd0e49f7dfa74eba026d go1.24.4.linux-386.tar.gz +77e5da33bb72aeaef1ba4418b6fe511bc4d041873cbf82e5aa6318740df98717 go1.24.4.linux-amd64.tar.gz +d5501ee5aca0f258d5fe9bfaed401958445014495dc115f202d43d5210b45241 go1.24.4.linux-arm64.tar.gz +6a554e32301cecae3162677e66d4264b81b3b1a89592dd1b7b5c552c7a49fe37 go1.24.4.linux-armv6l.tar.gz +b208eb25fe244408cbe269ed426454bc46e59d0e0a749b6240d39e884e969875 go1.24.4.linux-loong64.tar.gz +fddfcb28fd36fe63d2ae181026798f86f3bbd3a7bb0f1e1f617dd3d604bf3fe4 go1.24.4.linux-mips.tar.gz +7934b924d5ab8c8ae3134a09a6ae74d3c39f63f6c4322ec289364dbbf0bac3ca go1.24.4.linux-mips64.tar.gz +fa763d8673f94d6e534bb72c3cf675d4c2b8da4a6da42a89f08c5586106db39c go1.24.4.linux-mips64le.tar.gz +84363dbfe49b41d43df84420a09bd53a4770053d63bfa509868c46a5f8eb3ff7 go1.24.4.linux-mipsle.tar.gz +28fcbd5d3b56493606873c33f2b4bdd84ba93c633f37313613b5a1e6495c6fe5 go1.24.4.linux-ppc64.tar.gz +9ca4afef813a2578c23843b640ae0290aa54b2e3c950a6cc4c99e16a57dec2ec go1.24.4.linux-ppc64le.tar.gz +1d7034f98662d8f2c8abd7c700ada4093acb4f9c00e0e51a30344821d0785c77 go1.24.4.linux-riscv64.tar.gz +0449f3203c39703ab27684be763e9bb78ca9a051e0e4176727aead9461b6deb5 go1.24.4.linux-s390x.tar.gz +954b49ccc2cfcf4b5f7cd33ff662295e0d3b74e7590c8e25fc2abb30bce120ba go1.24.4.netbsd-386.tar.gz +370fabcdfee7c18857c96fdd5b706e025d4fb86a208da88ba56b1493b35498e9 go1.24.4.netbsd-amd64.tar.gz +7935ef95d4d1acc48587b1eb4acab98b0a7d9569736a32398b9c1d2e89026865 go1.24.4.netbsd-arm.tar.gz +ead78fd0fa29fbb176cc83f1caa54032e1a44f842affa56a682c647e0759f237 go1.24.4.netbsd-arm64.tar.gz +913e217394b851a636b99de175f0c2f9ab9938b41c557f047168f77ee485d776 go1.24.4.openbsd-386.tar.gz +24568da3dcbcdb24ec18b631f072faf0f3763e3d04f79032dc56ad9ec35379c4 go1.24.4.openbsd-amd64.tar.gz +45abf523f870632417ab007de3841f64dd906bde546ffc8c6380ccbe91c7fb73 go1.24.4.openbsd-arm.tar.gz +7c57c69b5dd1e946b28a3034c285240a48e2861bdcb50b7d9c0ed61bcf89c879 go1.24.4.openbsd-arm64.tar.gz +91ed711f704829372d6931e1897631ef40288b8f9e3cd6ef4a24df7126d1066a go1.24.4.openbsd-ppc64.tar.gz +de5e270d971c8790e8880168d56a2ea103979927c10ded136d792bbdf9bce3d3 go1.24.4.openbsd-riscv64.tar.gz +ff429d03f00bcd32a50f445320b8329d0fadb2a2fff899c11e95e0922a82c543 go1.24.4.plan9-386.tar.gz +39d6363a43fd16b60ae9ad7346a264e982e4fa653dee3b45f83e03cd2f7a6647 go1.24.4.plan9-amd64.tar.gz +1964ae2571259de77b930e97f2891aa92706ff81aac9909d45bb107b0fab16c8 go1.24.4.plan9-arm.tar.gz +a7f9af424e8fb87886664754badca459513f64f6a321d17f1d219b8edf519821 go1.24.4.solaris-amd64.tar.gz +d454d3cb144432f1726bf00e28c6017e78ccb256a8d01b8e3fb1b2e6b5650f28 go1.24.4.windows-386.zip +966ecace1cdbb3497a2b930bdb0f90c3ad32922fa1a7c655b2d4bbeb7e4ac308 go1.24.4.windows-386.msi +b751a1136cb9d8a2e7ebb22c538c4f02c09b98138c7c8bfb78a54a4566c013b1 go1.24.4.windows-amd64.zip +0cbb6e83865747dbe69b3d4155f92e88fcf336ff5d70182dba145e9d7bd3d8f6 go1.24.4.windows-amd64.msi +d17da51bc85bd010754a4063215d15d2c033cc289d67ca9201a03c9041b2969d go1.24.4.windows-arm64.zip +47dbe734b6a829de45654648a7abcf05bdceef5c80e03ea0b208eeebef75a852 go1.24.4.windows-arm64.msi # version:golangci 2.0.2 # https://github.com/golangci/golangci-lint/releases/ diff --git a/core/rawdb/database.go b/core/rawdb/database.go index 86f4ac19cb..8854336327 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -667,7 +667,6 @@ func SafeDeleteRange(db ethdb.KeyValueStore, start, end []byte, hashScheme bool, var ( count, deleted, skipped int - buff = crypto.NewKeccakState() 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 { // 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 { return err } diff --git a/core/rawdb/database_test.go b/core/rawdb/database_test.go deleted file mode 100644 index a0d7b5ec66..0000000000 --- a/core/rawdb/database_test.go +++ /dev/null @@ -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 . - -package rawdb diff --git a/core/state/dump.go b/core/state/dump.go index 11b5c32782..3af9133f5b 100644 --- a/core/state/dump.go +++ b/core/state/dump.go @@ -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) 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) diff --git a/core/state/reader.go b/core/state/reader.go index 09edf6ab8d..695521a71e 100644 --- a/core/state/reader.go +++ b/core/state/reader.go @@ -204,9 +204,8 @@ func (r *flatReader) Storage(addr common.Address, key common.Hash) (common.Hash, // // trieReader is safe for concurrent read. type trieReader struct { - root common.Hash // State root which uniquely represent a state - db *triedb.Database // Database for loading trie - buff crypto.KeccakState // Buffer for keccak256 hashing + root common.Hash // State root which uniquely represent a state + db *triedb.Database // Database for loading trie // Main trie, resolved in constructor. Note either the Merkle-Patricia-tree // 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{ root: root, db: db, - buff: crypto.NewKeccakState(), mainTrie: tr, subRoots: make(map[common.Address]common.Hash), 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] } 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 { return common.Hash{}, err } diff --git a/core/state/state_object.go b/core/state/state_object.go index a6979bd361..73a3b5146c 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -377,7 +377,6 @@ func (s *stateObject) updateRoot() { // fulfills the storage diffs into the given accountUpdate struct. func (s *stateObject) commitStorage(op *accountUpdate) { var ( - buf = crypto.NewKeccakState() encode = func(val common.Hash) []byte { if val == (common.Hash{}) { return nil @@ -394,7 +393,7 @@ func (s *stateObject) commitStorage(op *accountUpdate) { if val == s.originStorage[key] { continue } - hash := crypto.HashData(buf, key[:]) + hash := crypto.Keccak256Hash(key[:]) if op.storages == nil { op.storages = make(map[common.Hash][]byte) } diff --git a/core/state/statedb.go b/core/state/statedb.go index 62f984de56..6b474ea0a4 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -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) { var ( nodes []*trienode.NodeSet - buf = crypto.NewKeccakState() deletes = make(map[common.Hash]*accountDelete) ) for addr, prevObj := range s.stateObjectsDestruct { @@ -1079,7 +1078,7 @@ func (s *StateDB) handleDestruction(noStorageWiping bool) (map[common.Hash]*acco continue } // 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{ address: addr, origin: types.SlimAccountRLP(*prev), diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 8dd7b9f056..92a4e7d016 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -459,6 +459,8 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 { minPrice = 500 if maxLenOver32 { gas.Add(gas, gas) + } else { + gas = big.NewInt(16) } } diff --git a/crypto/bn256/cloudflare/mul_arm64.h b/crypto/bn256/cloudflare/mul_arm64.h index d405eb8f72..14f879c380 100644 --- a/crypto/bn256/cloudflare/mul_arm64.h +++ b/crypto/bn256/cloudflare/mul_arm64.h @@ -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) \ MUL R1, R5, c0 \ UMULH R1, R5, c1 \ @@ -16,54 +20,54 @@ UMULH R2, R5, R26 \ MUL R2, R6, R0 \ ADDS R0, R26 \ - UMULH R2, R6, R27 \ + UMULH R2, R6, c6 \ MUL R2, R7, R0 \ - ADCS R0, R27 \ - UMULH R2, R7, R29 \ + ADCS R0, c6 \ + UMULH R2, R7, c7 \ MUL R2, R8, R0 \ - ADCS R0, R29 \ + ADCS R0, c7 \ UMULH R2, R8, c5 \ ADCS ZR, c5 \ ADDS R1, c1 \ ADCS R26, c2 \ - ADCS R27, c3 \ - ADCS R29, c4 \ + ADCS c6, c3 \ + ADCS c7, c4 \ ADCS ZR, c5 \ \ MUL R3, R5, R1 \ UMULH R3, R5, R26 \ MUL R3, R6, R0 \ ADDS R0, R26 \ - UMULH R3, R6, R27 \ + UMULH R3, R6, R2 \ MUL R3, R7, R0 \ - ADCS R0, R27 \ - UMULH R3, R7, R29 \ + ADCS R0, R2 \ + UMULH R3, R7, c7 \ MUL R3, R8, R0 \ - ADCS R0, R29 \ + ADCS R0, c7 \ UMULH R3, R8, c6 \ ADCS ZR, c6 \ ADDS R1, c2 \ ADCS R26, c3 \ - ADCS R27, c4 \ - ADCS R29, c5 \ + ADCS R2, c4 \ + ADCS c7, c5 \ ADCS ZR, c6 \ \ MUL R4, R5, R1 \ UMULH R4, R5, R26 \ MUL R4, R6, R0 \ ADDS R0, R26 \ - UMULH R4, R6, R27 \ + UMULH R4, R6, R2 \ MUL R4, R7, R0 \ - ADCS R0, R27 \ - UMULH R4, R7, R29 \ + ADCS R0, R2 \ + UMULH R4, R7, R3 \ MUL R4, R8, R0 \ - ADCS R0, R29 \ + ADCS R0, R3 \ UMULH R4, R8, c7 \ ADCS ZR, c7 \ ADDS R1, c3 \ ADCS R26, c4 \ - ADCS R27, c5 \ - ADCS R29, c6 \ + ADCS R2, c5 \ + ADCS R3, c6 \ ADCS ZR, c7 #define gfpReduce() \ diff --git a/crypto/bn256/gnark/g1.go b/crypto/bn256/gnark/g1.go index 2f933dd536..59e04cb247 100644 --- a/crypto/bn256/gnark/g1.go +++ b/crypto/bn256/gnark/g1.go @@ -1,6 +1,7 @@ package bn256 import ( + "errors" "math/big" "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` // -// Note: whether the deserialization is of a compressed -// or an uncompressed point, is encoded in the bytes. -// -// For our purpose, the point will always be serialized -// as uncompressed, ie 64 bytes. +// The input is expected to be in the EVM format: +// 64 bytes: [32-byte x coordinate][32-byte y coordinate] +// where each coordinate is in big-endian format. // // This method also checks whether the point is on the // curve and in the prime order subgroup. 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. // -// 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 { - 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 } diff --git a/crypto/bn256/gnark/g2.go b/crypto/bn256/gnark/g2.go index 205373a591..07452cc2d8 100644 --- a/crypto/bn256/gnark/g2.go +++ b/crypto/bn256/gnark/g2.go @@ -1,6 +1,8 @@ package bn256 import ( + "errors" + "github.com/consensys/gnark-crypto/ecc/bn254" ) @@ -18,21 +20,66 @@ type G2 struct { // Unmarshal deserializes `buf` into `g` // -// Note: whether the deserialization is of a compressed -// or an uncompressed point, is encoded in the bytes. -// -// For our purpose, the point will always be serialized -// as uncompressed, ie 128 bytes. +// The input is expected to be in the EVM format: +// 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. // // This method also checks whether the point is on the // curve and in the prime order subgroup. 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. // -// 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 { - 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 } diff --git a/crypto/bn256/gnark/native_format_test.go b/crypto/bn256/gnark/native_format_test.go new file mode 100644 index 0000000000..e2b6744932 --- /dev/null +++ b/crypto/bn256/gnark/native_format_test.go @@ -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") + } +} diff --git a/crypto/bn256/google/bn256.go b/crypto/bn256/google/bn256.go index aca9cf62de..e427b8bf42 100644 --- a/crypto/bn256/google/bn256.go +++ b/crypto/bn256/google/bn256.go @@ -128,7 +128,7 @@ func (e *G1) Marshal() []byte { func (e *G1) Unmarshal(m []byte) ([]byte, error) { // Each value is a 256-bit number. const numBytes = 256 / 8 - if len(m) != 2*numBytes { + if len(m) < 2*numBytes { return nil, errors.New("bn256: not enough data") } // Unmarshal the points and check their caps @@ -253,7 +253,7 @@ func (n *G2) Marshal() []byte { func (e *G2) Unmarshal(m []byte) ([]byte, error) { // Each value is a 256-bit number. const numBytes = 256 / 8 - if len(m) != 4*numBytes { + if len(m) < 4*numBytes { return nil, errors.New("bn256: not enough data") } // Unmarshal the points and check their caps diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go index 5b0c9c0533..e620d6ee3a 100644 --- a/crypto/crypto_test.go +++ b/crypto/crypto_test.go @@ -19,6 +19,7 @@ package crypto import ( "bytes" "crypto/ecdsa" + "crypto/rand" "encoding/hex" "math/big" "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", 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[:]) + } +} diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index cbbdbbb361..e835344ca1 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -283,8 +283,14 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl // that should be fixed, not papered over. header := api.remoteBlocks.get(update.HeadBlockHash) if header == nil { - log.Warn("Forkchoice requested unknown head", "hash", update.HeadBlockHash) - return engine.STATUS_SYNCING, nil + 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 + } + api.remoteBlocks.put(retrievedHead.Hash(), retrievedHead) + header = retrievedHead } // If the finalized hash is known, we can direct the downloader to move // potentially more data to the freezer from the get go. diff --git a/eth/downloader/beacondevsync.go b/eth/downloader/beacondevsync.go index 9a38fedd46..0032eb53b9 100644 --- a/eth/downloader/beacondevsync.go +++ b/eth/downloader/beacondevsync.go @@ -21,6 +21,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" "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") default: } - // Pick a random peer to sync from and keep retrying if none are yet - // available due to fresh startup - d.peers.lock.RLock() - var peer *peerConnection - for _, peer = range d.peers.peers { - break - } - d.peers.lock.RUnlock() - - if peer == nil { + header, err := d.GetHeader(hash) + if err != nil { time.Sleep(time.Second) 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 // 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) if err != nil || len(headers) != 1 { - log.Warn("Failed to fetch sync target", "headers", len(headers), "err", err) - time.Sleep(time.Second) continue } // Head header retrieved, if the hash matches, start the actual sync if metas[0] != hash { - log.Error("Received invalid sync target", "want", hash, "have", metas[0]) - time.Sleep(time.Second) + log.Warn("Received invalid sync target", "peer", peer.id, "want", hash, "have", metas[0]) continue } - return d.BeaconSync(mode, headers[0], headers[0]) + return headers[0], nil } + return nil, errors.New("failed to fetch sync target") } diff --git a/eth/tracers/internal/tracetest/calltrace_test.go b/eth/tracers/internal/tracetest/calltrace_test.go index b2486661e4..70da34f427 100644 --- a/eth/tracers/internal/tracetest/calltrace_test.go +++ b/eth/tracers/internal/tracetest/calltrace_test.go @@ -321,7 +321,7 @@ func TestInternals(t *testing.T) { byte(vm.LOG0), }, 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 @@ -340,7 +340,7 @@ func TestInternals(t *testing.T) { byte(vm.LOG0), }, 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) { diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code.json index d60c3d7385..5601ac797a 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code.json @@ -59,8 +59,8 @@ }, "result": { "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": { - "balance": "0x0", - "nonce": 22 + "balance":"0x0", + "nonce":22 }, "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { "balance": "0x4d87094125a369d9bd5", @@ -75,9 +75,6 @@ "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { "balance": "0x1780d77678137ac1b775", "nonce": 29072 - }, - "0x1585936b53834b021f68cc13eeefdec2efc8e724": { - "balance": "0x0" } } } diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code_and_storage.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code_and_storage.json index b37dfa90a1..310a6696b8 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code_and_storage.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code_and_storage.json @@ -70,9 +70,6 @@ "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { "balance": "0x1780d77678137ac1b775", "nonce": 29072 - }, - "0x1585936b53834b021f68cc13eeefdec2efc8e724": { - "balance": "0x0" } } } diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_storage.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_storage.json index 43d6e03b44..c0cb05a2a2 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_storage.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_storage.json @@ -70,9 +70,6 @@ "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { "balance": "0x1780d77678137ac1b775", "nonce": 29072 - }, - "0x1585936b53834b021f68cc13eeefdec2efc8e724": { - "balance": "0x0" } } } diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/enable_empty.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/enable_empty.json new file mode 100644 index 0000000000..00b4c66c23 --- /dev/null +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/enable_empty.json @@ -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" + } + } +} diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json index 9811f87c4f..bbfdae306e 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json @@ -28,7 +28,7 @@ "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { "balance": "0x1780d77678137ac1b775", "code": "0x", - "nonce": "29072", + "nonce": 29072, "storage": {} } }, @@ -74,9 +74,6 @@ "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { "balance": "0x1780d77678137ac1b775", "nonce": 29072 - }, - "0x1585936b53834b021f68cc13eeefdec2efc8e724": { - "balance": "0x0" } } } diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json index 22932ebc95..be4981b8b8 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json @@ -64,9 +64,6 @@ "balance": "0x0", "nonce": 22 }, - "0x1585936b53834b021f68cc13eeefdec2efc8e724": { - "balance": "0x0" - }, "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { "balance": "0x4d87094125a369d9bd5", "nonce": 1, diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple_disable_code_and_storage.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple_disable_code_and_storage.json index 5f939ba2df..502149de43 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple_disable_code_and_storage.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple_disable_code_and_storage.json @@ -63,9 +63,6 @@ "balance": "0x0", "nonce": 22 }, - "0x1585936b53834b021f68cc13eeefdec2efc8e724": { - "balance": "0x0" - }, "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { "balance": "0x4d87094125a369d9bd5", "nonce": 1, diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index e04b77f61f..a2d598adaa 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -19,6 +19,7 @@ package native import ( "bytes" "encoding/json" + "errors" "math/big" "sync/atomic" @@ -75,6 +76,7 @@ type prestateTracerConfig struct { 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 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) { @@ -82,6 +84,11 @@ func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *p if err := json.Unmarshal(cfg, &config); err != nil { 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{ pre: stateMap{}, post: stateMap{}, @@ -177,11 +184,14 @@ func (t *prestateTracer) OnTxEnd(receipt *types.Receipt, err error) { if t.config.DiffMode { t.processDiffState() } - // the new created contracts' prestate were empty, so delete them - for a := range t.created { - // the created contract maybe exists in statedb before the creating tx - if s := t.pre[a]; s != nil && s.empty { - delete(t.pre, a) + // Remove accounts that were empty prior to execution. Unless + // user requested to include empty accounts. + if t.config.IncludeEmpty { + return + } + for addr, s := range t.pre { + if s.empty { + delete(t.pre, addr) } } } diff --git a/ethdb/pebble/pebble.go b/ethdb/pebble/pebble.go index aa9eca9c92..ef687bd464 100644 --- a/ethdb/pebble/pebble.go +++ b/ethdb/pebble/pebble.go @@ -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 // flushed at the background if the accumulated size exceeds this threshold. 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 // for more details. diff --git a/go.mod b/go.mod index 6c192c85d7..c3b27d405e 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/cespare/cp v0.1.0 github.com/cloudflare/cloudflare-go v0.114.0 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-ipa v0.0.0-20240724233137-53bbb0ceb27a github.com/davecgh/go-spew v1.1.1 @@ -64,11 +64,11 @@ require ( github.com/urfave/cli/v2 v2.27.5 go.uber.org/automaxprocs v1.5.2 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/sync v0.11.0 - golang.org/x/sys v0.30.0 - golang.org/x/text v0.22.0 + golang.org/x/sync v0.12.0 + golang.org/x/sys v0.31.0 + golang.org/x/text v0.23.0 golang.org/x/time v0.9.0 golang.org/x/tools v0.29.0 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/redact v1.1.5 // 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/deepmap/oapi-codegen v1.6.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/mitchellh/mapstructure v1.4.1 // 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/opentracing/opentracing-go v1.1.0 // 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/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // 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 - rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index c91e349656..6f31f96ec2 100644 --- a/go.sum +++ b/go.sum @@ -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/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/consensys/bavard v0.1.27 h1:j6hKUrGAy/H+gpNrpLU3I26n1yc+VMGmd6ID5+gAhOs= -github.com/consensys/bavard v0.1.27/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= -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/consensys/gnark-crypto v0.18.0 h1:vIye/FqI50VeAr0B3dx+YjeIvmc3LWz4yEfbWBpTUf0= +github.com/consensys/gnark-crypto v0.18.0/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c= 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/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/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/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/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= 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/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= 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.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.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +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/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= 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.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= 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.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +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-20181221193216-37e7f081c4d4/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-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.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +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-20190215142949-d0b11bdaac8a/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.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.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +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-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.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.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +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-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 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= diff --git a/metrics/counter.go b/metrics/counter.go index 0f373b0d92..c884e9a178 100644 --- a/metrics/counter.go +++ b/metrics/counter.go @@ -7,10 +7,7 @@ import ( // GetOrRegisterCounter returns an existing Counter or constructs and registers // a new Counter. func GetOrRegisterCounter(name string, r Registry) *Counter { - if r == nil { - r = DefaultRegistry - } - return r.GetOrRegister(name, NewCounter).(*Counter) + return getOrRegister(name, NewCounter, r) } // NewCounter constructs a new Counter. diff --git a/metrics/counter_float64.go b/metrics/counter_float64.go index 91c4215c4d..6cc73d89a2 100644 --- a/metrics/counter_float64.go +++ b/metrics/counter_float64.go @@ -8,10 +8,7 @@ import ( // GetOrRegisterCounterFloat64 returns an existing *CounterFloat64 or constructs and registers // a new CounterFloat64. func GetOrRegisterCounterFloat64(name string, r Registry) *CounterFloat64 { - if nil == r { - r = DefaultRegistry - } - return r.GetOrRegister(name, NewCounterFloat64).(*CounterFloat64) + return getOrRegister(name, NewCounterFloat64, r) } // NewCounterFloat64 constructs a new CounterFloat64. diff --git a/metrics/gauge.go b/metrics/gauge.go index ba7843e03b..20de95255b 100644 --- a/metrics/gauge.go +++ b/metrics/gauge.go @@ -11,10 +11,7 @@ func (g GaugeSnapshot) Value() int64 { return int64(g) } // GetOrRegisterGauge returns an existing Gauge or constructs and registers a // new Gauge. func GetOrRegisterGauge(name string, r Registry) *Gauge { - if r == nil { - r = DefaultRegistry - } - return r.GetOrRegister(name, NewGauge).(*Gauge) + return getOrRegister(name, NewGauge, r) } // NewGauge constructs a new Gauge. diff --git a/metrics/gauge_float64.go b/metrics/gauge_float64.go index 05b401ef9c..48524e4c3f 100644 --- a/metrics/gauge_float64.go +++ b/metrics/gauge_float64.go @@ -8,10 +8,7 @@ import ( // GetOrRegisterGaugeFloat64 returns an existing GaugeFloat64 or constructs and registers a // new GaugeFloat64. func GetOrRegisterGaugeFloat64(name string, r Registry) *GaugeFloat64 { - if nil == r { - r = DefaultRegistry - } - return r.GetOrRegister(name, NewGaugeFloat64()).(*GaugeFloat64) + return getOrRegister(name, NewGaugeFloat64, r) } // GaugeFloat64Snapshot is a read-only copy of a GaugeFloat64. diff --git a/metrics/gauge_info.go b/metrics/gauge_info.go index 1862ed55c5..34ac917919 100644 --- a/metrics/gauge_info.go +++ b/metrics/gauge_info.go @@ -16,10 +16,7 @@ func (val GaugeInfoValue) String() string { // GetOrRegisterGaugeInfo returns an existing GaugeInfo or constructs and registers a // new GaugeInfo. func GetOrRegisterGaugeInfo(name string, r Registry) *GaugeInfo { - if nil == r { - r = DefaultRegistry - } - return r.GetOrRegister(name, NewGaugeInfo()).(*GaugeInfo) + return getOrRegister(name, NewGaugeInfo, r) } // NewGaugeInfo constructs a new GaugeInfo. diff --git a/metrics/histogram.go b/metrics/histogram.go index 7c27bcc928..18bf6e3d2b 100644 --- a/metrics/histogram.go +++ b/metrics/histogram.go @@ -23,19 +23,13 @@ type Histogram interface { // GetOrRegisterHistogram returns an existing Histogram or constructs and // registers a new StandardHistogram. func GetOrRegisterHistogram(name string, r Registry, s Sample) Histogram { - if nil == r { - r = DefaultRegistry - } - return r.GetOrRegister(name, func() Histogram { return NewHistogram(s) }).(Histogram) + return getOrRegister(name, func() Histogram { return NewHistogram(s) }, r) } // GetOrRegisterHistogramLazy returns an existing Histogram or constructs and // registers a new StandardHistogram. func GetOrRegisterHistogramLazy(name string, r Registry, s func() Sample) Histogram { - if nil == r { - r = DefaultRegistry - } - return r.GetOrRegister(name, func() Histogram { return NewHistogram(s()) }).(Histogram) + return getOrRegister(name, func() Histogram { return NewHistogram(s()) }, r) } // NewHistogram constructs a new StandardHistogram from a Sample. diff --git a/metrics/meter.go b/metrics/meter.go index 197e5abbed..ee23af10eb 100644 --- a/metrics/meter.go +++ b/metrics/meter.go @@ -12,10 +12,7 @@ import ( // Be sure to unregister the meter from the registry once it is of no use to // allow for garbage collection. func GetOrRegisterMeter(name string, r Registry) *Meter { - if r == nil { - r = DefaultRegistry - } - return r.GetOrRegister(name, NewMeter).(*Meter) + return getOrRegister(name, NewMeter, r) } // NewMeter constructs a new Meter and launches a goroutine. diff --git a/metrics/registry.go b/metrics/registry.go index 527da6238d..6070f3d0e9 100644 --- a/metrics/registry.go +++ b/metrics/registry.go @@ -3,7 +3,6 @@ package metrics import ( "errors" "fmt" - "reflect" "sort" "strings" "sync" @@ -30,10 +29,9 @@ type Registry interface { // GetAll metrics in the Registry. GetAll() map[string]map[string]interface{} - // GetOrRegister gets an existing metric or registers the given one. - // The interface can be the metric to register if not found in registry, - // or a function returning the metric for lazy instantiation. - GetOrRegister(string, interface{}) interface{} + // GetOrRegister returns an existing metric or registers the one returned + // by the given constructor. + GetOrRegister(string, func() interface{}) interface{} // Register the given metric under the given name. Register(string, interface{}) error @@ -95,19 +93,13 @@ func (r *StandardRegistry) Get(name string) interface{} { // alternative to calling Get and Register on failure. // The interface can be the metric to register if not found in registry, // 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 cached, ok := r.metrics.Load(name) if ok { return cached } - if v := reflect.ValueOf(i); v.Kind() == reflect.Func { - i = v.Call(nil)[0].Interface() - } - item, _, ok := r.loadOrRegister(name, i) - if !ok { - return i - } + item, _, _ := r.loadOrRegister(name, ctor()) return item } @@ -120,9 +112,6 @@ func (r *StandardRegistry) Register(name string, i interface{}) error { 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) if loaded { 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. // The interface can be the metric to register if not found in registry, // 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 - 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. @@ -338,10 +327,17 @@ func Get(name string) interface{} { // GetOrRegister gets an existing metric or creates and registers a new one. Threadsafe // 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) } +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 // if a metric by the given name is already registered. func Register(name string, i interface{}) error { diff --git a/metrics/registry_test.go b/metrics/registry_test.go index bdc58fee6c..6af0796da9 100644 --- a/metrics/registry_test.go +++ b/metrics/registry_test.go @@ -30,7 +30,7 @@ func benchmarkRegistryGetOrRegisterParallel(b *testing.B, amount int) { wg.Add(1) go func() { for i := 0; i < b.N; i++ { - r.GetOrRegister("foo", NewMeter) + GetOrRegisterMeter("foo", r) } wg.Done() }() @@ -98,10 +98,10 @@ func TestRegistryGetOrRegister(t *testing.T) { r := NewRegistry() // First metric wins with GetOrRegister - _ = r.GetOrRegister("foo", NewCounter()) - m := r.GetOrRegister("foo", NewGauge()) - if _, ok := m.(*Counter); !ok { - t.Fatal(m) + c1 := GetOrRegisterCounter("foo", r) + c2 := GetOrRegisterCounter("foo", r) + if c1 != c2 { + t.Fatal("counters should've matched") } i := 0 @@ -123,10 +123,10 @@ func TestRegistryGetOrRegisterWithLazyInstantiation(t *testing.T) { r := NewRegistry() // First metric wins with GetOrRegister - _ = r.GetOrRegister("foo", NewCounter) - m := r.GetOrRegister("foo", NewGauge) - if _, ok := m.(*Counter); !ok { - t.Fatal(m) + c1 := GetOrRegisterCounter("foo", r) + c2 := GetOrRegisterCounter("foo", r) + if c1 != c2 { + t.Fatal("counters should've matched") } i := 0 @@ -165,7 +165,7 @@ func TestPrefixedChildRegistryGetOrRegister(t *testing.T) { r := NewRegistry() pr := NewPrefixedChildRegistry(r, "prefix.") - _ = pr.GetOrRegister("foo", NewCounter()) + _ = GetOrRegisterCounter("foo", pr) i := 0 r.Each(func(name string, m interface{}) { @@ -182,7 +182,7 @@ func TestPrefixedChildRegistryGetOrRegister(t *testing.T) { func TestPrefixedRegistryGetOrRegister(t *testing.T) { r := NewPrefixedRegistry("prefix.") - _ = r.GetOrRegister("foo", NewCounter()) + _ = GetOrRegisterCounter("foo", r) i := 0 r.Each(func(name string, m interface{}) { diff --git a/metrics/resetting_timer.go b/metrics/resetting_timer.go index 66458bdb91..8aa7dc1488 100644 --- a/metrics/resetting_timer.go +++ b/metrics/resetting_timer.go @@ -8,10 +8,7 @@ import ( // GetOrRegisterResettingTimer returns an existing ResettingTimer or constructs and registers a // new ResettingTimer. func GetOrRegisterResettingTimer(name string, r Registry) *ResettingTimer { - if nil == r { - r = DefaultRegistry - } - return r.GetOrRegister(name, NewResettingTimer).(*ResettingTimer) + return getOrRegister(name, NewResettingTimer, r) } // NewRegisteredResettingTimer constructs and registers a new ResettingTimer. diff --git a/metrics/runtimehistogram.go b/metrics/runtimehistogram.go index 92fcbcc281..53904b2b28 100644 --- a/metrics/runtimehistogram.go +++ b/metrics/runtimehistogram.go @@ -8,11 +8,8 @@ import ( ) func getOrRegisterRuntimeHistogram(name string, scale float64, r Registry) *runtimeHistogram { - if r == nil { - r = DefaultRegistry - } constructor := func() Histogram { return newRuntimeHistogram(scale) } - return r.GetOrRegister(name, constructor).(*runtimeHistogram) + return getOrRegister(name, constructor, r).(*runtimeHistogram) } // runtimeHistogram wraps a runtime/metrics histogram. diff --git a/metrics/timer.go b/metrics/timer.go index 9df15c967a..894bdfc327 100644 --- a/metrics/timer.go +++ b/metrics/timer.go @@ -10,10 +10,7 @@ import ( // Be sure to unregister the meter from the registry once it is of no use to // allow for garbage collection. func GetOrRegisterTimer(name string, r Registry) *Timer { - if nil == r { - r = DefaultRegistry - } - return r.GetOrRegister(name, NewTimer).(*Timer) + return getOrRegister(name, NewTimer, r) } // NewCustomTimer constructs a new Timer from a Histogram and a Meter. diff --git a/node/rpcstack.go b/node/rpcstack.go index 1669901e6e..828fd8b32c 100644 --- a/node/rpcstack.go +++ b/node/rpcstack.go @@ -62,6 +62,7 @@ type rpcEndpointConfig struct { type rpcHandler struct { http.Handler + prefix string server *rpc.Server } @@ -79,11 +80,11 @@ type httpServer struct { // HTTP RPC handler things. httpConfig httpConfig - httpHandler atomic.Value // *rpcHandler + httpHandler atomic.Pointer[rpcHandler] // WebSocket handler things. wsConfig wsConfig - wsHandler atomic.Value // *rpcHandler + wsHandler atomic.Pointer[rpcHandler] // These are set by setListenAddr. endpoint string @@ -99,9 +100,6 @@ const ( 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.httpHandler.Store((*rpcHandler)(nil)) - h.wsHandler.Store((*rpcHandler)(nil)) 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 - ws := h.wsHandler.Load().(*rpcHandler) + ws := h.wsHandler.Load() if ws != nil && isWebsocket(r) { - if checkPath(r, h.wsConfig.prefix) { + if checkPath(r, ws.prefix) { ws.ServeHTTP(w, r) } return } // if http-rpc is enabled, try to serve request - rpc := h.httpHandler.Load().(*rpcHandler) + rpc := h.httpHandler.Load() if rpc != nil { // First try to route in 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 } - if checkPath(r, h.httpConfig.prefix) { + if checkPath(r, rpc.prefix) { rpc.ServeHTTP(w, r) return } @@ -298,14 +296,14 @@ func (h *httpServer) doStop() { } // Shut down the server. - httpHandler := h.httpHandler.Load().(*rpcHandler) - wsHandler := h.wsHandler.Load().(*rpcHandler) + httpHandler := h.httpHandler.Load() + wsHandler := h.wsHandler.Load() if httpHandler != nil { - h.httpHandler.Store((*rpcHandler)(nil)) + h.httpHandler.Store(nil) httpHandler.server.Stop() } if wsHandler != nil { - h.wsHandler.Store((*rpcHandler)(nil)) + h.wsHandler.Store(nil) wsHandler.server.Stop() } @@ -346,6 +344,7 @@ func (h *httpServer) enableRPC(apis []rpc.API, config httpConfig) error { h.httpConfig = config h.httpHandler.Store(&rpcHandler{ Handler: NewHTTPHandlerStack(srv, config.CorsAllowedOrigins, config.Vhosts, config.jwtSecret), + prefix: config.prefix, server: srv, }) 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. func (h *httpServer) disableRPC() bool { - handler := h.httpHandler.Load().(*rpcHandler) + handler := h.httpHandler.Load() if handler != nil { - h.httpHandler.Store((*rpcHandler)(nil)) + h.httpHandler.Store(nil) handler.server.Stop() } return handler != nil @@ -381,6 +380,7 @@ func (h *httpServer) enableWS(apis []rpc.API, config wsConfig) error { h.wsConfig = config h.wsHandler.Store(&rpcHandler{ Handler: NewWSHandlerStack(srv.WebsocketHandler(config.Origins), config.jwtSecret), + prefix: config.prefix, server: srv, }) return nil @@ -400,9 +400,9 @@ func (h *httpServer) stopWS() { // disableWS disables the WebSocket handler. This is internal, the caller must hold h.mu. func (h *httpServer) disableWS() bool { - ws := h.wsHandler.Load().(*rpcHandler) + ws := h.wsHandler.Load() if ws != nil { - h.wsHandler.Store((*rpcHandler)(nil)) + h.wsHandler.Store(nil) ws.server.Stop() } return ws != nil @@ -410,12 +410,12 @@ func (h *httpServer) disableWS() bool { // rpcAllowed returns true when JSON-RPC over HTTP is enabled. 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. 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. diff --git a/oss-fuzz.sh b/oss-fuzz.sh index 4db245a781..020b6fee27 100644 --- a/oss-fuzz.sh +++ b/oss-fuzz.sh @@ -152,6 +152,14 @@ compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bn256 \ FuzzPair fuzzBn256Pair \ $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 \ Fuzz fuzzTxfetcher \ $repo/tests/fuzzers/txfetcher/txfetcher_test.go diff --git a/tests/fuzzers/bn256/bn256_fuzz.go b/tests/fuzzers/bn256/bn256_fuzz.go index 4521f6b0db..d53bdbb4b9 100644 --- a/tests/fuzzers/bn256/bn256_fuzz.go +++ b/tests/fuzzers/bn256/bn256_fuzz.go @@ -161,6 +161,60 @@ func fuzzPair(data []byte) int { 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` // so that it can be compared with a gnark GT point. // diff --git a/tests/fuzzers/bn256/bn256_test.go b/tests/fuzzers/bn256/bn256_test.go index 8b2f962284..80fb850103 100644 --- a/tests/fuzzers/bn256/bn256_test.go +++ b/tests/fuzzers/bn256/bn256_test.go @@ -35,3 +35,15 @@ func FuzzPair(f *testing.F) { 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) + }) +} diff --git a/trie/database_test.go b/trie/database_test.go index 535f0d61b2..98fd2372ef 100644 --- a/trie/database_test.go +++ b/trie/database_test.go @@ -86,6 +86,10 @@ func (db *testDb) InsertPreimage(preimages map[common.Hash][]byte) { rawdb.WritePreimages(db.disk, preimages) } +func (db *testDb) PreimageEnabled() bool { + return true +} + func (db *testDb) Scheme() string { return db.scheme } func (db *testDb) Update(root common.Hash, parent common.Hash, nodes *trienode.MergedNodeSet) error { diff --git a/trie/secure_trie.go b/trie/secure_trie.go index 7852e16619..ac20f961e5 100644 --- a/trie/secure_trie.go +++ b/trie/secure_trie.go @@ -33,6 +33,9 @@ type preimageStore interface { // InsertPreimage commits a set of preimages along with their hashes. InsertPreimage(preimages map[common.Hash][]byte) + + // PreimageEnabled returns true if the preimage store is enabled. + PreimageEnabled() bool } // 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} // link the preimage store if it's supported - preimages, ok := db.(preimageStore) - if ok { + if preimages, ok := db.(preimageStore); ok && preimages.PreimageEnabled() { tr.preimages = preimages } return tr, nil @@ -159,7 +161,9 @@ func (t *StateTrie) GetNode(path []byte) ([]byte, int, error) { func (t *StateTrie) MustUpdate(key, value []byte) { hk := crypto.Keccak256(key) t.trie.MustUpdate(hk, value) - t.getSecKeyCache()[common.Hash(hk)] = common.CopyBytes(key) + if t.preimages != nil { + t.getSecKeyCache()[common.Hash(hk)] = common.CopyBytes(key) + } } // 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 { return err } - t.getSecKeyCache()[common.Hash(hk)] = common.CopyBytes(key) + if t.preimages != nil { + t.getSecKeyCache()[common.Hash(hk)] = common.CopyBytes(key) + } 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 { return err } - t.getSecKeyCache()[common.Hash(hk)] = address.Bytes() + if t.preimages != nil { + t.getSecKeyCache()[common.Hash(hk)] = address.Bytes() + } 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. func (t *StateTrie) MustDelete(key []byte) { hk := crypto.Keccak256(key) - delete(t.getSecKeyCache(), common.Hash(hk)) + if t.preimages != nil { + delete(t.getSecKeyCache(), common.Hash(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. func (t *StateTrie) DeleteStorage(_ common.Address, key []byte) error { hk := crypto.Keccak256(key) - delete(t.getSecKeyCache(), common.Hash(hk)) + if t.preimages != nil { + delete(t.getSecKeyCache(), common.Hash(hk)) + } return t.trie.Delete(hk) } // DeleteAccount abstracts an account deletion from the trie. func (t *StateTrie) DeleteAccount(address common.Address) error { hk := crypto.Keccak256(address.Bytes()) - delete(t.getSecKeyCache(), common.Hash(hk)) + if t.preimages != nil { + delete(t.getSecKeyCache(), common.Hash(hk)) + } return t.trie.Delete(hk) } // GetKey returns the sha3 preimage of a hashed key that was // previously used to store a value. func (t *StateTrie) GetKey(shaKey []byte) []byte { - if key, ok := t.getSecKeyCache()[common.BytesToHash(shaKey)]; ok { - return key - } if t.preimages == nil { return nil } + if key, ok := t.getSecKeyCache()[common.BytesToHash(shaKey)]; ok { + return key + } return t.preimages.Preimage(common.BytesToHash(shaKey)) } diff --git a/triedb/database.go b/triedb/database.go index 18e24cd176..1c9d49b245 100644 --- a/triedb/database.go +++ b/triedb/database.go @@ -213,6 +213,11 @@ func (db *Database) InsertPreimage(preimages map[common.Hash][]byte) { 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 // 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. diff --git a/triedb/pathdb/execute.go b/triedb/pathdb/execute.go index db1e679277..aa4bd8b44b 100644 --- a/triedb/pathdb/execute.go +++ b/triedb/pathdb/execute.go @@ -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 { // The account was present in prev-state, decode it from the // 'slim-rlp' format bytes. - h := crypto.NewKeccakState() - - addrHash := crypto.HashData(h, addr.Bytes()) + addrHash := crypto.Keccak256Hash(addr.Bytes()) prev, err := types.FullAccount(ctx.accounts[addr]) if err != nil { return err @@ -113,7 +111,7 @@ func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address) for key, val := range ctx.storages[addr] { tkey := key if ctx.rawStorageKey { - tkey = crypto.HashData(h, key.Bytes()) + tkey = crypto.Keccak256Hash(key.Bytes()) } var err error 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. func deleteAccount(ctx *context, db database.NodeDatabase, addr common.Address) error { // The account must be existent in post-state, load the account. - h := crypto.NewKeccakState() - - addrHash := crypto.HashData(h, addr.Bytes()) + addrHash := crypto.Keccak256Hash(addr.Bytes()) blob, err := ctx.accountTrie.Get(addrHash.Bytes()) if err != nil { return err @@ -173,7 +169,7 @@ func deleteAccount(ctx *context, db database.NodeDatabase, addr common.Address) } tkey := key if ctx.rawStorageKey { - tkey = crypto.HashData(h, key.Bytes()) + tkey = crypto.Keccak256Hash(key.Bytes()) } if err := st.Delete(tkey.Bytes()); err != nil { return err diff --git a/triedb/pathdb/history.go b/triedb/pathdb/history.go index aed0296da5..63c9152bf7 100644 --- a/triedb/pathdb/history.go +++ b/triedb/pathdb/history.go @@ -278,12 +278,11 @@ func newHistory(root common.Hash, parent common.Hash, block uint64, accounts map // and the hash of the storage slot key. func (h *history) stateSet() (map[common.Hash][]byte, map[common.Hash]map[common.Hash][]byte) { var ( - buff = crypto.NewKeccakState() accounts = make(map[common.Hash][]byte) storages = make(map[common.Hash]map[common.Hash][]byte) ) for addr, blob := range h.accounts { - addrHash := crypto.HashData(buff, addr.Bytes()) + addrHash := crypto.Keccak256Hash(addr.Bytes()) accounts[addrHash] = blob storage, exist := h.storages[addr] @@ -295,7 +294,7 @@ func (h *history) stateSet() (map[common.Hash][]byte, map[common.Hash]map[common } else { subset := make(map[common.Hash][]byte) for key, slot := range storage { - subset[crypto.HashData(buff, key.Bytes())] = slot + subset[crypto.Keccak256Hash(key.Bytes())] = slot } storages[addrHash] = subset }