@@ -19,6 +19,7 @@ package blobpool
19
19
20
20
import (
21
21
"container/heap"
22
+ "errors"
22
23
"fmt"
23
24
"math"
24
25
"math/big"
@@ -35,7 +36,6 @@ import (
35
36
"github.com/ethereum/go-ethereum/core/state"
36
37
"github.com/ethereum/go-ethereum/core/txpool"
37
38
"github.com/ethereum/go-ethereum/core/types"
38
- "github.com/ethereum/go-ethereum/crypto/kzg4844"
39
39
"github.com/ethereum/go-ethereum/event"
40
40
"github.com/ethereum/go-ethereum/log"
41
41
"github.com/ethereum/go-ethereum/metrics"
@@ -83,16 +83,6 @@ const (
83
83
limboedTransactionStore = "limbo"
84
84
)
85
85
86
- // blobTx is a wrapper around types.BlobTx which also contains the literal blob
87
- // data along with all the transaction metadata.
88
- type blobTx struct {
89
- Tx * types.Transaction
90
-
91
- Blobs []kzg4844.Blob
92
- Commits []kzg4844.Commitment
93
- Proofs []kzg4844.Proof
94
- }
95
-
96
86
// blobTxMeta is the minimal subset of types.BlobTx necessary to validate and
97
87
// schedule the blob transactions into the following blocks. Only ever add the
98
88
// bare minimum needed fields to keep the size down (and thus number of entries
@@ -455,22 +445,27 @@ func (p *BlobPool) Close() error {
455
445
// parseTransaction is a callback method on pool creation that gets called for
456
446
// each transaction on disk to create the in-memory metadata index.
457
447
func (p * BlobPool ) parseTransaction (id uint64 , size uint32 , blob []byte ) error {
458
- item := new (blobTx )
459
- if err := rlp .DecodeBytes (blob , item ); err != nil {
448
+ tx := new (types. Transaction )
449
+ if err := rlp .DecodeBytes (blob , tx ); err != nil {
460
450
// This path is impossible unless the disk data representation changes
461
451
// across restarts. For that ever unprobable case, recover gracefully
462
452
// by ignoring this data entry.
463
453
log .Error ("Failed to decode blob pool entry" , "id" , id , "err" , err )
464
454
return err
465
455
}
466
- meta := newBlobTxMeta (id , size , item .Tx )
456
+ if tx .BlobTxSidecar () == nil {
457
+ log .Error ("Missing sidecar in blob pool entry" , "id" , id , "hash" , tx .Hash ())
458
+ return errors .New ("missing blob sidecar" )
459
+ }
460
+
461
+ meta := newBlobTxMeta (id , size , tx )
467
462
468
- sender , err := p .signer .Sender (item . Tx )
463
+ sender , err := p .signer .Sender (tx )
469
464
if err != nil {
470
465
// This path is impossible unless the signature validity changes across
471
466
// restarts. For that ever unprobable case, recover gracefully by ignoring
472
467
// this data entry.
473
- log .Error ("Failed to recover blob tx sender" , "id" , id , "hash" , item . Tx .Hash (), "err" , err )
468
+ log .Error ("Failed to recover blob tx sender" , "id" , id , "hash" , tx .Hash (), "err" , err )
474
469
return err
475
470
}
476
471
if _ , ok := p .index [sender ]; ! ok {
@@ -718,17 +713,17 @@ func (p *BlobPool) offload(addr common.Address, nonce uint64, id uint64, inclusi
718
713
log .Error ("Blobs missing for included transaction" , "from" , addr , "nonce" , nonce , "id" , id , "err" , err )
719
714
return
720
715
}
721
- item := new ( blobTx )
722
- if err = rlp .DecodeBytes (data , item ); err != nil {
716
+ var tx types. Transaction
717
+ if err = rlp .DecodeBytes (data , tx ); err != nil {
723
718
log .Error ("Blobs corrupted for included transaction" , "from" , addr , "nonce" , nonce , "id" , id , "err" , err )
724
719
return
725
720
}
726
- block , ok := inclusions [item . Tx .Hash ()]
721
+ block , ok := inclusions [tx .Hash ()]
727
722
if ! ok {
728
723
log .Warn ("Blob transaction swapped out by signer" , "from" , addr , "nonce" , nonce , "id" , id )
729
724
return
730
725
}
731
- if err := p .limbo .push (item . Tx . Hash () , block , item . Blobs , item . Commits , item . Proofs ); err != nil {
726
+ if err := p .limbo .push (& tx , block ); err != nil {
732
727
log .Warn ("Failed to offload blob tx into limbo" , "err" , err )
733
728
return
734
729
}
@@ -760,7 +755,7 @@ func (p *BlobPool) Reset(oldHead, newHead *types.Header) {
760
755
for addr , txs := range reinject {
761
756
// Blindly push all the lost transactions back into the pool
762
757
for _ , tx := range txs {
763
- p .reinject (addr , tx )
758
+ p .reinject (addr , tx . Hash () )
764
759
}
765
760
// Recheck the account's pooled transactions to drop included and
766
761
// invalidated one
@@ -920,16 +915,19 @@ func (p *BlobPool) reorg(oldHead, newHead *types.Header) (map[common.Address][]*
920
915
// Note, the method will not initialize the eviction cache values as those will
921
916
// be done once for all transactions belonging to an account after all individual
922
917
// transactions are injected back into the pool.
923
- func (p * BlobPool ) reinject (addr common.Address , tx * types. Transaction ) {
918
+ func (p * BlobPool ) reinject (addr common.Address , txhash common. Hash ) {
924
919
// Retrieve the associated blob from the limbo. Without the blobs, we cannot
925
920
// add the transaction back into the pool as it is not mineable.
926
- blobs , commits , proofs , err := p .limbo .pull (tx . Hash () )
921
+ tx , err := p .limbo .pull (txhash )
927
922
if err != nil {
928
923
log .Error ("Blobs unavailable, dropping reorged tx" , "err" , err )
929
924
return
930
925
}
931
- // Serialize the transaction back into the primary datastore
932
- blob , err := rlp .EncodeToBytes (& blobTx {Tx : tx , Blobs : blobs , Commits : commits , Proofs : proofs })
926
+ // TODO: seems like an easy optimization here would be getting the serialized tx
927
+ // from limbo instead of re-serializing it here.
928
+
929
+ // Serialize the transaction back into the primary datastore.
930
+ blob , err := rlp .EncodeToBytes (tx )
933
931
if err != nil {
934
932
log .Error ("Failed to encode transaction for storage" , "hash" , tx .Hash (), "err" , err )
935
933
return
@@ -939,9 +937,9 @@ func (p *BlobPool) reinject(addr common.Address, tx *types.Transaction) {
939
937
log .Error ("Failed to write transaction into storage" , "hash" , tx .Hash (), "err" , err )
940
938
return
941
939
}
940
+
942
941
// Update the indixes and metrics
943
942
meta := newBlobTxMeta (id , p .store .Size (id ), tx )
944
-
945
943
if _ , ok := p .index [addr ]; ! ok {
946
944
if err := p .reserve (addr , true ); err != nil {
947
945
log .Warn ("Failed to reserve account for blob pool" , "tx" , tx .Hash (), "from" , addr , "err" , err )
@@ -1023,7 +1021,7 @@ func (p *BlobPool) SetGasTip(tip *big.Int) {
1023
1021
1024
1022
// validateTx checks whether a transaction is valid according to the consensus
1025
1023
// rules and adheres to some heuristic limits of the local node (price and size).
1026
- func (p * BlobPool ) validateTx (tx * types.Transaction , blobs []kzg4844. Blob , commits []kzg4844. Commitment , proofs []kzg4844. Proof ) error {
1024
+ func (p * BlobPool ) validateTx (tx * types.Transaction ) error {
1027
1025
// Ensure the transaction adheres to basic pool filters (type, size, tip) and
1028
1026
// consensus rules
1029
1027
baseOpts := & txpool.ValidationOptions {
@@ -1032,7 +1030,7 @@ func (p *BlobPool) validateTx(tx *types.Transaction, blobs []kzg4844.Blob, commi
1032
1030
MaxSize : txMaxSize ,
1033
1031
MinTip : p .gasTip .ToBig (),
1034
1032
}
1035
- if err := txpool .ValidateTransaction (tx , blobs , commits , proofs , p .head , p .signer , baseOpts ); err != nil {
1033
+ if err := txpool .ValidateTransaction (tx , p .head , p .signer , baseOpts ); err != nil {
1036
1034
return err
1037
1035
}
1038
1036
// Ensure the transaction adheres to the stateful pool filters (nonce, balance)
@@ -1117,7 +1115,7 @@ func (p *BlobPool) Has(hash common.Hash) bool {
1117
1115
}
1118
1116
1119
1117
// Get returns a transaction if it is contained in the pool, or nil otherwise.
1120
- func (p * BlobPool ) Get (hash common.Hash ) * txpool .Transaction {
1118
+ func (p * BlobPool ) Get (hash common.Hash ) * types .Transaction {
1121
1119
// Track the amount of time waiting to retrieve a fully resolved blob tx from
1122
1120
// the pool and the amount of time actually spent on pulling the data from disk.
1123
1121
getStart := time .Now ()
@@ -1139,32 +1137,27 @@ func (p *BlobPool) Get(hash common.Hash) *txpool.Transaction {
1139
1137
log .Error ("Tracked blob transaction missing from store" , "hash" , hash , "id" , id , "err" , err )
1140
1138
return nil
1141
1139
}
1142
- item := new (blobTx )
1140
+ item := new (types. Transaction )
1143
1141
if err = rlp .DecodeBytes (data , item ); err != nil {
1144
1142
log .Error ("Blobs corrupted for traced transaction" , "hash" , hash , "id" , id , "err" , err )
1145
1143
return nil
1146
1144
}
1147
- return & txpool.Transaction {
1148
- Tx : item .Tx ,
1149
- BlobTxBlobs : item .Blobs ,
1150
- BlobTxCommits : item .Commits ,
1151
- BlobTxProofs : item .Proofs ,
1152
- }
1145
+ return item
1153
1146
}
1154
1147
1155
1148
// Add inserts a set of blob transactions into the pool if they pass validation (both
1156
1149
// consensus validity and pool restictions).
1157
- func (p * BlobPool ) Add (txs []* txpool .Transaction , local bool , sync bool ) []error {
1150
+ func (p * BlobPool ) Add (txs []* types .Transaction , local bool , sync bool ) []error {
1158
1151
errs := make ([]error , len (txs ))
1159
1152
for i , tx := range txs {
1160
- errs [i ] = p .add (tx . Tx , tx . BlobTxBlobs , tx . BlobTxCommits , tx . BlobTxProofs )
1153
+ errs [i ] = p .add (tx )
1161
1154
}
1162
1155
return errs
1163
1156
}
1164
1157
1165
1158
// Add inserts a new blob transaction into the pool if it passes validation (both
1166
1159
// consensus validity and pool restictions).
1167
- func (p * BlobPool ) add (tx * types.Transaction , blobs []kzg4844. Blob , commits []kzg4844. Commitment , proofs []kzg4844. Proof ) (err error ) {
1160
+ func (p * BlobPool ) add (tx * types.Transaction ) (err error ) {
1168
1161
// The blob pool blocks on adding a transaction. This is because blob txs are
1169
1162
// only even pulled form the network, so this method will act as the overload
1170
1163
// protection for fetches.
@@ -1178,7 +1171,7 @@ func (p *BlobPool) add(tx *types.Transaction, blobs []kzg4844.Blob, commits []kz
1178
1171
}(time .Now ())
1179
1172
1180
1173
// Ensure the transaction is valid from all perspectives
1181
- if err := p .validateTx (tx , blobs , commits , proofs ); err != nil {
1174
+ if err := p .validateTx (tx ); err != nil {
1182
1175
log .Trace ("Transaction validation failed" , "hash" , tx .Hash (), "err" , err )
1183
1176
return err
1184
1177
}
@@ -1203,7 +1196,7 @@ func (p *BlobPool) add(tx *types.Transaction, blobs []kzg4844.Blob, commits []kz
1203
1196
}
1204
1197
// Transaction permitted into the pool from a nonce and cost perspective,
1205
1198
// insert it into the database and update the indices
1206
- blob , err := rlp .EncodeToBytes (& blobTx { Tx : tx , Blobs : blobs , Commits : commits , Proofs : proofs } )
1199
+ blob , err := rlp .EncodeToBytes (tx )
1207
1200
if err != nil {
1208
1201
log .Error ("Failed to encode transaction for storage" , "hash" , tx .Hash (), "err" , err )
1209
1202
return err
0 commit comments