mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-24 08:49:29 +00:00
core/txpool/blobpool: support legacy limbo blobs
This commit is contained in:
parent
8a0223e8da
commit
7162ee2f72
2 changed files with 94 additions and 4 deletions
|
|
@ -1366,6 +1366,54 @@ func TestLegacyTxConversion(t *testing.T) {
|
|||
verifyPoolInternals(t, pool)
|
||||
}
|
||||
|
||||
// TestLegacyLimboBlobConversion verifies that limbo entries stored in the
|
||||
// legacy *types.Transaction RLP format remain available after opening the limbo
|
||||
// with the blobTxForPool storage format.
|
||||
func TestLegacyLimboBlobConversion(t *testing.T) {
|
||||
storage := t.TempDir()
|
||||
limbodir := filepath.Join(storage, limboedTransactionStore)
|
||||
if err := os.MkdirAll(limbodir, 0700); err != nil {
|
||||
t.Fatalf("failed to create limbo dir: %v", err)
|
||||
}
|
||||
store, err := billy.Open(billy.Options{Path: limbodir}, newSlotter(params.BlobTxMaxBlobs), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open limbo store: %v", err)
|
||||
}
|
||||
key, _ := crypto.GenerateKey()
|
||||
tx := makeMultiBlobTx(0, 1, 1000, 100, 2, 0, key, types.BlobSidecarVersion0)
|
||||
|
||||
legacy, err := rlp.EncodeToBytes(&legacyLimboBlob{
|
||||
TxHash: tx.Hash(),
|
||||
Block: 7,
|
||||
Tx: tx,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to encode legacy limbo blob: %v", err)
|
||||
}
|
||||
if _, err := store.Put(legacy); err != nil {
|
||||
t.Fatalf("failed to put legacy limbo blob: %v", err)
|
||||
}
|
||||
store.Close()
|
||||
|
||||
limbo, err := newLimbo(params.TestChainConfig, limbodir)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open limbo: %v", err)
|
||||
}
|
||||
defer limbo.Close()
|
||||
|
||||
ptx, err := limbo.pull(tx.Hash())
|
||||
if err != nil {
|
||||
t.Fatalf("failed to pull legacy limbo blob: %v", err)
|
||||
}
|
||||
got := ptx.ToTx()
|
||||
if got.Hash() != tx.Hash() {
|
||||
t.Fatalf("limbo tx hash mismatch: have %s, want %s", got.Hash(), tx.Hash())
|
||||
}
|
||||
if got.BlobTxSidecar() == nil {
|
||||
t.Fatalf("limbo tx lost sidecar")
|
||||
}
|
||||
}
|
||||
|
||||
// TestBlobCountLimit tests the blobpool enforced limits on the max blob count.
|
||||
func TestBlobCountLimit(t *testing.T) {
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -36,6 +36,12 @@ type limboBlob struct {
|
|||
Ptx *blobTxForPool
|
||||
}
|
||||
|
||||
type legacyLimboBlob struct {
|
||||
TxHash common.Hash // Owner transaction's hash to support resurrecting reorged txs
|
||||
Block uint64 // Block in which the blob transaction was included
|
||||
Tx *types.Transaction
|
||||
}
|
||||
|
||||
// limbo is a light, indexed database to temporarily store recently included
|
||||
// blobs until they are finalized. The purpose is to support small reorgs, which
|
||||
// would require pulling back up old blobs (which aren't part of the chain).
|
||||
|
|
@ -97,8 +103,8 @@ func (l *limbo) Close() error {
|
|||
// parseBlob is a callback method on limbo creation that gets called for each
|
||||
// limboed blob on disk to create the in-memory metadata index.
|
||||
func (l *limbo) parseBlob(id uint64, data []byte) error {
|
||||
item := new(limboBlob)
|
||||
if err := rlp.DecodeBytes(data, item); err != nil {
|
||||
item, err := decodeLimboBlob(data)
|
||||
if err != nil {
|
||||
// This path is impossible unless the disk data representation changes
|
||||
// across restarts. For that ever improbable case, recover gracefully
|
||||
// by ignoring this data entry.
|
||||
|
|
@ -122,6 +128,42 @@ func (l *limbo) parseBlob(id uint64, data []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func decodeLimboBlob(data []byte) (*limboBlob, error) {
|
||||
item := new(limboBlob)
|
||||
err := rlp.DecodeBytes(data, item)
|
||||
if err == nil {
|
||||
return validateLimboBlob(item)
|
||||
}
|
||||
legacy := new(legacyLimboBlob)
|
||||
if legacyErr := rlp.DecodeBytes(data, legacy); legacyErr != nil {
|
||||
return nil, errors.Join(err, legacyErr)
|
||||
}
|
||||
if legacy.Tx == nil {
|
||||
return nil, errors.New("missing limbo transaction")
|
||||
}
|
||||
if legacy.Tx.Hash() != legacy.TxHash {
|
||||
return nil, errors.New("limbo transaction hash mismatch")
|
||||
}
|
||||
if legacy.Tx.BlobTxSidecar() == nil {
|
||||
return nil, errors.New("missing limbo blob sidecar")
|
||||
}
|
||||
return &limboBlob{
|
||||
TxHash: legacy.TxHash,
|
||||
Block: legacy.Block,
|
||||
Ptx: newBlobTxForPool(legacy.Tx),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func validateLimboBlob(item *limboBlob) (*limboBlob, error) {
|
||||
if item.Ptx == nil || item.Ptx.Tx == nil {
|
||||
return nil, errors.New("missing limbo transaction")
|
||||
}
|
||||
if item.Ptx.Tx.Hash() != item.TxHash {
|
||||
return nil, errors.New("limbo transaction hash mismatch")
|
||||
}
|
||||
return item, nil
|
||||
}
|
||||
|
||||
// finalize evicts all blobs belonging to a recently finalized block or older.
|
||||
func (l *limbo) finalize(final *types.Header) {
|
||||
// Just in case there's no final block yet (network not yet merged, weird
|
||||
|
|
@ -222,8 +264,8 @@ func (l *limbo) getAndDrop(id uint64) (*limboBlob, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
item := new(limboBlob)
|
||||
if err = rlp.DecodeBytes(data, item); err != nil {
|
||||
item, err := decodeLimboBlob(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
delete(l.index, item.TxHash)
|
||||
|
|
|
|||
Loading…
Reference in a new issue