mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 06:06:44 +00:00
core/txpool/blobpool: also migrate limbo
This commit is contained in:
parent
ace873c1d0
commit
e6ea290f8e
4 changed files with 66 additions and 38 deletions
|
|
@ -398,36 +398,10 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserver txpool.Reser
|
||||||
// Create new slotter for pre-Osaka blob configuration.
|
// Create new slotter for pre-Osaka blob configuration.
|
||||||
slotter := newSlotter(eip4844.LatestMaxBlobsPerBlock(p.chain.Config()))
|
slotter := newSlotter(eip4844.LatestMaxBlobsPerBlock(p.chain.Config()))
|
||||||
|
|
||||||
// Check if we need to migrate our blob db to the new slotter.
|
// See if we need to migrate the limbo after fusaka.
|
||||||
if p.chain.Config().OsakaTime != nil {
|
slotter, err = tryMigrate(p.chain.Config(), slotter, p.config.Datadir)
|
||||||
// Open the store using the version slotter to see if any version has been
|
if err != nil {
|
||||||
// written.
|
return err
|
||||||
var version int
|
|
||||||
index := func(_ uint64, _ uint32, blob []byte) {
|
|
||||||
version = max(version, parseSlotterVersion(blob))
|
|
||||||
}
|
|
||||||
store, err := billy.Open(billy.Options{Path: queuedir}, newVersionSlotter(), index)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
store.Close()
|
|
||||||
|
|
||||||
// If the version found is less than the currently configured store version,
|
|
||||||
// perform a migration then write the updated version of the store.
|
|
||||||
if version < storeVersion {
|
|
||||||
newSlotter := newSlotterEIP7594(eip4844.LatestMaxBlobsPerBlock(p.chain.Config()))
|
|
||||||
if err := billy.Migrate(billy.Options{Path: queuedir, Repair: true}, slotter, newSlotter); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
store, err = billy.Open(billy.Options{Path: queuedir}, newVersionSlotter(), nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
writeSlotterVersion(store, storeVersion)
|
|
||||||
store.Close()
|
|
||||||
}
|
|
||||||
// Set the slotter to the format now that the Osaka is active.
|
|
||||||
slotter = newSlotterEIP7594(eip4844.LatestMaxBlobsPerBlock(p.chain.Config()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Index all transactions on disk and delete anything unprocessable
|
// Index all transactions on disk and delete anything unprocessable
|
||||||
|
|
@ -470,7 +444,7 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserver txpool.Reser
|
||||||
|
|
||||||
// Pool initialized, attach the blob limbo to it to track blobs included
|
// Pool initialized, attach the blob limbo to it to track blobs included
|
||||||
// recently but not yet finalized
|
// recently but not yet finalized
|
||||||
p.limbo, err = newLimbo(limbodir, eip4844.LatestMaxBlobsPerBlock(p.chain.Config()))
|
p.limbo, err = newLimbo(p.chain.Config(), limbodir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.Close()
|
p.Close()
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -1175,8 +1175,9 @@ func TestBillyMigration(t *testing.T) {
|
||||||
storage := t.TempDir()
|
storage := t.TempDir()
|
||||||
|
|
||||||
os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
|
os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
|
||||||
|
os.MkdirAll(filepath.Join(storage, limboedTransactionStore), 0700)
|
||||||
// Create the billy with the old slotter
|
// Create the billy with the old slotter
|
||||||
oldSlotter := newSlotter(6)
|
oldSlotter := newSlotterEIP7594(6)
|
||||||
store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, oldSlotter, nil)
|
store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, oldSlotter, nil)
|
||||||
|
|
||||||
// Create transactions from a few accounts.
|
// Create transactions from a few accounts.
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,10 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/holiman/billy"
|
"github.com/holiman/billy"
|
||||||
)
|
)
|
||||||
|
|
@ -48,11 +50,21 @@ type limbo struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// newLimbo opens and indexes a set of limboed blob transactions.
|
// newLimbo opens and indexes a set of limboed blob transactions.
|
||||||
func newLimbo(datadir string, maxBlobsPerTransaction int) (*limbo, error) {
|
func newLimbo(config *params.ChainConfig, datadir string) (*limbo, error) {
|
||||||
l := &limbo{
|
l := &limbo{
|
||||||
index: make(map[common.Hash]uint64),
|
index: make(map[common.Hash]uint64),
|
||||||
groups: make(map[uint64]map[uint64]common.Hash),
|
groups: make(map[uint64]map[uint64]common.Hash),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create new slotter for pre-Osaka blob configuration.
|
||||||
|
slotter := newSlotter(eip4844.LatestMaxBlobsPerBlock(config))
|
||||||
|
|
||||||
|
// See if we need to migrate the limbo after fusaka.
|
||||||
|
slotter, err := tryMigrate(config, slotter, datadir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// Index all limboed blobs on disk and delete anything unprocessable
|
// Index all limboed blobs on disk and delete anything unprocessable
|
||||||
var fails []uint64
|
var fails []uint64
|
||||||
index := func(id uint64, size uint32, data []byte) {
|
index := func(id uint64, size uint32, data []byte) {
|
||||||
|
|
@ -60,7 +72,7 @@ func newLimbo(datadir string, maxBlobsPerTransaction int) (*limbo, error) {
|
||||||
fails = append(fails, id)
|
fails = append(fails, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
store, err := billy.Open(billy.Options{Path: datadir, Repair: true}, newSlotter(maxBlobsPerTransaction), index)
|
store, err := billy.Open(billy.Options{Path: datadir, Repair: true}, slotter, index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,48 @@
|
||||||
|
|
||||||
package blobpool
|
package blobpool
|
||||||
|
|
||||||
import "github.com/holiman/billy"
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/holiman/billy"
|
||||||
|
)
|
||||||
|
|
||||||
|
// tryMigrate checks if the billy needs to be migrated and migrates if needed.
|
||||||
|
// Returns a slotter that can be used for the database.
|
||||||
|
func tryMigrate(config *params.ChainConfig, slotter billy.SlotSizeFn, datadir string) (billy.SlotSizeFn, error) {
|
||||||
|
// Check if we need to migrate our blob db to the new slotter.
|
||||||
|
if config.OsakaTime != nil {
|
||||||
|
// Open the store using the version slotter to see if any version has been
|
||||||
|
// written.
|
||||||
|
var version int
|
||||||
|
index := func(_ uint64, _ uint32, blob []byte) {
|
||||||
|
version = max(version, parseSlotterVersion(blob))
|
||||||
|
}
|
||||||
|
store, err := billy.Open(billy.Options{Path: datadir}, newVersionSlotter(), index)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
store.Close()
|
||||||
|
|
||||||
|
// If the version found is less than the currently configured store version,
|
||||||
|
// perform a migration then write the updated version of the store.
|
||||||
|
if version < storeVersion {
|
||||||
|
newSlotter := newSlotterEIP7594(eip4844.LatestMaxBlobsPerBlock(config))
|
||||||
|
if err := billy.Migrate(billy.Options{Path: datadir, Repair: true}, slotter, newSlotter); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
store, err = billy.Open(billy.Options{Path: datadir}, newVersionSlotter(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
writeSlotterVersion(store, storeVersion)
|
||||||
|
store.Close()
|
||||||
|
}
|
||||||
|
// Set the slotter to the format now that the Osaka is active.
|
||||||
|
slotter = newSlotterEIP7594(eip4844.LatestMaxBlobsPerBlock(config))
|
||||||
|
}
|
||||||
|
return slotter, nil
|
||||||
|
}
|
||||||
|
|
||||||
// newSlotter creates a helper method for the Billy datastore that returns the
|
// newSlotter creates a helper method for the Billy datastore that returns the
|
||||||
// individual shelf sizes used to store transactions in.
|
// individual shelf sizes used to store transactions in.
|
||||||
|
|
@ -27,7 +68,7 @@ import "github.com/holiman/billy"
|
||||||
// The slotter also creates a shelf for 0-blob transactions. Whilst those are not
|
// The slotter also creates a shelf for 0-blob transactions. Whilst those are not
|
||||||
// allowed in the current protocol, having an empty shelf is not a relevant use
|
// allowed in the current protocol, having an empty shelf is not a relevant use
|
||||||
// of resources, but it makes stress testing with junk transactions simpler.
|
// of resources, but it makes stress testing with junk transactions simpler.
|
||||||
func newSlotter(maxBlobsPerTransaction int) func() (uint32, bool) {
|
func newSlotter(maxBlobsPerTransaction int) billy.SlotSizeFn {
|
||||||
slotsize := uint32(txAvgSize)
|
slotsize := uint32(txAvgSize)
|
||||||
slotsize -= uint32(blobSize) // underflows, it's ok, will overflow back in the first return
|
slotsize -= uint32(blobSize) // underflows, it's ok, will overflow back in the first return
|
||||||
|
|
||||||
|
|
@ -45,7 +86,7 @@ func newSlotter(maxBlobsPerTransaction int) func() (uint32, bool) {
|
||||||
// This slotter adds a dynamic overhead component to the slotter, which also
|
// This slotter adds a dynamic overhead component to the slotter, which also
|
||||||
// captures the notion that blob transactions with more blobs are also more likely to
|
// captures the notion that blob transactions with more blobs are also more likely to
|
||||||
// to have more calldata.
|
// to have more calldata.
|
||||||
func newSlotterEIP7594(maxBlobsPerTransaction int) func() (uint32, bool) {
|
func newSlotterEIP7594(maxBlobsPerTransaction int) billy.SlotSizeFn {
|
||||||
slotsize := uint32(txAvgSize)
|
slotsize := uint32(txAvgSize)
|
||||||
slotsize -= uint32(blobSize) + txBlobOverhead // underflows, it's ok, will overflow back in the first return
|
slotsize -= uint32(blobSize) + txBlobOverhead // underflows, it's ok, will overflow back in the first return
|
||||||
|
|
||||||
|
|
@ -59,7 +100,7 @@ func newSlotterEIP7594(maxBlobsPerTransaction int) func() (uint32, bool) {
|
||||||
|
|
||||||
// newVersionSlotter creates a slotter with a single 8 byte shelf to store
|
// newVersionSlotter creates a slotter with a single 8 byte shelf to store
|
||||||
// version metadata in.
|
// version metadata in.
|
||||||
func newVersionSlotter() func() (uint32, bool) {
|
func newVersionSlotter() billy.SlotSizeFn {
|
||||||
return func() (size uint32, done bool) {
|
return func() (size uint32, done bool) {
|
||||||
return 8, true
|
return 8, true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue