Beispiel #1
0
        private async Task DetectChainAsync()
        {
            var commands = new[]
            {
                new DaemonCmd(EC.GetNetVersion),
                new DaemonCmd(EC.ParityChain),
            };

            var results = await daemon.ExecuteBatchAnyAsync(logger, commands);

            if (results.Any(x => x.Error != null))
            {
                if (results[1].Error != null)
                {
                    isParity = false;
                }

                var errors = results.Take(1).Where(x => x.Error != null)
                             .ToArray();

                if (errors.Any())
                {
                    throw new Exception($"Chain detection failed: {string.Join(", ", errors.Select(y => y.Error.Message))}");
                }
            }

            // convert network
            var netVersion  = results[0].Response.ToObject <string>();
            var parityChain = isParity ?
                              results[1].Response.ToObject <string>() :
                              (extraPoolConfig?.ChainTypeOverride ?? "Mainnet");

            EthereumUtils.DetectNetworkAndChain(netVersion, parityChain, out networkType, out chainType);
        }
Beispiel #2
0
        private async Task OnGetWorkAsync(StratumClient client, Timestamped <JsonRpcRequest> tsRequest)
        {
            var request = tsRequest.Value;
            var context = client.ContextAs <EthereumWorkerContext>();

            if (request.Id == null)
            {
                throw new StratumException(StratumError.Other, "missing request id");
            }

            object[] newJobParams = (object[])currentJobParams;
            var      header       = newJobParams[2];
            var      seed         = newJobParams[1];
            var      target       = EthereumUtils.GetTargetHex(new BigInteger(context.Difficulty * EthereumConstants.StratumDiffFactor));

            await client.RespondAsync(new object[] { header, seed, target }, request.Id);

            context.IsInitialWorkSent = true;

            await EnsureInitialWorkSent(client);
        }
Beispiel #3
0
        protected override async Task PostStartInitAsync(CancellationToken ct)
        {
            var commands = new[]
            {
                new DaemonCmd(EC.GetNetVersion),
                new DaemonCmd(EC.GetAccounts),
                new DaemonCmd(EC.GetCoinbase),
                new DaemonCmd(EC.ParityChain),
            };

            var results = await daemon.ExecuteBatchAnyAsync(logger, commands);

            if (results.Any(x => x.Error != null))
            {
                if (results[3].Error != null)
                {
                    isParity = false;
                }

                var errors = results.Take(3).Where(x => x.Error != null)
                             .ToArray();

                if (errors.Any())
                {
                    logger.ThrowLogPoolStartupException($"Init RPC failed: {string.Join(", ", errors.Select(y => y.Error.Message))}");
                }
            }

            // extract results
            var netVersion  = results[0].Response.ToObject <string>();
            var accounts    = results[1].Response.ToObject <string[]>();
            var coinbase    = results[2].Response.ToObject <string>();
            var parityChain = isParity ?
                              results[3].Response.ToObject <string>() :
                              (extraPoolConfig?.ChainTypeOverride ?? "Mainnet");

            // ensure pool owns wallet
            //if (clusterConfig.PaymentProcessing?.Enabled == true && !accounts.Contains(poolConfig.Address) || coinbase != poolConfig.Address)
            //    logger.ThrowLogPoolStartupException($"Daemon does not own pool-address '{poolConfig.Address}'", LogCat);

            EthereumUtils.DetectNetworkAndChain(netVersion, parityChain, out networkType, out chainType);

            if (clusterConfig.PaymentProcessing?.Enabled == true && poolConfig.PaymentProcessing?.Enabled == true)
            {
                ConfigureRewards();
            }

            // update stats
            BlockchainStats.RewardType  = "POW";
            BlockchainStats.NetworkType = $"{chainType}-{networkType}";

            await UpdateNetworkStatsAsync();

            // Periodically update network stats
            Observable.Interval(TimeSpan.FromSeconds(30))
            .Select(via => Observable.FromAsync(async() =>
            {
                try
                {
                    await UpdateNetworkStatsAsync();
                }

                catch (Exception ex)
                {
                    logger.Error(ex);
                }
            }))
            .Concat()
            .Subscribe();

            if (poolConfig.EnableInternalStratum == true)
            {
                // make sure we have a current DAG
                while (true)
                {
                    var blockTemplate = await GetBlockTemplateAsync();

                    if (blockTemplate != null)
                    {
                        logger.Info(() => $"Loading current DAG ...");

                        await ethash.GetDagAsync(blockTemplate.Height, logger, ct);

                        logger.Info(() => $"Loaded current DAG");
                        break;
                    }

                    logger.Info(() => $"Waiting for first valid block template");
                    await Task.Delay(TimeSpan.FromSeconds(5), ct);
                }
            }

            await SetupJobUpdatesAsync();
        }