Snapshots: don't panic after too far reset (#4558)

* save

* save

* save

* save
This commit is contained in:
Alex Sharov 2022-06-28 10:31:44 +06:00 committed by GitHub
parent 359ae889b8
commit 538b4fea6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -6,6 +6,7 @@ import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"github.com/ledgerwatch/erigon-lib/common/dbg"
"github.com/ledgerwatch/erigon-lib/gointerfaces" "github.com/ledgerwatch/erigon-lib/gointerfaces"
"github.com/ledgerwatch/erigon-lib/gointerfaces/remote" "github.com/ledgerwatch/erigon-lib/gointerfaces/remote"
"github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv"
@ -490,6 +491,9 @@ func (back *BlockReaderWithSnapshots) headerFromSnapshot(blockHeight uint64, sn
headerOffset := sn.idxHeaderHash.OrdinalLookup(blockHeight - sn.idxHeaderHash.BaseDataID()) headerOffset := sn.idxHeaderHash.OrdinalLookup(blockHeight - sn.idxHeaderHash.BaseDataID())
gg := sn.seg.MakeGetter() gg := sn.seg.MakeGetter()
gg.Reset(headerOffset) gg.Reset(headerOffset)
if !gg.HasNext() {
return nil, nil, nil
}
buf, _ = gg.Next(buf[:0]) buf, _ = gg.Next(buf[:0])
if len(buf) == 0 { if len(buf) == 0 {
return nil, buf, nil return nil, buf, nil
@ -506,6 +510,12 @@ func (back *BlockReaderWithSnapshots) headerFromSnapshot(blockHeight uint64, sn
// but because our indices are based on PerfectHashMap, no way to know is given key exists or not, only way - // but because our indices are based on PerfectHashMap, no way to know is given key exists or not, only way -
// to make sure is to fetch it and compare hash // to make sure is to fetch it and compare hash
func (back *BlockReaderWithSnapshots) headerFromSnapshotByHash(hash common.Hash, sn *HeaderSegment, buf []byte) (*types.Header, error) { func (back *BlockReaderWithSnapshots) headerFromSnapshotByHash(hash common.Hash, sn *HeaderSegment, buf []byte) (*types.Header, error) {
defer func() {
if rec := recover(); rec != nil {
panic(fmt.Errorf("%+v, snapshot: %d-%d, trace: %s", rec, sn.From, sn.To, dbg.Stack()))
}
}() // avoid crash because Erigon's core does many things
if sn.idxHeaderHash == nil { if sn.idxHeaderHash == nil {
return nil, nil return nil, nil
} }
@ -514,6 +524,9 @@ func (back *BlockReaderWithSnapshots) headerFromSnapshotByHash(hash common.Hash,
headerOffset := sn.idxHeaderHash.OrdinalLookup(localID) headerOffset := sn.idxHeaderHash.OrdinalLookup(localID)
gg := sn.seg.MakeGetter() gg := sn.seg.MakeGetter()
gg.Reset(headerOffset) gg.Reset(headerOffset)
if !gg.HasNext() {
return nil, nil
}
buf, _ = gg.Next(buf[:0]) buf, _ = gg.Next(buf[:0])
if len(buf) > 1 && hash[0] != buf[0] { if len(buf) > 1 && hash[0] != buf[0] {
return nil, nil return nil, nil
@ -545,6 +558,12 @@ func (back *BlockReaderWithSnapshots) bodyFromSnapshot(blockHeight uint64, sn *B
} }
func (back *BlockReaderWithSnapshots) bodyForStorageFromSnapshot(blockHeight uint64, sn *BodySegment, buf []byte) (*types.BodyForStorage, []byte, error) { func (back *BlockReaderWithSnapshots) bodyForStorageFromSnapshot(blockHeight uint64, sn *BodySegment, buf []byte) (*types.BodyForStorage, []byte, error) {
defer func() {
if rec := recover(); rec != nil {
panic(fmt.Errorf("%+v, snapshot: %d-%d, trace: %s", rec, sn.From, sn.To, dbg.Stack()))
}
}() // avoid crash because Erigon's core does many things
if sn.idxBodyNumber == nil { if sn.idxBodyNumber == nil {
return nil, buf, nil return nil, buf, nil
} }
@ -552,6 +571,9 @@ func (back *BlockReaderWithSnapshots) bodyForStorageFromSnapshot(blockHeight uin
gg := sn.seg.MakeGetter() gg := sn.seg.MakeGetter()
gg.Reset(bodyOffset) gg.Reset(bodyOffset)
if !gg.HasNext() {
return nil, nil, nil
}
buf, _ = gg.Next(buf[:0]) buf, _ = gg.Next(buf[:0])
if len(buf) == 0 { if len(buf) == 0 {
return nil, nil, nil return nil, nil, nil
@ -569,6 +591,12 @@ func (back *BlockReaderWithSnapshots) bodyForStorageFromSnapshot(blockHeight uin
} }
func (back *BlockReaderWithSnapshots) txsFromSnapshot(baseTxnID uint64, txsAmount uint32, txsSeg *TxnSegment, buf []byte) (txs []types.Transaction, senders []common.Address, err error) { func (back *BlockReaderWithSnapshots) txsFromSnapshot(baseTxnID uint64, txsAmount uint32, txsSeg *TxnSegment, buf []byte) (txs []types.Transaction, senders []common.Address, err error) {
defer func() {
if rec := recover(); rec != nil {
panic(fmt.Errorf("%+v, snapshot: %d-%d, trace: %s", rec, txsSeg.From, txsSeg.To, dbg.Stack()))
}
}() // avoid crash because Erigon's core does many things
if txsSeg.IdxTxnHash == nil { if txsSeg.IdxTxnHash == nil {
return nil, nil, nil return nil, nil, nil
} }
@ -587,6 +615,9 @@ func (back *BlockReaderWithSnapshots) txsFromSnapshot(baseTxnID uint64, txsAmoun
gg.Reset(txnOffset) gg.Reset(txnOffset)
stream := rlp.NewStream(reader, 0) stream := rlp.NewStream(reader, 0)
for i := uint32(0); i < txsAmount; i++ { for i := uint32(0); i < txsAmount; i++ {
if !gg.HasNext() {
return nil, nil, nil
}
buf, _ = gg.Next(buf[:0]) buf, _ = gg.Next(buf[:0])
if len(buf) < 1+20 { if len(buf) < 1+20 {
return nil, nil, fmt.Errorf("segment %s has too short record: len(buf)=%d < 21", txsSeg.Seg.FilePath(), len(buf)) return nil, nil, fmt.Errorf("segment %s has too short record: len(buf)=%d < 21", txsSeg.Seg.FilePath(), len(buf))
@ -609,6 +640,9 @@ func (back *BlockReaderWithSnapshots) txnByID(txnID uint64, sn *TxnSegment, buf
offset := sn.IdxTxnHash.OrdinalLookup(txnID - sn.IdxTxnHash.BaseDataID()) offset := sn.IdxTxnHash.OrdinalLookup(txnID - sn.IdxTxnHash.BaseDataID())
gg := sn.Seg.MakeGetter() gg := sn.Seg.MakeGetter()
gg.Reset(offset) gg.Reset(offset)
if !gg.HasNext() {
return nil, nil
}
buf, _ = gg.Next(buf[:0]) buf, _ = gg.Next(buf[:0])
sender, txnRlp := buf[1:1+20], buf[1+20:] sender, txnRlp := buf[1:1+20], buf[1+20:]