mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-24 08:49:29 +00:00
core/rawdb: introduce freezer table for BALs
This commit is contained in:
parent
ff9c04e4c8
commit
da877346c6
3 changed files with 44 additions and 5 deletions
|
|
@ -614,9 +614,18 @@ func HasAccessList(db ethdb.Reader, hash common.Hash, number uint64) bool {
|
|||
return has
|
||||
}
|
||||
|
||||
// ReadAccessListRLP retrieves the RLP-encoded block access list for a block from KV.
|
||||
// ReadAccessListRLP retrieves the RLP-encoded block access list for a block.
|
||||
func ReadAccessListRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
|
||||
data, _ := db.Get(accessListKey(number, hash))
|
||||
var data []byte
|
||||
db.ReadAncients(func(reader ethdb.AncientReaderOp) error {
|
||||
data, _ = reader.Ancient(ChainFreezerBALTable, number)
|
||||
if len(data) > 0 {
|
||||
return nil
|
||||
}
|
||||
// Block is not in ancients, read from key-value store by hash and number.
|
||||
data, _ = db.Get(accessListKey(number, hash))
|
||||
return nil
|
||||
})
|
||||
return data
|
||||
}
|
||||
|
||||
|
|
@ -759,6 +768,13 @@ func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *type
|
|||
if err := op.Append(ChainFreezerReceiptTable, num, receipts); err != nil {
|
||||
return fmt.Errorf("can't append block %d receipts: %v", num, err)
|
||||
}
|
||||
// The assumption is held that BAL of ancient block is no longer available
|
||||
// (it may still reachable, but it's not worthwhile to even retrieve it
|
||||
// from the network). A nil entry is stored in the BAL table as the absence
|
||||
// placeholder.
|
||||
if err := op.AppendRaw(ChainFreezerBALTable, num, nil); err != nil {
|
||||
return fmt.Errorf("can't append block %d bals: %v", num, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -791,6 +807,7 @@ func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
|
|||
DeleteReceipts(db, hash, number)
|
||||
DeleteHeader(db, hash, number)
|
||||
DeleteBody(db, hash, number)
|
||||
DeleteAccessList(db, hash, number)
|
||||
}
|
||||
|
||||
// DeleteBlockWithoutNumber removes all block data associated with a hash, except
|
||||
|
|
@ -799,6 +816,7 @@ func DeleteBlockWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number
|
|||
DeleteReceipts(db, hash, number)
|
||||
deleteHeaderWithoutNumber(db, hash, number)
|
||||
DeleteBody(db, hash, number)
|
||||
DeleteAccessList(db, hash, number)
|
||||
}
|
||||
|
||||
const badBlockToKeep = 10
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@ const (
|
|||
|
||||
// ChainFreezerReceiptTable indicates the name of the freezer receipts table.
|
||||
ChainFreezerReceiptTable = "receipts"
|
||||
|
||||
// ChainFreezerBALTable indicates the name of the freezer block access list
|
||||
// table introduced by EIP-7928.
|
||||
ChainFreezerBALTable = "bals"
|
||||
)
|
||||
|
||||
// Identifiers of tail groups used by the chain freezer.
|
||||
|
|
@ -43,6 +47,11 @@ const (
|
|||
// receipt tables. The two tables are pruned together and therefore have
|
||||
// the same tail position.
|
||||
ChainFreezerBlockDataGroup = "blockdata"
|
||||
|
||||
// ChainFreezerBALGroup is the tail group for the block access list table.
|
||||
// BAL is only populated after EIP-7928 activates, so it generally has a
|
||||
// higher tail than the block-data group and is pruned independently.
|
||||
ChainFreezerBALGroup = "bal"
|
||||
)
|
||||
|
||||
// chainFreezerTableConfigs configures the settings for tables in the chain freezer.
|
||||
|
|
@ -54,6 +63,7 @@ var chainFreezerTableConfigs = map[string]freezerTableConfig{
|
|||
ChainFreezerHashTable: {noSnappy: true},
|
||||
ChainFreezerBodiesTable: {noSnappy: false, tailGroup: ChainFreezerBlockDataGroup},
|
||||
ChainFreezerReceiptTable: {noSnappy: false, tailGroup: ChainFreezerBlockDataGroup},
|
||||
ChainFreezerBALTable: {noSnappy: false, tailGroup: ChainFreezerBALGroup},
|
||||
}
|
||||
|
||||
// freezerTableConfig contains the settings for a freezer table.
|
||||
|
|
|
|||
|
|
@ -45,9 +45,7 @@ const (
|
|||
// key-value database to flat files for saving space on live database.
|
||||
type chainFreezer struct {
|
||||
ancients ethdb.AncientStore // Ancient store for storing cold chain segment
|
||||
|
||||
// Optional Era database used as a backup for the pruned chain.
|
||||
eradb *eradb.Store
|
||||
eradb *eradb.Store // Optional Era database used as a backup for the pruned chain
|
||||
|
||||
quit chan struct{}
|
||||
wg sync.WaitGroup
|
||||
|
|
@ -327,6 +325,16 @@ func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hash
|
|||
if len(receipts) == 0 {
|
||||
return fmt.Errorf("block receipts missing, can't freeze block %d", number)
|
||||
}
|
||||
// An empty block access list is allowed and may occur in multiple
|
||||
// scenarios, such as:
|
||||
// - pre-Amsterdam blocks
|
||||
// - post-Amsterdam blocks with the BAL absent (e.g. pruned by network)
|
||||
// - post-Amsterdam blocks with an explicitly empty BAL
|
||||
//
|
||||
// In these cases, a nil entry will be stored in the BAL table as the
|
||||
// absence placeholder.
|
||||
bals := ReadAccessListRLP(nfdb, hash, number)
|
||||
|
||||
// Write to the batch.
|
||||
if err := op.AppendRaw(ChainFreezerHashTable, number, hash[:]); err != nil {
|
||||
return fmt.Errorf("can't write hash to Freezer: %v", err)
|
||||
|
|
@ -340,6 +348,9 @@ func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hash
|
|||
if err := op.AppendRaw(ChainFreezerReceiptTable, number, receipts); err != nil {
|
||||
return fmt.Errorf("can't write receipts to Freezer: %v", err)
|
||||
}
|
||||
if err := op.AppendRaw(ChainFreezerBALTable, number, bals); err != nil {
|
||||
return fmt.Errorf("can't write bals to Freezer: %v", err)
|
||||
}
|
||||
hashes = append(hashes, hash)
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
Loading…
Reference in a new issue