// Logs creates a subscription that fires for all new log that match the given filter criteria. func (s *PublicFilterAPI) Logs(ctx context.Context, args NewFilterArgs) (rpc.Subscription, error) { notifier, supported := rpc.NotifierFromContext(ctx) if !supported { return nil, rpc.ErrNotificationsUnsupported } var ( externalId string subscription rpc.Subscription err error ) if externalId, err = newFilterId(); err != nil { return nil, err } // uninstall filter when subscription is unsubscribed/cancelled if subscription, err = notifier.NewSubscription(func(string) { s.UninstallFilter(externalId) }); err != nil { return nil, err } notifySubscriber := func(log *vm.Log, removed bool) { rpcLog := toRPCLogs(vm.Logs{log}, removed) if err := subscription.Notify(rpcLog); err != nil { subscription.Cancel() } } // from and to block number are not used since subscriptions don't allow you to travel to "time" var id int if len(args.Addresses) > 0 { id, err = s.newLogFilter(-1, -1, args.Addresses, args.Topics, notifySubscriber) } else { id, err = s.newLogFilter(-1, -1, nil, args.Topics, notifySubscriber) } if err != nil { subscription.Cancel() return nil, err } s.filterMapMu.Lock() s.filterMapping[externalId] = id s.filterMapMu.Unlock() return subscription, err }
// Syncing provides information when this nodes starts synchronising with the Ethereum network and when it's finished. func (api *PublicDownloaderAPI) Syncing(ctx context.Context) (rpc.Subscription, error) { notifier, supported := rpc.NotifierFromContext(ctx) if !supported { return nil, rpc.ErrNotificationsUnsupported } subscription, err := notifier.NewSubscription(func(id string) { api.muSyncSubscriptions.Lock() delete(api.syncSubscriptions, id) api.muSyncSubscriptions.Unlock() }) if err != nil { return nil, err } api.muSyncSubscriptions.Lock() api.syncSubscriptions[subscription.ID()] = subscription api.muSyncSubscriptions.Unlock() return subscription, nil }