erigontech / erigon

Ethereum implementation on the efficiency frontier https://erigon.gitbook.io
GNU Lesser General Public License v3.0
3.1k stars 1.09k forks source link

Reading from erigon db gives me error for several blocks starting from 20,300,000 #11683

Open 0xSorcerer opened 3 weeks ago

0xSorcerer commented 3 weeks ago

I read from erigon's DB and create a FullBlock (block that contains both transactions and their receipts) with:

var (
    chainDataDir    = "/root/.local/share/erigon/chaindata"
    snapshotDataDir = "/root/.local/share/erigon/snapshots"
    erigonDB        kv.RwDB
    erigonTX        kv.Tx
    blockReader     services.FullBlockReader
)

func OpenHistoric() {
    erigonDB = mdbx.MustOpen(chainDataDir)
    etx, err := erigonDB.BeginRo(context.Background())

    if err != nil {
        panic("Error: initializeErigon")
    }

    erigonTX = etx

    snapshots := freezeblocks.NewRoSnapshots(ethconfig.BlocksFreezing{}, snapshotDataDir, 0, log.New())
    snapshots.OptimisticReopenWithDB(erigonDB)

    blockReader = freezeblocks.NewBlockReader(snapshots, nil)
}

func CloseHistoric() {
    erigonTX.Rollback()
    erigonDB.Close()
}

func GetFullBlock(blockNumber uint64) (*aTypes.FullBlock, error) {
    block, err := blockReader.BlockByNumber(context.Background(), erigonTX, blockNumber)

    if err != nil {
        return nil, err
    }

    receipts := rawdb.ReadReceipts(erigonTX, block, []common.Address{})

    fullBlock := aTypes.MakeFullBlock(block, receipts)

    return fullBlock, nil
}

Works perfectly until I reach block 20300000:

    retriever.OpenHistoric()
    defer retriever.CloseHistoric()

    fullBlock, err := retriever.GetFullBlock(20300000)

    if err != nil {
        panic(err)
    }

    println(len(fullBlock.Transactions))

I then get the error:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0xae5492]

goroutine 1 [running]:
github.com/ledgerwatch/erigon/core/types.(*Block).Transactions(...)
        /root/atlas-erigon/erigon/core/types/block.go:1119
atlas/types.MakeFullBlock(0x0, {0x0, 0x0, 0xc0ba693eff?})
        /root/atlas-erigon/atlas/types/full_block.go:18 +0x32
atlas/retriever.GetFullBlock(0x1263a60?)
        /root/atlas-erigon/atlas/retriever/historic.go:57 +0x90
main.main()
        /root/atlas-erigon/atlas/main.go:239 +0x45
exit status 2

MakeFullBlock implementation:

func MakeFullBlock(block *types.Block, receipts types.Receipts) *FullBlock {
    transactions := []*FullTransaction{}

    txs := block.Transactions()

    for i, tx := range txs {
        transaction := MakeFullTransaction(&tx, receipts[i])
        transactions = append(transactions, transaction)
    }

    return &FullBlock{
        Hash:         block.Hash(),
        Number:       block.NumberU64(),
        Coinbase:     block.Coinbase(),
        Transactions: transactions,
    }
}

Node is synced and --internalcl flag is enabled.

Furthermore, I noticed that this goes back to working for more recent blocks, such as 20564334.

0xSorcerer commented 3 weeks ago

Upon further investigation, it looks like the function ReadHeaderRLP in erigon/core/rawdb/accessors_chain yields an empty RLP header for the block hash and number. This is very strange as when I query the node externally through RPC I get the actual header. What could be the issue?

AskAlexSharov commented 3 weeks ago

You can print in logs reason why block is nil (means - not found) by: https://github.com/erigontech/erigon/tree/main/cmd/rpcdaemon#debugging

0xSorcerer commented 3 weeks ago

I did this but the thing is that the block ISN'T nil when making a JSON rpc request to the node. It is nil (0x0 pointer) though when reading the database directly.

xuht724 commented 1 week ago

I would like ask you your go mod setting, I dose not know how to use erigon-lib and erigon simultaneously:

package main

import (
    "context"
    "fmt"

    "github.com/ledgerwatch/erigon-lib/kv"
    "github.com/ledgerwatch/erigon-lib/kv/mdbx"
)

Here is my go.mod setting

module github.com/xuht724/erigon_read_db

go 1.22.3

replace github.com/erigontech/erigon => /home/os/haotian/erigon-2.60.6

replace github.com/ledgerwatch/erigon-lib => /home/os/haotian/erigon-2.60.6/erigon-lib
AskAlexSharov commented 1 week ago

We had test about it: https://github.com/erigontech/erigon/tree/main/tests/erigon-ext-test