diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 02399bc801..5a6ab36599 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -563,7 +563,7 @@ type ReceiptWithTx struct { // In addition to returning receipts, it also returns the corresponding transactions. // This is because receipts only contain low-level data, while user-facing data // may require additional information from the Transaction. -func filterReceipts(txHashes []common.Hash, ev core.ChainEvent) []*ReceiptWithTx { +func filterReceipts(txHashMap map[common.Hash]bool, ev core.ChainEvent) []*ReceiptWithTx { var ret []*ReceiptWithTx receipts := ev.Receipts @@ -574,7 +574,7 @@ func filterReceipts(txHashes []common.Hash, ev core.ChainEvent) []*ReceiptWithTx return ret } - if len(txHashes) == 0 { + if len(txHashMap) == 0 { // No filter, send all receipts with their transactions. ret = make([]*ReceiptWithTx, len(receipts)) for i, receipt := range receipts { @@ -583,25 +583,7 @@ func filterReceipts(txHashes []common.Hash, ev core.ChainEvent) []*ReceiptWithTx Transaction: txs[i], } } - } else if len(txHashes) == 1 { - // Filter by single transaction hash. - // This is a common case, so we distinguish it from filtering by multiple tx hashes and made a small optimization. - for i, receipt := range receipts { - if receipt.TxHash == txHashes[0] { - ret = append(ret, &ReceiptWithTx{ - Receipt: receipt, - Transaction: txs[i], - }) - break - } - } } else { - // Filter by multiple transaction hashes. - txHashMap := make(map[common.Hash]bool, len(txHashes)) - for _, hash := range txHashes { - txHashMap[hash] = true - } - for i, receipt := range receipts { if txHashMap[receipt.TxHash] { ret = append(ret, &ReceiptWithTx{ @@ -610,7 +592,7 @@ func filterReceipts(txHashes []common.Hash, ev core.ChainEvent) []*ReceiptWithTx }) // Early exit if all receipts are found - if len(ret) == len(txHashes) { + if len(ret) == len(txHashMap) { break } } diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go index 02783fa5ec..853286d560 100644 --- a/eth/filters/filter_system.go +++ b/eth/filters/filter_system.go @@ -185,9 +185,9 @@ type subscription struct { txs chan []*types.Transaction headers chan *types.Header receipts chan []*ReceiptWithTx - txHashes []common.Hash // contains transaction hashes for transactionReceipts subscription filtering - installed chan struct{} // closed when the filter is installed - err chan error // closed when the filter is uninstalled + hashSet map[common.Hash]bool // contains transaction hashes for transactionReceipts subscription filtering + installed chan struct{} // closed when the filter is installed + err chan error // closed when the filter is uninstalled } // EventSystem creates subscriptions, processes events and broadcasts them to the @@ -403,6 +403,10 @@ func (es *EventSystem) SubscribePendingTxs(txs chan []*types.Transaction) *Subsc // transactions when they are included in blocks. If txHashes is provided, only receipts // for those specific transaction hashes will be delivered. func (es *EventSystem) SubscribeTransactionReceipts(txHashes []common.Hash, receipts chan []*ReceiptWithTx) *Subscription { + hashSet := make(map[common.Hash]bool) + for _, h := range txHashes { + hashSet[h] = true + } sub := &subscription{ id: rpc.NewID(), typ: TransactionReceiptsSubscription, @@ -411,7 +415,7 @@ func (es *EventSystem) SubscribeTransactionReceipts(txHashes []common.Hash, rece txs: make(chan []*types.Transaction), headers: make(chan *types.Header), receipts: receipts, - txHashes: txHashes, + hashSet: hashSet, installed: make(chan struct{}), err: make(chan error), } @@ -445,7 +449,7 @@ func (es *EventSystem) handleChainEvent(filters filterIndex, ev core.ChainEvent) // Handle transaction receipts subscriptions when a new block is added for _, f := range filters[TransactionReceiptsSubscription] { - matchedReceipts := filterReceipts(f.txHashes, ev) + matchedReceipts := filterReceipts(f.hashSet, ev) if len(matchedReceipts) > 0 { f.receipts <- matchedReceipts }