Skip to content

Commit a35c6d2

Browse files
authored
feat: transactionReceipts auto-unsubscribe implementation (#3459)
1 parent b135fd9 commit a35c6d2

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

eth/filters/api.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,19 @@ func (api *FilterAPI) TransactionReceipts(ctx context.Context, filter *Transacti
452452
gopool.Submit(func() {
453453
defer receiptsSub.Unsubscribe()
454454

455-
signer := types.LatestSigner(api.sys.backend.ChainConfig())
455+
var (
456+
signer = types.LatestSigner(api.sys.backend.ChainConfig())
457+
pending map[common.Hash]struct{} // Track pending receipts, nil means never auto-unsubscribe
458+
gracePeriod <-chan time.Time
459+
)
460+
461+
// Initialize pending map for specific tx hashes
462+
if len(txHashes) > 0 {
463+
pending = make(map[common.Hash]struct{}, len(txHashes))
464+
for _, hash := range txHashes {
465+
pending[hash] = struct{}{}
466+
}
467+
}
456468

457469
for {
458470
select {
@@ -473,7 +485,21 @@ func (api *FilterAPI) TransactionReceipts(ctx context.Context, filter *Transacti
473485

474486
// Send a batch of tx receipts in one notification
475487
notifier.Notify(rpcSub.ID, marshaledReceipts)
488+
489+
// Auto-unsubscribe when all receipts received (with grace period for reorgs)
490+
if pending != nil {
491+
for _, receiptWithTx := range receiptsWithTxs {
492+
if receiptWithTx.Transaction != nil {
493+
delete(pending, receiptWithTx.Transaction.Hash())
494+
}
495+
}
496+
if len(pending) == 0 && gracePeriod == nil {
497+
gracePeriod = time.After(12 * time.Second) // Grace period for reorg handling
498+
}
499+
}
476500
}
501+
case <-gracePeriod:
502+
return
477503
case <-rpcSub.Err():
478504
return
479505
}

0 commit comments

Comments
 (0)