core/txpool/local, eth: return no error if transaction fails stateful check

This commit is contained in:
Gary Rong 2025-02-25 20:55:40 +08:00
parent 05647d8126
commit c748bf6201
2 changed files with 24 additions and 12 deletions

View file

@ -74,31 +74,41 @@ func New(journalPath string, journalTime time.Duration, chainConfig *params.Chai
// Track adds a transaction to the tracked set.
// Note: blob-type transactions are ignored.
func (tracker *TxTracker) Track(tx *types.Transaction) {
tracker.TrackAll([]*types.Transaction{tx})
func (tracker *TxTracker) Track(tx *types.Transaction) error {
return tracker.TrackAll([]*types.Transaction{tx})[0]
}
// TrackAll adds a list of transactions to the tracked set.
// Note: blob-type transactions are ignored.
func (tracker *TxTracker) TrackAll(txs []*types.Transaction) {
func (tracker *TxTracker) TrackAll(txs []*types.Transaction) []error {
tracker.mu.Lock()
defer tracker.mu.Unlock()
var errors []error
for _, tx := range txs {
if tx.Type() == types.BlobTxType {
errors = append(errors, nil)
continue
}
// Ignore the transactions which are failed for fundamental
// validation such as invalid parameters.
if tracker.pool.ValidateTxBasics(tx) != nil {
if err := tracker.pool.ValidateTxBasics(tx); err != nil {
log.Debug("Invalid transaction submitted", "hash", tx.Hash(), "err", err)
errors = append(errors, err)
continue
}
// If we're already tracking it, it's a no-op
if _, ok := tracker.all[tx.Hash()]; ok {
errors = append(errors, nil)
continue
}
// Theoretically, checking the error here is unnecessary since sender recovery
// is already part of basic validation. However, retrieving the sender address
// from the transaction cache is effectively a no-op if it was previously verified.
// Therefore, the error is still checked just in case.
addr, err := types.Sender(tracker.signer, tx)
if err != nil { // Ignore this tx
if err != nil {
errors = append(errors, err)
continue
}
tracker.all[tx.Hash()] = tx
@ -112,6 +122,7 @@ func (tracker *TxTracker) TrackAll(txs []*types.Transaction) {
}
}
localGauge.Update(int64(len(tracker.all)))
return errors
}
// recheck checks and returns any transactions that needs to be resubmitted.

View file

@ -273,14 +273,15 @@ func (b *EthAPIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscri
func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
if locals := b.eth.localTxTracker; locals != nil {
locals.Track(signedTx)
if err := locals.Track(signedTx); err != nil {
return err
}
}
// TODO(rjl493456442): If a transaction fails stateful validation (e.g., no
// available slot), an error will be returned to the user. However, locally
// submitted transactions may be resubmitted later via the local tracker, which
// could cause confusion that a previously "rejected" transaction is later
// accepted.
return b.eth.txPool.Add([]*types.Transaction{signedTx}, false)[0]
// No error will be returned to user if the transaction fails stateful
// validation (e.g., no available slot), as the locally submitted transactions
// may be resubmitted later via the local tracker.
b.eth.txPool.Add([]*types.Transaction{signedTx}, false)
return nil
}
func (b *EthAPIBackend) GetPoolTransactions() (types.Transactions, error) {