Ejemplo n.º 1
0
        protected virtual void SetupJobUpdates()
        {
            if (poolConfig.ExternalStratum)
            {
                return;
            }

            var enableStreaming = extraPoolConfig?.EnableDaemonWebsocketStreaming == true;

            if (enableStreaming && !poolConfig.Daemons.Any(x =>
                                                           x.Extra.SafeExtensionDataAs <EthereumDaemonEndpointConfigExtra>()?.PortWs.HasValue == true))
            {
                logger.Warn(() => $"[{LogCat}] '{nameof(EthereumPoolConfigExtra.EnableDaemonWebsocketStreaming).ToLowerCamelCase()}' enabled but not a single daemon found with a configured websocket port ('{nameof(EthereumDaemonEndpointConfigExtra.PortWs).ToLowerCamelCase()}'). Falling back to polling.");
                enableStreaming = false;
            }

            if (enableStreaming)
            {
                // collect ports
                var wsDaemons = poolConfig.Daemons
                                .Where(x => x.Extra.SafeExtensionDataAs <EthereumDaemonEndpointConfigExtra>()?.PortWs.HasValue == true)
                                .ToDictionary(x => x, x => x.Extra.SafeExtensionDataAs <EthereumDaemonEndpointConfigExtra>().PortWs.Value);

                logger.Info(() => $"[{LogCat}] Subscribing to WebSocket push-updates from {string.Join(", ", wsDaemons.Keys.Select(x=> x.Host).Distinct())}");

                // stream pending blocks
                var pendingBlockObs = daemon.WebsocketSubscribe(wsDaemons, EC.ParitySubscribe, new[] { (object)EC.GetBlockByNumber, new[] { "pending", (object)true } })
                                      .Select(data =>
                {
                    try
                    {
                        var psp = DeserializeRequest(data).ParamsAs <PubSubParams <Block> >();
                        return(psp?.Result);
                    }

                    catch (Exception ex)
                    {
                        logger.Info(() => $"[{LogCat}] Error deserializing pending block: {ex.Message}");
                    }

                    return(null);
                });

                // stream work updates
                var getWorkObs = daemon.WebsocketSubscribe(wsDaemons, EC.ParitySubscribe, new[] { (object)EC.GetWork })
                                 .Select(data =>
                {
                    try
                    {
                        var psp = DeserializeRequest(data).ParamsAs <PubSubParams <string[]> >();
                        return(psp?.Result);
                    }

                    catch (Exception ex)
                    {
                        logger.Info(() => $"[{LogCat}] Error deserializing pending block: {ex.Message}");
                    }

                    return(null);
                });

                Jobs = Observable.CombineLatest(
                    pendingBlockObs.Where(x => x != null),
                    getWorkObs.Where(x => x != null),
                    AssembleBlockTemplate)
                       .Select(UpdateJob)
                       .Do(isNew =>
                {
                    if (isNew)
                    {
                        logger.Info(() => $"[{LogCat}] New block {currentJob.BlockTemplate.Height} detected");
                    }
                })
                       .Where(isNew => isNew)
                       .Select(_ => GetJobParamsForStratum(true))
                       .Publish()
                       .RefCount();
            }

            else
            {
                Jobs = Observable.Interval(TimeSpan.FromMilliseconds(poolConfig.BlockRefreshInterval))
                       .Select(_ => Observable.FromAsync(UpdateJobAsync))
                       .Concat()
                       .Do(isNew =>
                {
                    if (isNew)
                    {
                        logger.Info(() => $"[{LogCat}] New block {currentJob.BlockTemplate.Height} detected");
                    }
                })
                       .Where(isNew => isNew)
                       .Select(_ => GetJobParamsForStratum(true))
                       .Publish()
                       .RefCount();
            }
        }