eth/filters, accounts/abi/bind/backends: Support websocket subscriptions of dropped and rejected txs

This adds the final piece for being able to get a websocket subscription to the new
dropped and rejected transactions feeds. An update was also needed in the abi/bind
simulated backend for it to comply with the newly specified interfaces.
This commit is contained in:
Austin Roberts 2020-04-08 11:37:48 -05:00
parent 29e619a95b
commit 4eab5b8213
3 changed files with 100 additions and 0 deletions

View file

@ -0,0 +1,16 @@
package backends
import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/event"
)
func (fb *filterBackend) SubscribeDropTxsEvent(ch chan<- core.DropTxsEvent) event.Subscription {
return nullSubscription()
}
func (fb *filterBackend) SubscribeRejectedTxEvent(ch chan<- core.RejectedTxEvent) event.Subscription {
return nullSubscription()
}

View file

@ -0,0 +1,82 @@
package filters
import (
"context"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rpc"
)
type dropNotification struct {
TxHash common.Hash `json:"txhash"`
Reason string `json:"reason"`
}
type rejectNotification struct {
Tx *types.Transaction
Reason string `json:"reason"`
}
// DroppedTransactions send a notification each time a transaction is dropped from the mempool
func (api *PublicFilterAPI) DroppedTransactions(ctx context.Context) (*rpc.Subscription, error) {
notifier, supported := rpc.NotifierFromContext(ctx)
if !supported {
return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported
}
rpcSub := notifier.CreateSubscription()
go func() {
dropped := make(chan core.DropTxsEvent)
droppedSub := api.backend.SubscribeDropTxsEvent(dropped)
for {
select {
case d := <-dropped:
for _, tx := range d.Txs {
notifier.Notify(rpcSub.ID, &dropNotification{TxHash: tx.Hash(), Reason: d.Reason})
}
case <-rpcSub.Err():
droppedSub.Unsubscribe()
return
case <-notifier.Closed():
droppedSub.Unsubscribe()
return
}
}
}()
return rpcSub, nil
}
// RejectedTransactions send a notification each time a transaction is rejected from entering the mempool
func (api *PublicFilterAPI) RejectedTransactions(ctx context.Context) (*rpc.Subscription, error) {
notifier, supported := rpc.NotifierFromContext(ctx)
if !supported {
return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported
}
rpcSub := notifier.CreateSubscription()
go func() {
rejected := make(chan core.RejectedTxEvent)
rejectedSub := api.backend.SubscribeRejectedTxEvent(rejected)
for {
select {
case d := <-rejected:
notifier.Notify(rpcSub.ID, &rejectNotification{Tx: d.Tx, Reason: d.Reason.Error()})
case <-rpcSub.Err():
rejectedSub.Unsubscribe()
return
case <-notifier.Closed():
rejectedSub.Unsubscribe()
return
}
}
}()
return rpcSub, nil
}

View file

@ -38,6 +38,8 @@ type Backend interface {
GetLogs(ctx context.Context, blockHash common.Hash) ([][]*types.Log, error)
SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
SubscribeDropTxsEvent(ch chan<- core.DropTxsEvent) event.Subscription
SubscribeRejectedTxEvent(ch chan<- core.RejectedTxEvent) event.Subscription
SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription
SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription