Commit graph

10 commits

Author SHA1 Message Date
Marius van der Wijden
e94123acc2
core/rawdb: reduce allocations in rawdb.ReadHeaderNumber (#31913)
Some checks are pending
/ Linux Build (push) Waiting to run
/ Linux Build (arm) (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run
This is something interesting I came across during my benchmarks, we
spent ~3.8% of all allocations allocating the header number on the heap.

```
(pprof) list GetHeaderByHash
Total: 38197204475
ROUTINE ======================== github.com/ethereum/go-ethereum/core.(*BlockChain).GetHeaderByHash in github.com/ethereum/go-ethereum/core/blockchain_reader.go
         0 5786566117 (flat, cum) 15.15% of Total
         .          .     79:func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header {
         . 5786566117     80: return bc.hc.GetHeaderByHash(hash)
         .          .     81:}
         .          .     82:
         .          .     83:// GetHeaderByNumber retrieves a block header from the database by number,
         .          .     84:// caching it (associated with its hash) if found.
         .          .     85:func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
ROUTINE ======================== github.com/ethereum/go-ethereum/core.(*HeaderChain).GetHeaderByHash in github.com/ethereum/go-ethereum/core/headerchain.go
         0 5786566117 (flat, cum) 15.15% of Total
         .          .    404:func (hc *HeaderChain) GetHeaderByHash(hash common.Hash) *types.Header {
         . 1471264309    405: number := hc.GetBlockNumber(hash)
         .          .    406: if number == nil {
         .          .    407:  return nil
         .          .    408: }
         . 4315301808    409: return hc.GetHeader(hash, *number)
         .          .    410:}
         .          .    411:
         .          .    412:// HasHeader checks if a block header is present in the database or not.
         .          .    413:// In theory, if header is present in the database, all relative components
         .          .    414:// like td and hash->number should be present too.
(pprof) list GetBlockNumber
Total: 38197204475
ROUTINE ======================== github.com/ethereum/go-ethereum/core.(*HeaderChain).GetBlockNumber in github.com/ethereum/go-ethereum/core/headerchain.go
  94438817 1471264309 (flat, cum)  3.85% of Total
         .          .    100:func (hc *HeaderChain) GetBlockNumber(hash common.Hash) *uint64 {
  94438817   94438817    101: if cached, ok := hc.numberCache.Get(hash); ok {
         .          .    102:  return &cached
         .          .    103: }
         . 1376270828    104: number := rawdb.ReadHeaderNumber(hc.chainDb, hash)
         .          .    105: if number != nil {
         .     554664    106:  hc.numberCache.Add(hash, *number)
         .          .    107: }
         .          .    108: return number
         .          .    109:}
         .          .    110:
         .          .    111:type headerWriteResult struct {
(pprof) list ReadHeaderNumber
Total: 38197204475
ROUTINE ======================== github.com/ethereum/go-ethereum/core/rawdb.ReadHeaderNumber in github.com/ethereum/go-ethereum/core/rawdb/accessors_chain.go
 204606513 1376270828 (flat, cum)  3.60% of Total
         .          .    146:func ReadHeaderNumber(db ethdb.KeyValueReader, hash common.Hash) *uint64 {
 109577863 1281242178    147: data, _ := db.Get(headerNumberKey(hash))
         .          .    148: if len(data) != 8 {
         .          .    149:  return nil
         .          .    150: }
  95028650   95028650    151: number := binary.BigEndian.Uint64(data)
         .          .    152: return &number
         .          .    153:}
         .          .    154:
         .          .    155:// WriteHeaderNumber stores the hash->number mapping.
         .          .    156:func WriteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
```

Opening this to discuss the idea, I know that rawdb.EmptyNumber is not a
great name for the variable, open to suggestions
2025-07-15 15:48:36 +02:00
Sina M
615d29f7c2
core: reduce load on txindexer from API (#31752)
Fixes https://github.com/ethereum/go-ethereum/issues/31732.

This logic was removed in the recent refactoring in the txindexer to
handle history cutoff (#31393). It was first introduced in this PR:
https://github.com/ethereum/go-ethereum/pull/28908.

I have tested it and it works as an alternative to #31745.

This PR packs 3 changes to the flow of fetching txs from the API:

- It caches the indexer tail after each run is over to avoid hitting the
db all the time as was done originally in #28908.

- Changes `backend.GetTransaction`. It doesn't return an error anymore
when tx indexer is in progress. It shifts the responsibility to the
caller to check the progress. The reason is that in most cases we anyway
check the txpool for the tx. If it was indeed a pending tx we can avoid
the indexer progress check.

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2025-05-05 10:07:55 +08:00
Sina M
e444823394
core: fix sync reset in pruned nodes (#31638)
This is an attempt at fixing #31601. I think what happens is the startup
logic will try to get the full block body (it's `bc.loadLastState`) and
fail because genesis block has been pruned from the freezer. This will
cause it to keep repeating the reset logic, causing a deadlock.

This can happen when due to an unsuccessful sync we don't have the state
for the head (or any other state) fully, and try to redo the snap sync.

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2025-04-17 16:32:40 +08:00
rjl493456442
90d44e715d
core, eth/downloader: implement pruning mode sync (#31414)
This pull request introduces new sync logic for pruning mode. The downloader will now skip
insertion of block bodies and receipts before the configured history cutoff point.

Originally, in snap sync, the header chain and other components (bodies and receipts) were
inserted separately. However, in Proof-of-Stake, this separation is unnecessary since the
sync target is already verified by the CL.

To simplify the process, this pull request modifies `InsertReceiptChain` to insert headers
along with block bodies and receipts together. Besides, `InsertReceiptChain` doesn't have
the notion of reorg, as the common ancestor is always be found before the sync and extra
side chain is truncated at the beginning if they fall in the ancient store. The stale
canonical chain flags will always be rewritten by the new chain. Explicit reorg logic is
no longer required in `InsertReceiptChain`.
2025-04-03 15:16:35 +02:00
Sina M
8fe09df54f
cmd/geth: add prune history command (#31384)
This adds a new subcommand 'geth prune-history' that removes the pre-merge history
on supported networks. Geth is not fully ready to work in this mode, please do not run
this command on your production node.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2025-03-21 13:12:56 +01:00
Sina M
1886922264
core: respect history cutoff in txindexer (#31393)
In #31384 we unindex TXes prior to the merge block. However when the
node starts up it will try to re-index those back if the config is to index the
whole chain. This change makes the indexer aware of the history cutoff block,
avoiding reindexing in that segment.

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
Co-authored-by: Felix Lange <fjl@twurst.com>
2025-03-21 11:29:51 +01:00
Felix Lange
5d97db8d03
all: update license comments and AUTHORS (#31133) 2025-02-05 23:01:17 +01:00
Péter Szilágyi
368e16f39d
core, eth, ethstats: simplify chain head events (#30601) 2024-10-16 10:32:58 +03:00
rjl493456442
0b5d8d2b58
core: cache transaction indexing tail in memory (#28908) 2024-02-06 10:44:42 +08:00
rjl493456442
6b0de79935
core: move tx indexer to its own file (#28857)
This change moves all the transaction indexing functions to a separate txindexer.go file and defines a txIndexer structure as a refactoring.
2024-01-23 21:00:50 +01:00