mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-07 23:48:36 +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
|
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 {
|
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
|
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 {
|
if err := op.Append(ChainFreezerReceiptTable, num, receipts); err != nil {
|
||||||
return fmt.Errorf("can't append block %d receipts: %v", num, err)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -791,6 +807,7 @@ func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
|
||||||
DeleteReceipts(db, hash, number)
|
DeleteReceipts(db, hash, number)
|
||||||
DeleteHeader(db, hash, number)
|
DeleteHeader(db, hash, number)
|
||||||
DeleteBody(db, hash, number)
|
DeleteBody(db, hash, number)
|
||||||
|
DeleteAccessList(db, hash, number)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteBlockWithoutNumber removes all block data associated with a hash, except
|
// 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)
|
DeleteReceipts(db, hash, number)
|
||||||
deleteHeaderWithoutNumber(db, hash, number)
|
deleteHeaderWithoutNumber(db, hash, number)
|
||||||
DeleteBody(db, hash, number)
|
DeleteBody(db, hash, number)
|
||||||
|
DeleteAccessList(db, hash, number)
|
||||||
}
|
}
|
||||||
|
|
||||||
const badBlockToKeep = 10
|
const badBlockToKeep = 10
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,10 @@ const (
|
||||||
|
|
||||||
// ChainFreezerReceiptTable indicates the name of the freezer receipts table.
|
// ChainFreezerReceiptTable indicates the name of the freezer receipts table.
|
||||||
ChainFreezerReceiptTable = "receipts"
|
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.
|
// 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
|
// receipt tables. The two tables are pruned together and therefore have
|
||||||
// the same tail position.
|
// the same tail position.
|
||||||
ChainFreezerBlockDataGroup = "blockdata"
|
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.
|
// chainFreezerTableConfigs configures the settings for tables in the chain freezer.
|
||||||
|
|
@ -54,6 +63,7 @@ var chainFreezerTableConfigs = map[string]freezerTableConfig{
|
||||||
ChainFreezerHashTable: {noSnappy: true},
|
ChainFreezerHashTable: {noSnappy: true},
|
||||||
ChainFreezerBodiesTable: {noSnappy: false, tailGroup: ChainFreezerBlockDataGroup},
|
ChainFreezerBodiesTable: {noSnappy: false, tailGroup: ChainFreezerBlockDataGroup},
|
||||||
ChainFreezerReceiptTable: {noSnappy: false, tailGroup: ChainFreezerBlockDataGroup},
|
ChainFreezerReceiptTable: {noSnappy: false, tailGroup: ChainFreezerBlockDataGroup},
|
||||||
|
ChainFreezerBALTable: {noSnappy: false, tailGroup: ChainFreezerBALGroup},
|
||||||
}
|
}
|
||||||
|
|
||||||
// freezerTableConfig contains the settings for a freezer table.
|
// 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.
|
// key-value database to flat files for saving space on live database.
|
||||||
type chainFreezer struct {
|
type chainFreezer struct {
|
||||||
ancients ethdb.AncientStore // Ancient store for storing cold chain segment
|
ancients ethdb.AncientStore // Ancient store for storing cold chain segment
|
||||||
|
eradb *eradb.Store // Optional Era database used as a backup for the pruned chain
|
||||||
// Optional Era database used as a backup for the pruned chain.
|
|
||||||
eradb *eradb.Store
|
|
||||||
|
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
|
|
@ -327,6 +325,16 @@ func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hash
|
||||||
if len(receipts) == 0 {
|
if len(receipts) == 0 {
|
||||||
return fmt.Errorf("block receipts missing, can't freeze block %d", number)
|
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.
|
// Write to the batch.
|
||||||
if err := op.AppendRaw(ChainFreezerHashTable, number, hash[:]); err != nil {
|
if err := op.AppendRaw(ChainFreezerHashTable, number, hash[:]); err != nil {
|
||||||
return fmt.Errorf("can't write hash to Freezer: %v", err)
|
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 {
|
if err := op.AppendRaw(ChainFreezerReceiptTable, number, receipts); err != nil {
|
||||||
return fmt.Errorf("can't write receipts to Freezer: %v", err)
|
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)
|
hashes = append(hashes, hash)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue