mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
More careful handle of sequences in stage_headers --reset (#4023)
* save * save * save * save
This commit is contained in:
parent
38e8706c91
commit
77560b6732
@ -17,7 +17,6 @@ import (
|
||||
"github.com/ledgerwatch/erigon-lib/kv"
|
||||
"github.com/ledgerwatch/erigon/cmd/rpcdaemon/interfaces"
|
||||
"github.com/ledgerwatch/erigon/cmd/sentry/sentry"
|
||||
"github.com/ledgerwatch/erigon/common/dbutils"
|
||||
"github.com/ledgerwatch/erigon/consensus"
|
||||
"github.com/ledgerwatch/erigon/consensus/ethash"
|
||||
"github.com/ledgerwatch/erigon/core"
|
||||
@ -483,7 +482,7 @@ func stageHeaders(db kv.RwDB, ctx context.Context) error {
|
||||
return fmt.Errorf("re-read Bodies progress: %w", err)
|
||||
}
|
||||
{ // hard-unwind stage_body also
|
||||
if err := rawdb.DeleteNewBlocks(tx, progress+1); err != nil {
|
||||
if err := rawdb.TruncateBlocks(tx, progress+1); err != nil {
|
||||
return err
|
||||
}
|
||||
progressBodies, err := stages.GetStageProgress(tx, stages.Bodies)
|
||||
@ -497,14 +496,10 @@ func stageHeaders(db kv.RwDB, ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
// remove all canonical markers from this point
|
||||
if err := tx.ForEach(kv.HeaderCanonical, dbutils.EncodeBlockNumber(progress+1), func(k, v []byte) error {
|
||||
return tx.Delete(kv.HeaderCanonical, k, nil)
|
||||
}); err != nil {
|
||||
if err = rawdb.TruncateCanonicalHash(tx, progress+1); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.ForEach(kv.HeaderTD, dbutils.EncodeBlockNumber(progress+1), func(k, v []byte) error {
|
||||
return tx.Delete(kv.HeaderTD, k, nil)
|
||||
}); err != nil {
|
||||
if err = rawdb.TruncateTd(tx, progress+1); err != nil {
|
||||
return err
|
||||
}
|
||||
hash, err := rawdb.ReadCanonicalHash(tx, progress-1)
|
||||
|
@ -1,16 +1,48 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/kv"
|
||||
"github.com/ledgerwatch/erigon-lib/kv/memdb"
|
||||
"github.com/ledgerwatch/erigon/params"
|
||||
"github.com/ledgerwatch/erigon/params/networkname"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDefaultBSCGenesisBlock(t *testing.T) {
|
||||
genesis := DefaultBSCGenesisBlock()
|
||||
db := memdb.New()
|
||||
_, block, err := CommitGenesisBlock(db, genesis)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, block.Hash(), params.BSCGenesisHash)
|
||||
db := memdb.NewTestDB(t)
|
||||
check := func(network string) {
|
||||
genesis := DefaultGenesisBlockByChainName(network)
|
||||
tx, err := db.BeginRw(context.Background())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer tx.Rollback()
|
||||
_, block, err := WriteGenesisBlock(tx, genesis)
|
||||
require.NoError(t, err)
|
||||
expect := params.GenesisHashByChainName(network)
|
||||
require.NotNil(t, expect, network)
|
||||
require.Equal(t, block.Hash().Bytes(), expect.Bytes(), network)
|
||||
}
|
||||
for _, network := range networkname.All {
|
||||
check(network)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitGenesisIdempotency(t *testing.T) {
|
||||
_, tx := memdb.NewTestTx(t)
|
||||
genesis := DefaultGenesisBlockByChainName(networkname.MainnetChainName)
|
||||
_, _, err := WriteGenesisBlock(tx, genesis)
|
||||
require.NoError(t, err)
|
||||
seq, err := tx.ReadSequence(kv.EthTx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(2), seq)
|
||||
|
||||
_, _, err = WriteGenesisBlock(tx, genesis)
|
||||
require.NoError(t, err)
|
||||
seq, err = tx.ReadSequence(kv.EthTx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(2), seq)
|
||||
}
|
||||
|
@ -26,8 +26,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/kv"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
|
||||
"github.com/ledgerwatch/erigon/cmd/rpcdaemon/interfaces"
|
||||
"github.com/ledgerwatch/erigon/common"
|
||||
"github.com/ledgerwatch/erigon/common/dbutils"
|
||||
@ -35,6 +33,7 @@ import (
|
||||
"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
|
||||
"github.com/ledgerwatch/erigon/ethdb/cbor"
|
||||
"github.com/ledgerwatch/erigon/rlp"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
)
|
||||
|
||||
// ReadCanonicalHash retrieves the hash assigned to a canonical block number.
|
||||
@ -57,10 +56,12 @@ func WriteCanonicalHash(db kv.Putter, hash common.Hash, number uint64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteCanonicalHash removes the number to hash canonical mapping.
|
||||
func DeleteCanonicalHash(db kv.Deleter, number uint64) error {
|
||||
if err := db.Delete(kv.HeaderCanonical, dbutils.EncodeBlockNumber(number), nil); err != nil {
|
||||
return fmt.Errorf("failed to delete number to hash mapping: %w", err)
|
||||
// TruncateCanonicalHash removes all the number to hash canonical mapping from block number N
|
||||
func TruncateCanonicalHash(tx kv.RwTx, blockFrom uint64) error {
|
||||
if err := tx.ForEach(kv.HeaderCanonical, dbutils.EncodeBlockNumber(blockFrom), func(k, _ []byte) error {
|
||||
return tx.Delete(kv.HeaderCanonical, k, nil)
|
||||
}); err != nil {
|
||||
return fmt.Errorf("TruncateCanonicalHash: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -254,8 +255,8 @@ func WriteHeader(db kv.Putter, header *types.Header) {
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteHeader removes all block header data associated with a hash.
|
||||
func DeleteHeader(db kv.Deleter, hash common.Hash, number uint64) {
|
||||
// deleteHeader - dangerous, use DeleteAncientBlocks/TruncateBlocks methods
|
||||
func deleteHeader(db kv.Deleter, hash common.Hash, number uint64) {
|
||||
if err := db.Delete(kv.Headers, dbutils.HeaderKey(number, hash), nil); err != nil {
|
||||
log.Crit("Failed to delete header", "err", err)
|
||||
}
|
||||
@ -617,8 +618,8 @@ func WriteSenders(db kv.Putter, hash common.Hash, number uint64, senders []commo
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteBody removes all block body data associated with a hash.
|
||||
func DeleteBody(db kv.Deleter, hash common.Hash, number uint64) {
|
||||
// deleteBody removes all block body data associated with a hash.
|
||||
func deleteBody(db kv.Deleter, hash common.Hash, number uint64) {
|
||||
if err := db.Delete(kv.BlockBody, dbutils.BlockBodyKey(number, hash), nil); err != nil {
|
||||
log.Crit("Failed to delete block body", "err", err)
|
||||
}
|
||||
@ -797,10 +798,12 @@ func WriteTd(db kv.Putter, hash common.Hash, number uint64, td *big.Int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteTd removes all block total difficulty data associated with a hash.
|
||||
func DeleteTd(db kv.Deleter, hash common.Hash, number uint64) error {
|
||||
if err := db.Delete(kv.HeaderTD, dbutils.HeaderKey(number, hash), nil); err != nil {
|
||||
return fmt.Errorf("failed to delete block total difficulty: %w", err)
|
||||
// TruncateTd removes all block total difficulty from block number N
|
||||
func TruncateTd(tx kv.RwTx, blockFrom uint64) error {
|
||||
if err := tx.ForEach(kv.HeaderTD, dbutils.EncodeBlockNumber(blockFrom), func(k, _ []byte) error {
|
||||
return tx.Delete(kv.HeaderTD, k, nil)
|
||||
}); err != nil {
|
||||
return fmt.Errorf("TruncateTd: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -960,25 +963,9 @@ func AppendReceipts(tx kv.StatelessWriteTx, blockNumber uint64, receipts types.R
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteReceipts removes all receipt data associated with a block hash.
|
||||
func DeleteReceipts(db kv.RwTx, number uint64) error {
|
||||
if err := db.Delete(kv.Receipts, dbutils.EncodeBlockNumber(number), nil); err != nil {
|
||||
return fmt.Errorf("receipts delete failed: %d, %w", number, err)
|
||||
}
|
||||
|
||||
prefix := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(prefix, number)
|
||||
if err := db.ForPrefix(kv.Log, prefix, func(k, v []byte) error {
|
||||
return db.Delete(kv.Log, k, nil)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteNewerReceipts removes all receipt for given block number or newer
|
||||
func DeleteNewerReceipts(db kv.RwTx, number uint64) error {
|
||||
if err := db.ForEach(kv.Receipts, dbutils.EncodeBlockNumber(number), func(k, v []byte) error {
|
||||
// TruncateReceipts removes all receipt for given block number or newer
|
||||
func TruncateReceipts(db kv.RwTx, number uint64) error {
|
||||
if err := db.ForEach(kv.Receipts, dbutils.EncodeBlockNumber(number), func(k, _ []byte) error {
|
||||
return db.Delete(kv.Receipts, k, nil)
|
||||
}); err != nil {
|
||||
return err
|
||||
@ -986,7 +973,7 @@ func DeleteNewerReceipts(db kv.RwTx, number uint64) error {
|
||||
|
||||
from := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(from, number)
|
||||
if err := db.ForEach(kv.Log, from, func(k, v []byte) error {
|
||||
if err := db.ForEach(kv.Log, from, func(k, _ []byte) error {
|
||||
return db.Delete(kv.Log, k, nil)
|
||||
}); err != nil {
|
||||
return err
|
||||
@ -1099,22 +1086,17 @@ func DeleteAncientBlocks(db kv.RwTx, blockTo uint64, blocksDeleteLimit int) erro
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
var stopAtBlock, firstNonGenesisInDB uint64
|
||||
{
|
||||
k, _, err := c.First()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
firstNonGenesisInDB = binary.BigEndian.Uint64(k)
|
||||
if firstNonGenesisInDB == 0 { // keep genesis in DB
|
||||
k, _, err := c.Next()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
firstNonGenesisInDB = binary.BigEndian.Uint64(k)
|
||||
}
|
||||
stopAtBlock = min(blockTo, firstNonGenesisInDB+uint64(blocksDeleteLimit))
|
||||
// find first non-genesis block
|
||||
k, _, err := c.Seek(dbutils.EncodeBlockNumber(1))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if k == nil { //nothing to delete
|
||||
return nil
|
||||
}
|
||||
blockFrom := binary.BigEndian.Uint64(k)
|
||||
stopAtBlock := min(blockTo, blockFrom+uint64(blocksDeleteLimit))
|
||||
|
||||
for k, _, err := c.Current(); k != nil; k, _, err = c.Next() {
|
||||
if err != nil {
|
||||
return err
|
||||
@ -1124,38 +1106,7 @@ func DeleteAncientBlocks(db kv.RwTx, blockTo uint64, blocksDeleteLimit int) erro
|
||||
if n >= stopAtBlock { // [from, to)
|
||||
break
|
||||
}
|
||||
|
||||
canonicalHash, err := ReadCanonicalHash(db, n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
isCanonical := bytes.Equal(k[8:], canonicalHash[:])
|
||||
|
||||
b, err := ReadBodyForStorageByKey(db, k)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b == nil {
|
||||
return fmt.Errorf("DeleteAncientBlocks: block body not found for block %d", n)
|
||||
}
|
||||
txIDBytes := make([]byte, 8)
|
||||
for txID := b.BaseTxId; txID < b.BaseTxId+uint64(b.TxAmount); txID++ {
|
||||
binary.BigEndian.PutUint64(txIDBytes, txID)
|
||||
bucket := kv.EthTx
|
||||
if !isCanonical {
|
||||
bucket = kv.NonCanonicalTxs
|
||||
}
|
||||
if err := db.Delete(bucket, txIDBytes, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := db.Delete(kv.Headers, k, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.Delete(kv.BlockBody, k, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.Delete(kv.Senders, k, nil); err != nil {
|
||||
if err := delBlock(db, k, true); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -1163,65 +1114,125 @@ func DeleteAncientBlocks(db kv.RwTx, blockTo uint64, blocksDeleteLimit int) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
func DeleteNewBlocks(db kv.RwTx, blockFrom uint64) error {
|
||||
c, err := db.Cursor(kv.Headers)
|
||||
func lastKey(tx kv.Tx, table string) ([]byte, error) {
|
||||
c, err := tx.Cursor(table)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer c.Close()
|
||||
k, _, err := c.Last()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return k, nil
|
||||
}
|
||||
|
||||
// delBlock - low-level method to delete 1 block by key
|
||||
// keeps genesis in db: [1, to)
|
||||
// doesn't delete Reciepts
|
||||
// doesn't delete Canonical markers
|
||||
// doesn't delete TotalDifficulty
|
||||
// keepSequence - can track decrement sequnces of Canonical and Non-Canonical txs
|
||||
func delBlock(tx kv.RwTx, k []byte, keepSequence bool) error {
|
||||
n := binary.BigEndian.Uint64(k)
|
||||
canonicalHash, err := ReadCanonicalHash(tx, n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
isCanonical := bytes.Equal(k[8:], canonicalHash[:])
|
||||
b, err := ReadBodyForStorageByKey(tx, k)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b == nil {
|
||||
return fmt.Errorf("DeleteAncientBlocks: block body not found for block %d", n)
|
||||
}
|
||||
txIDBytes := make([]byte, 8)
|
||||
for txID := b.BaseTxId; txID < b.BaseTxId+uint64(b.TxAmount); txID++ {
|
||||
binary.BigEndian.PutUint64(txIDBytes, txID)
|
||||
bucket := kv.EthTx
|
||||
if !isCanonical {
|
||||
bucket = kv.NonCanonicalTxs
|
||||
}
|
||||
|
||||
if !keepSequence {
|
||||
lastK, err := lastKey(tx, bucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
seq, err := tx.ReadSequence(bucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if lastK != nil && binary.BigEndian.Uint64(lastK) > seq {
|
||||
return fmt.Errorf("please delete blocks from newest to older. txnId: %d > %d", binary.BigEndian.Uint64(lastK), seq)
|
||||
}
|
||||
if seq > b.BaseTxId+uint64(b.TxAmount) {
|
||||
return fmt.Errorf("please delete blocks from newest to older. seq: %d > %d+%d", seq, b.BaseTxId, uint64(b.TxAmount))
|
||||
}
|
||||
if err := ResetSequence(tx, bucket, b.BaseTxId); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Delete(bucket, txIDBytes, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tx.Delete(kv.Headers, k, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Delete(kv.BlockBody, k, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Delete(kv.Senders, k, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !keepSequence {
|
||||
bucket := kv.EthTx
|
||||
if !isCanonical {
|
||||
bucket = kv.NonCanonicalTxs
|
||||
}
|
||||
lastK, err := lastKey(tx, bucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
seq, err := tx.ReadSequence(bucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if lastK != nil && binary.BigEndian.Uint64(lastK) > seq {
|
||||
return fmt.Errorf("end: please delete blocks from newest to older. txnId: %d > %d", binary.BigEndian.Uint64(lastK), seq)
|
||||
}
|
||||
if seq > b.BaseTxId+uint64(b.TxAmount) {
|
||||
return fmt.Errorf("end: please delete blocks from newest to older. seq: %d > %d+%d", seq, b.BaseTxId, uint64(b.TxAmount))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TruncateBlocks - delete block >= blockFrom
|
||||
func TruncateBlocks(tx kv.RwTx, blockFrom uint64) error {
|
||||
c, err := tx.Cursor(kv.Headers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
for k, _, err := c.Seek(dbutils.EncodeBlockNumber(blockFrom)); k != nil; k, _, err = c.Next() {
|
||||
if blockFrom < 1 { //protect genesis
|
||||
blockFrom = 1
|
||||
}
|
||||
for k, _, err := c.Last(); k != nil; k, _, err = c.Prev() {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n := binary.BigEndian.Uint64(k)
|
||||
|
||||
canonicalHash, err := ReadCanonicalHash(db, n)
|
||||
if err != nil {
|
||||
if n < blockFrom { // [from, to)
|
||||
break
|
||||
}
|
||||
if err := delBlock(tx, k, false); err != nil {
|
||||
return err
|
||||
}
|
||||
isCanonical := bytes.Equal(k[8:], canonicalHash[:])
|
||||
|
||||
b, err := ReadBodyForStorageByKey(db, k)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b != nil { // b == nil means body were marked as non-canonical already
|
||||
txIDBytes := make([]byte, 8)
|
||||
for txID := b.BaseTxId; txID < b.BaseTxId+uint64(b.TxAmount); txID++ {
|
||||
binary.BigEndian.PutUint64(txIDBytes, txID)
|
||||
bucket := kv.EthTx
|
||||
if !isCanonical {
|
||||
bucket = kv.NonCanonicalTxs
|
||||
}
|
||||
if err := db.Delete(bucket, txIDBytes, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := db.Delete(kv.Headers, k, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.Delete(kv.BlockBody, k, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.Delete(kv.Senders, k, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteBlock removes all block data associated with a hash.
|
||||
func DeleteBlock(db kv.RwTx, hash common.Hash, number uint64) error {
|
||||
if err := DeleteReceipts(db, number); err != nil {
|
||||
return err
|
||||
}
|
||||
DeleteHeader(db, hash, number)
|
||||
DeleteBody(db, hash, number)
|
||||
if err := DeleteTd(db, hash, number); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ func TestHeaderStorage(t *testing.T) {
|
||||
}
|
||||
}
|
||||
// Delete the header and verify the execution
|
||||
DeleteHeader(tx, header.Hash(), header.Number.Uint64())
|
||||
deleteHeader(tx, header.Hash(), header.Number.Uint64())
|
||||
if entry := ReadHeader(tx, header.Hash(), header.Number.Uint64()); entry != nil {
|
||||
t.Fatalf("Deleted header returned: %v", entry)
|
||||
}
|
||||
@ -116,7 +116,7 @@ func TestBodyStorage(t *testing.T) {
|
||||
}
|
||||
}
|
||||
// Delete the body and verify the execution
|
||||
DeleteBody(tx, hash, 0)
|
||||
deleteBody(tx, hash, 0)
|
||||
if entry := ReadCanonicalBodyWithTransactions(tx, hash, 0); entry != nil {
|
||||
t.Fatalf("Deleted body returned: %v", entry)
|
||||
}
|
||||
@ -128,6 +128,7 @@ func TestBlockStorage(t *testing.T) {
|
||||
|
||||
// Create a test block to move around the database and make sure it's really new
|
||||
block := types.NewBlockWithHeader(&types.Header{
|
||||
Number: big.NewInt(1),
|
||||
Extra: []byte("test block"),
|
||||
UncleHash: types.EmptyUncleHash,
|
||||
TxHash: types.EmptyRootHash,
|
||||
@ -157,15 +158,21 @@ func TestBlockStorage(t *testing.T) {
|
||||
} else if entry.Hash() != block.Hash() {
|
||||
t.Fatalf("Retrieved header mismatch: have %v, want %v", entry, block.Header())
|
||||
}
|
||||
if err := TruncateBlocks(tx, 2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if entry := ReadCanonicalBodyWithTransactions(tx, block.Hash(), block.NumberU64()); entry == nil {
|
||||
t.Fatalf("Stored body not found")
|
||||
} else if types.DeriveSha(types.Transactions(entry.Transactions)) != types.DeriveSha(block.Transactions()) || types.CalcUncleHash(entry.Uncles) != types.CalcUncleHash(block.Uncles()) {
|
||||
t.Fatalf("Retrieved body mismatch: have %v, want %v", entry, block.Body())
|
||||
}
|
||||
// Delete the block and verify the execution
|
||||
if err := DeleteBlock(tx, block.Hash(), block.NumberU64()); err != nil {
|
||||
t.Fatalf("Could not delete block: %v", err)
|
||||
if err := TruncateBlocks(tx, block.NumberU64()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
//if err := DeleteBlock(tx, block.Hash(), block.NumberU64()); err != nil {
|
||||
// t.Fatalf("Could not delete block: %v", err)
|
||||
//}
|
||||
if entry := ReadBlock(tx, block.Hash(), block.NumberU64()); entry != nil {
|
||||
t.Fatalf("Deleted block returned: %v", entry)
|
||||
}
|
||||
@ -175,6 +182,14 @@ func TestBlockStorage(t *testing.T) {
|
||||
if entry := ReadCanonicalBodyWithTransactions(tx, block.Hash(), block.NumberU64()); entry != nil {
|
||||
t.Fatalf("Deleted body returned: %v", entry)
|
||||
}
|
||||
|
||||
// write again and delete it as old one
|
||||
if err := WriteBlock(tx, block); err != nil {
|
||||
t.Fatalf("Could not write block: %v", err)
|
||||
}
|
||||
if err := DeleteAncientBlocks(tx, 0, 1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that partial block contents don't get reassembled into full blocks.
|
||||
@ -193,7 +208,7 @@ func TestPartialBlockStorage(t *testing.T) {
|
||||
if entry := ReadBlock(tx, block.Hash(), block.NumberU64()); entry != nil {
|
||||
t.Fatalf("Non existent block returned: %v", entry)
|
||||
}
|
||||
DeleteHeader(tx, block.Hash(), block.NumberU64())
|
||||
deleteHeader(tx, block.Hash(), block.NumberU64())
|
||||
|
||||
// Store a body and check that it's not recognized as a block
|
||||
if err := WriteBody(tx, block.Hash(), block.NumberU64(), block.Body()); err != nil {
|
||||
@ -202,7 +217,7 @@ func TestPartialBlockStorage(t *testing.T) {
|
||||
if entry := ReadBlock(tx, block.Hash(), block.NumberU64()); entry != nil {
|
||||
t.Fatalf("Non existent block returned: %v", entry)
|
||||
}
|
||||
DeleteBody(tx, block.Hash(), block.NumberU64())
|
||||
deleteBody(tx, block.Hash(), block.NumberU64())
|
||||
|
||||
// Store a header and a body separately and check reassembly
|
||||
WriteHeader(tx, header)
|
||||
@ -245,7 +260,7 @@ func TestTdStorage(t *testing.T) {
|
||||
t.Fatalf("Retrieved TD mismatch: have %v, want %v", entry, td)
|
||||
}
|
||||
// Delete the TD and verify the execution
|
||||
err = DeleteTd(tx, hash, 0)
|
||||
err = TruncateTd(tx, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("DeleteTd failed: %v", err)
|
||||
}
|
||||
@ -286,7 +301,7 @@ func TestCanonicalMappingStorage(t *testing.T) {
|
||||
t.Fatalf("Retrieved canonical mapping mismatch: have %v, want %v", entry, hash)
|
||||
}
|
||||
// Delete the TD and verify the execution
|
||||
err = DeleteCanonicalHash(tx, number)
|
||||
err = TruncateCanonicalHash(tx, number)
|
||||
if err != nil {
|
||||
t.Fatalf("DeleteCanonicalHash failed: %v", err)
|
||||
}
|
||||
@ -394,8 +409,8 @@ func TestBlockReceiptStorage(t *testing.T) {
|
||||
}
|
||||
}
|
||||
// Delete the body and ensure that the receipts are no longer returned (metadata can't be recomputed)
|
||||
DeleteHeader(tx, hash, 0)
|
||||
DeleteBody(tx, hash, 0)
|
||||
deleteHeader(tx, hash, 0)
|
||||
deleteBody(tx, hash, 0)
|
||||
b, senders, err = ReadBlockWithSenders(tx, hash, 0)
|
||||
require.NoError(err)
|
||||
require.Nil(b)
|
||||
@ -409,7 +424,7 @@ func TestBlockReceiptStorage(t *testing.T) {
|
||||
WriteHeader(tx, header)
|
||||
// Sanity check that body alone without the receipt is a full purge
|
||||
require.NoError(WriteBody(tx, hash, 0, body))
|
||||
require.NoError(DeleteReceipts(tx, 0))
|
||||
require.NoError(TruncateReceipts(tx, 0))
|
||||
b, senders, err = ReadBlockWithSenders(tx, hash, 0)
|
||||
require.NoError(err)
|
||||
require.NotNil(b)
|
||||
|
@ -519,7 +519,7 @@ func unwindExecutionStage(u *UnwindState, s *StageState, tx kv.RwTx, quit <-chan
|
||||
return err
|
||||
}
|
||||
|
||||
if err := rawdb.DeleteNewerReceipts(tx, u.UnwindPoint+1); err != nil {
|
||||
if err := rawdb.TruncateReceipts(tx, u.UnwindPoint+1); err != nil {
|
||||
return fmt.Errorf("walking receipts: %w", err)
|
||||
}
|
||||
if err := rawdb.DeleteNewerEpochs(tx, u.UnwindPoint+1); err != nil {
|
||||
|
@ -23,7 +23,6 @@ import (
|
||||
"github.com/ledgerwatch/erigon/common/dbutils"
|
||||
"github.com/ledgerwatch/erigon/core/rawdb"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
|
||||
"github.com/ledgerwatch/erigon/ethdb/privateapi"
|
||||
"github.com/ledgerwatch/erigon/params"
|
||||
"github.com/ledgerwatch/erigon/rlp"
|
||||
@ -871,11 +870,6 @@ func HeadersUnwind(u *UnwindState, s *StageState, tx kv.RwTx, cfg HeadersCfg, te
|
||||
defer tx.Rollback()
|
||||
}
|
||||
// Delete canonical hashes that are being unwound
|
||||
var headerProgress uint64
|
||||
headerProgress, err = stages.GetStageProgress(tx, stages.Headers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
badBlock := u.BadBlock != (common.Hash{})
|
||||
if badBlock {
|
||||
cfg.hd.ReportBadHeader(u.BadBlock)
|
||||
@ -899,10 +893,8 @@ func HeadersUnwind(u *UnwindState, s *StageState, tx kv.RwTx, cfg HeadersCfg, te
|
||||
return fmt.Errorf("iterate over headers to mark bad headers: %w", err)
|
||||
}
|
||||
}
|
||||
for blockHeight := headerProgress; blockHeight > u.UnwindPoint; blockHeight-- {
|
||||
if err = rawdb.DeleteCanonicalHash(tx, blockHeight); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := rawdb.TruncateCanonicalHash(tx, u.UnwindPoint+1); err != nil {
|
||||
return err
|
||||
}
|
||||
if badBlock {
|
||||
var maxTd big.Int
|
||||
|
@ -41,8 +41,8 @@ func TestTxsBeginEnd(t *testing.T) {
|
||||
return err
|
||||
}
|
||||
|
||||
err = rawdb.TruncateCanonicalHash(tx, 7)
|
||||
for i := uint64(7); i < 10; i++ {
|
||||
err = rawdb.DeleteCanonicalHash(tx, i)
|
||||
require.NoError(err)
|
||||
hash := common.Hash{0xa, byte(i)}
|
||||
err = writeRawBodyDeprecated(tx, hash, i, b)
|
||||
|
@ -17,3 +17,21 @@ const (
|
||||
MumbaiChainName = "mumbai"
|
||||
BorMainnetChainName = "bor-mainnet"
|
||||
)
|
||||
|
||||
var All = []string{
|
||||
MainnetChainName,
|
||||
SepoliaChainName,
|
||||
RopstenChainName,
|
||||
RinkebyChainName,
|
||||
GoerliChainName,
|
||||
KilnDevnetChainName,
|
||||
//DevChainName,
|
||||
ErigonMineName,
|
||||
SokolChainName,
|
||||
FermionChainName,
|
||||
BSCChainName,
|
||||
ChapelChainName,
|
||||
//RialtoChainName,
|
||||
MumbaiChainName,
|
||||
BorMainnetChainName,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user