Пример #1
0
        public CryptonoteJob(GetBlockTemplateResponse blockTemplate, byte[] instanceId, string jobId,
                             PoolConfig poolConfig, ClusterConfig clusterConfig, string prevHash)
        {
            Contract.RequiresNonNull(blockTemplate, nameof(blockTemplate));
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));
            Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));
            Contract.RequiresNonNull(instanceId, nameof(instanceId));
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty");

            coin          = poolConfig.Template.As <CryptonoteCoinTemplate>();
            BlockTemplate = blockTemplate;
            PrepareBlobTemplate(instanceId);
            PrevHash = prevHash;

            switch (coin.Hash)
            {
            case CryptonightHashType.Normal:
                hashFunc = LibCryptonight.Cryptonight;
                break;

            case CryptonightHashType.Lite:
                hashFunc = LibCryptonight.CryptonightLight;
                break;

            case CryptonightHashType.Heavy:
                hashFunc = LibCryptonight.CryptonightHeavy;
                break;
            }
        }
Пример #2
0
        public ShareRecorder(IConnectionFactory cf, IMapper mapper,
                             JsonSerializerSettings jsonSerializerSettings,
                             IShareRepository shareRepo, IBlockRepository blockRepo,
                             IMasterClock clock,
                             IMessageBus messageBus)
        {
            Contract.RequiresNonNull(cf, nameof(cf));
            Contract.RequiresNonNull(mapper, nameof(mapper));
            Contract.RequiresNonNull(shareRepo, nameof(shareRepo));
            Contract.RequiresNonNull(blockRepo, nameof(blockRepo));
            Contract.RequiresNonNull(jsonSerializerSettings, nameof(jsonSerializerSettings));
            Contract.RequiresNonNull(clock, nameof(clock));
            Contract.RequiresNonNull(messageBus, nameof(messageBus));

            this.cf     = cf;
            this.mapper = mapper;
            this.jsonSerializerSettings = jsonSerializerSettings;
            this.clock      = clock;
            this.messageBus = messageBus;

            this.shareRepo = shareRepo;
            this.blockRepo = blockRepo;

            BuildFaultHandlingPolicy();
        }
Пример #3
0
        /// <summary>
        /// </summary>
        /// <example>
        /// python: http://runnable.com/U3jqtyYUmAUxtsSS/bitcoin-block-merkle-root-python
        /// nodejs: https://github.com/zone117x/node-stratum-pool/blob/master/lib/merkleTree.js#L9
        /// </example>
        /// <param name="hashList"></param>
        /// <returns></returns>
        private IList <byte[]> CalculateSteps(IEnumerable <byte[]> hashList)
        {
            Contract.RequiresNonNull(hashList, nameof(hashList));

            var steps = new List <byte[]>();

            var L = new List <byte[]> {
                null
            };

            L.AddRange(hashList);

            var startL = 2;
            var Ll     = L.Count;

            if (Ll > 1)
            {
                while (true)
                {
                    if (Ll == 1)
                    {
                        break;
                    }

                    steps.Add(L[1]);

                    if (Ll % 2 == 1)
                    {
                        L.Add(L[^ 1]);
Пример #4
0
        protected PoolBase(IComponentContext ctx,
                           JsonSerializerSettings serializerSettings,
                           IConnectionFactory cf,
                           IStatsRepository statsRepo,
                           IMapper mapper,
                           IMasterClock clock,
                           IMessageBus messageBus,
                           NicehashService nicehashService) : base(ctx, clock)
        {
            Contract.RequiresNonNull(ctx, nameof(ctx));
            Contract.RequiresNonNull(serializerSettings, nameof(serializerSettings));
            Contract.RequiresNonNull(cf, nameof(cf));
            Contract.RequiresNonNull(statsRepo, nameof(statsRepo));
            Contract.RequiresNonNull(mapper, nameof(mapper));
            Contract.RequiresNonNull(clock, nameof(clock));
            Contract.RequiresNonNull(messageBus, nameof(messageBus));
            Contract.RequiresNonNull(nicehashService, nameof(nicehashService));

            this.serializerSettings = serializerSettings;
            this.cf              = cf;
            this.statsRepo       = statsRepo;
            this.mapper          = mapper;
            this.messageBus      = messageBus;
            this.nicehashService = nicehashService;
        }
Пример #5
0
        public bool ValidateAddress(string address)
        {
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(address), $"{nameof(address)} must not be empty");

            var addressPrefix           = LibCryptonote.DecodeAddress(address);
            var addressIntegratedPrefix = LibCryptonote.DecodeIntegratedAddress(address);
            var coin = poolConfig.Template.As <CryptonoteCoinTemplate>();

            switch (networkType)
            {
            case CryptonoteNetworkType.Main:
                if (addressPrefix != coin.AddressPrefix &&
                    addressIntegratedPrefix != coin.AddressPrefixIntegrated)
                {
                    return(false);
                }
                break;

            case CryptonoteNetworkType.Test:
                if (addressPrefix != coin.AddressPrefixTestnet &&
                    addressIntegratedPrefix != coin.AddressPrefixIntegratedTestnet)
                {
                    return(false);
                }
                break;
            }

            return(true);
        }
Пример #6
0
        public PayoutManager(IComponentContext ctx,
                             IConnectionFactory cf,
                             IBlockRepository blockRepo,
                             IShareRepository shareRepo,
                             IBalanceRepository balanceRepo,
                             ClusterConfig clusterConfig,
                             IMessageBus messageBus)
        {
            Contract.RequiresNonNull(ctx, nameof(ctx));
            Contract.RequiresNonNull(cf, nameof(cf));
            Contract.RequiresNonNull(blockRepo, nameof(blockRepo));
            Contract.RequiresNonNull(shareRepo, nameof(shareRepo));
            Contract.RequiresNonNull(balanceRepo, nameof(balanceRepo));
            Contract.RequiresNonNull(messageBus, nameof(messageBus));

            this.ctx           = ctx;
            this.cf            = cf;
            this.blockRepo     = blockRepo;
            this.shareRepo     = shareRepo;
            this.balanceRepo   = balanceRepo;
            this.messageBus    = messageBus;
            this.clusterConfig = clusterConfig;

            interval = TimeSpan.FromSeconds(clusterConfig.PaymentProcessing.Interval > 0 ?
                                            clusterConfig.PaymentProcessing.Interval : 600);
        }
Пример #7
0
        public void Configure(DaemonEndpointConfig[] endPoints, string digestAuthRealm = null)
        {
            Contract.RequiresNonNull(endPoints, nameof(endPoints));
            Contract.Requires <ArgumentException>(endPoints.Length > 0, $"{nameof(endPoints)} must not be empty");

            this.endPoints = endPoints;

            // create one HttpClient instance per endpoint that carries the associated credentials
            httpClients = endPoints.ToDictionary(endpoint => endpoint, endpoint =>
            {
                if (string.IsNullOrEmpty(endpoint.User) || !endpoint.DigestAuth)
                {
                    return(defaultHttpClient);
                }

                return(new HttpClient(new SocketsHttpHandler
                {
                    AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip,

                    Credentials = new NetworkCredential(endpoint.User, endpoint.Password),
                    PreAuthenticate = true,

                    SslOptions = new SslClientAuthenticationOptions
                    {
                        RemoteCertificateValidationCallback = ((sender, certificate, chain, errors) => true),
                    }
                }));
            });
        }
Пример #8
0
        /// <summary>
        /// Executes the request against all configured demons and returns their responses as an array
        /// </summary>
        /// <typeparam name="TResponse"></typeparam>
        /// <param name="method"></param>
        /// <param name="payload"></param>
        /// <returns></returns>
        public async Task <DaemonResponse <TResponse>[]> ExecuteCmdAllAsync <TResponse>(ILogger logger, string method,
                                                                                        object payload = null, JsonSerializerSettings payloadJsonSerializerSettings = null)
            where TResponse : class
        {
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(method), $"{nameof(method)} must not be empty");

            logger.LogInvoke(new[] { "\"" + method + "\"" });

            var tasks = endPoints.Select(endPoint => BuildRequestTask(logger, endPoint, method, payload, CancellationToken.None, payloadJsonSerializerSettings)).ToArray();

            try
            {
                await Task.WhenAll(tasks);
            }

            catch (Exception)
            {
                // ignored
            }

            var results = tasks.Select((x, i) => MapDaemonResponse <TResponse>(i, x))
                          .ToArray();

            return(results);
        }
Пример #9
0
        public ShareRecorder(IConnectionFactory cf,
                             IMapper mapper,
                             JsonSerializerSettings jsonSerializerSettings,
                             IShareRepository shareRepo,
                             IBlockRepository blockRepo,
                             ClusterConfig clusterConfig,
                             IMessageBus messageBus)
        {
            Contract.RequiresNonNull(cf, nameof(cf));
            Contract.RequiresNonNull(mapper, nameof(mapper));
            Contract.RequiresNonNull(shareRepo, nameof(shareRepo));
            Contract.RequiresNonNull(blockRepo, nameof(blockRepo));
            Contract.RequiresNonNull(jsonSerializerSettings, nameof(jsonSerializerSettings));
            Contract.RequiresNonNull(messageBus, nameof(messageBus));

            this.cf     = cf;
            this.mapper = mapper;
            this.jsonSerializerSettings = jsonSerializerSettings;
            this.messageBus             = messageBus;
            this.clusterConfig          = clusterConfig;

            this.shareRepo = shareRepo;
            this.blockRepo = blockRepo;

            pools = clusterConfig.Pools.ToDictionary(x => x.Id, x => x);

            BuildFaultHandlingPolicy();
            ConfigureRecovery();
        }
Пример #10
0
        public InvalidShareRecorder(IConnectionFactory cf, IMapper mapper,
                                    JsonSerializerSettings jsonSerializerSettings,
                                    IInvalidShareRepository shareRepo,
                                    IMasterClock clock,
                                    IMessageBus messageBus,
                                    NotificationService notificationService)
        {
            Contract.RequiresNonNull(cf, nameof(cf));
            Contract.RequiresNonNull(mapper, nameof(mapper));
            Contract.RequiresNonNull(shareRepo, nameof(shareRepo));
            Contract.RequiresNonNull(jsonSerializerSettings, nameof(jsonSerializerSettings));
            Contract.RequiresNonNull(clock, nameof(clock));
            Contract.RequiresNonNull(messageBus, nameof(messageBus));
            Contract.RequiresNonNull(notificationService, nameof(notificationService));

            this.cf     = cf;
            this.mapper = mapper;
            this.jsonSerializerSettings = jsonSerializerSettings;
            this.clock               = clock;
            this.messageBus          = messageBus;
            this.notificationService = notificationService;

            this.shareRepo = shareRepo;

            BuildFaultHandlingPolicy();
        }
Пример #11
0
        protected PayoutHandlerBase(
            IConnectionFactory cf,
            IMapper mapper,
            IShareRepository shareRepo,
            IBlockRepository blockRepo,
            IBalanceRepository balanceRepo,
            IPaymentRepository paymentRepo,
            IMasterClock clock,
            IMessageBus messageBus)
        {
            Contract.RequiresNonNull(cf, nameof(cf));
            Contract.RequiresNonNull(mapper, nameof(mapper));
            Contract.RequiresNonNull(shareRepo, nameof(shareRepo));
            Contract.RequiresNonNull(blockRepo, nameof(blockRepo));
            Contract.RequiresNonNull(balanceRepo, nameof(balanceRepo));
            Contract.RequiresNonNull(paymentRepo, nameof(paymentRepo));
            Contract.RequiresNonNull(clock, nameof(clock));
            Contract.RequiresNonNull(messageBus, nameof(messageBus));

            this.cf          = cf;
            this.mapper      = mapper;
            this.clock       = clock;
            this.shareRepo   = shareRepo;
            this.blockRepo   = blockRepo;
            this.balanceRepo = balanceRepo;
            this.paymentRepo = paymentRepo;
            this.messageBus  = messageBus;

            BuildFaultHandlingPolicy();
        }
Пример #12
0
        protected StratumServer(IComponentContext ctx, IMasterClock clock)
        {
            Contract.RequiresNonNull(ctx, nameof(ctx));
            Contract.RequiresNonNull(clock, nameof(clock));

            this.ctx   = ctx;
            this.clock = clock;
        }
Пример #13
0
        protected JobManagerBase(IComponentContext ctx, IMessageBus messageBus)
        {
            Contract.RequiresNonNull(ctx, nameof(ctx));
            Contract.RequiresNonNull(messageBus, nameof(messageBus));

            this.ctx        = ctx;
            this.messageBus = messageBus;
        }
Пример #14
0
        public void Start(ClusterConfig clusterConfig)
        {
            Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));
            this.clusterConfig = clusterConfig;

            logger.Info(() => $"Launching ...");
            StartApi(clusterConfig);
            StartAdminApi(clusterConfig);
        }
Пример #15
0
        public virtual void Configure(PoolConfig poolConfig, ClusterConfig clusterConfig)
        {
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));
            Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));

            logger             = LogUtil.GetPoolScopedLogger(typeof(PoolBase), poolConfig);
            this.poolConfig    = poolConfig;
            this.clusterConfig = clusterConfig;
        }
Пример #16
0
        public SOLOPaymentScheme(
            IShareRepository shareRepo,
            IBalanceRepository balanceRepo)
        {
            Contract.RequiresNonNull(shareRepo, nameof(shareRepo));
            Contract.RequiresNonNull(balanceRepo, nameof(balanceRepo));

            this.shareRepo   = shareRepo;
            this.balanceRepo = balanceRepo;
        }
Пример #17
0
        public async Task <Share> SubmitShareAsync(StratumClient worker,
                                                   CryptonoteSubmitShareRequest request, CryptonoteWorkerJob workerJob, double stratumDifficultyBase, CancellationToken ct)
        {
            Contract.RequiresNonNull(worker, nameof(worker));
            Contract.RequiresNonNull(request, nameof(request));

            logger.LogInvoke(new[] { worker.ConnectionId });
            var context = worker.ContextAs <CryptonoteWorkerContext>();

            var job = currentJob;

            if (workerJob.Height != job?.BlockTemplate.Height)
            {
                throw new StratumException(StratumError.MinusOne, "block expired");
            }

            // validate & process
            var(share, blobHex, blobHash) = job.ProcessShare(request.Nonce, workerJob.ExtraNonce, request.Hash, worker);

            // enrich share with common data
            share.PoolId            = poolConfig.Id;
            share.IpAddress         = worker.RemoteEndpoint.Address.ToString();
            share.Miner             = context.MinerName;
            share.Worker            = context.WorkerName;
            share.PayoutInfo        = context.PaymentId;
            share.UserAgent         = context.UserAgent;
            share.Source            = clusterConfig.ClusterName;
            share.NetworkDifficulty = job.BlockTemplate.Difficulty;
            share.Created           = clock.Now;

            // if block candidate, submit & check if accepted by network
            if (share.IsBlockCandidate)
            {
                logger.Info(() => $"Submitting block {share.BlockHeight} [{blobHash.Substring(0, 6)}]");

                share.IsBlockCandidate = await SubmitBlockAsync(share, blobHex, blobHash);

                if (share.IsBlockCandidate)
                {
                    logger.Info(() => $"Daemon accepted block {share.BlockHeight} [{blobHash.Substring(0, 6)}] submitted by {context.MinerName}");
                    blockSubmissionSubject.OnNext(Unit.Default);

                    share.TransactionConfirmationData = blobHash;
                }

                else
                {
                    // clear fields that no longer apply
                    share.TransactionConfirmationData = null;
                }
            }

            return(share);
        }
Пример #18
0
        public byte[] WithFirst(byte[] first)
        {
            Contract.RequiresNonNull(first, nameof(first));

            foreach (var step in Steps)
            {
                first = DoubleDigest(first.Concat(step)).ToArray();
            }

            return(first);
        }
Пример #19
0
        public async Task ConfigureAsync(ClusterConfig clusterConfig, PoolConfig poolConfig)
        {
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));

            this.poolConfig    = poolConfig;
            this.clusterConfig = clusterConfig;
            extraConfig        = poolConfig.PaymentProcessing.Extra.SafeExtensionDataAs <CryptonotePoolPaymentProcessingConfigExtra>();

            logger = LogUtil.GetPoolScopedLogger(typeof(CryptonotePayoutHandler), poolConfig);

            // configure standard daemon
            var jsonSerializerSettings = ctx.Resolve <JsonSerializerSettings>();

            var daemonEndpoints = poolConfig.Daemons
                                  .Where(x => string.IsNullOrEmpty(x.Category))
                                  .Select(x =>
            {
                if (string.IsNullOrEmpty(x.HttpPath))
                {
                    x.HttpPath = CryptonoteConstants.DaemonRpcLocation;
                }

                return(x);
            })
                                  .ToArray();

            daemon = new DaemonClient(jsonSerializerSettings, messageBus, clusterConfig.ClusterName ?? poolConfig.PoolName, poolConfig.Id);
            daemon.Configure(daemonEndpoints);

            // configure wallet daemon
            var walletDaemonEndpoints = poolConfig.Daemons
                                        .Where(x => x.Category?.ToLower() == CryptonoteConstants.WalletDaemonCategory)
                                        .Select(x =>
            {
                if (string.IsNullOrEmpty(x.HttpPath))
                {
                    x.HttpPath = CryptonoteConstants.DaemonRpcLocation;
                }

                return(x);
            })
                                        .ToArray();

            walletDaemon = new DaemonClient(jsonSerializerSettings, messageBus, clusterConfig.ClusterName ?? poolConfig.PoolName, poolConfig.Id);
            walletDaemon.Configure(walletDaemonEndpoints);

            // detect network
            await GetNetworkTypeAsync();

            // detect transfer_split support
            var response = await walletDaemon.ExecuteCmdSingleAsync <TransferResponse>(logger, CryptonoteWalletCommands.TransferSplit);

            walletSupportsTransferSplit = response.Error.Code != CryptonoteConstants.MoneroRpcMethodNotFound;
        }
Пример #20
0
        public async Task StartAsync(CancellationToken ct)
        {
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));

            logger.Info(() => $"Starting Job Manager ...");

            await StartDaemonAsync(ct);
            await EnsureDaemonsSynchedAsync(ct);
            await PostStartInitAsync(ct);

            logger.Info(() => $"Job Manager Online");
        }
Пример #21
0
        public CryptonoteJobManager(
            IComponentContext ctx,
            IMasterClock clock,
            IMessageBus messageBus) :
            base(ctx, messageBus)
        {
            Contract.RequiresNonNull(ctx, nameof(ctx));
            Contract.RequiresNonNull(clock, nameof(clock));
            Contract.RequiresNonNull(messageBus, nameof(messageBus));

            this.clock = clock;
        }
Пример #22
0
        public virtual (Share Share, string BlockHex) ProcessShare(StratumClient worker,
                                                                   string extraNonce2, string nTime, string nonce, string versionBits = null)
        {
            Contract.RequiresNonNull(worker, nameof(worker));
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(extraNonce2), $"{nameof(extraNonce2)} must not be empty");
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(nTime), $"{nameof(nTime)} must not be empty");
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(nonce), $"{nameof(nonce)} must not be empty");

            var context = worker.ContextAs <BitcoinWorkerContext>();

            // validate nTime
            if (nTime.Length != 8)
            {
                throw new StratumException(StratumError.Other, "incorrect size of ntime");
            }

            var nTimeInt = uint.Parse(nTime, NumberStyles.HexNumber);

            if (nTimeInt < BlockTemplate.CurTime || nTimeInt > ((DateTimeOffset)clock.Now).ToUnixTimeSeconds() + 7200)
            {
                throw new StratumException(StratumError.Other, "ntime out of range");
            }

            // validate nonce
            if (nonce.Length != 8)
            {
                throw new StratumException(StratumError.Other, "incorrect size of nonce");
            }

            var nonceInt = uint.Parse(nonce, NumberStyles.HexNumber);

            // validate version-bits (overt ASIC boost)
            uint versionBitsInt = 0;

            if (context.VersionRollingMask.HasValue && versionBits != null)
            {
                versionBitsInt = uint.Parse(versionBits, NumberStyles.HexNumber);

                // enforce that only bits covered by current mask are changed by miner
                if ((versionBitsInt & ~context.VersionRollingMask.Value) != 0)
                {
                    throw new StratumException(StratumError.Other, "rolling-version mask violation");
                }
            }

            // dupe check
            if (!RegisterSubmit(context.ExtraNonce1, extraNonce2, nTime, nonce))
            {
                throw new StratumException(StratumError.DuplicateShare, "duplicate share");
            }

            return(ProcessShareInternal(worker, extraNonce2, nTimeInt, nonceInt, versionBitsInt));
        }
Пример #23
0
        public bool ValidateAddress(string address)
        {
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(address), $"{nameof(address)} must not be empty");

            if (EthereumConstants.ZeroHashPattern.IsMatch(address) ||
                !EthereumConstants.ValidAddressPattern.IsMatch(address))
            {
                return(false);
            }

            return(true);
        }
Пример #24
0
        public CryptonoteJob(GetBlockTemplateResponse blockTemplate, byte[] instanceId, string jobId,
                             PoolConfig poolConfig, ClusterConfig clusterConfig)
        {
            Contract.RequiresNonNull(blockTemplate, nameof(blockTemplate));
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));
            Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));
            Contract.RequiresNonNull(instanceId, nameof(instanceId));
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty");

            coin          = poolConfig.Template.As <CryptonoteCoinTemplate>();
            BlockTemplate = blockTemplate;
            PrepareBlobTemplate(instanceId);
        }
Пример #25
0
        public void Ban(IPAddress address, TimeSpan duration)
        {
            Contract.RequiresNonNull(address, nameof(address));
            Contract.Requires <ArgumentException>(duration.TotalMilliseconds > 0, $"{nameof(duration)} must not be empty");

            // exclude 127.0.0.1 from ban
            if (address.Equals(IPAddress.Loopback) || address.Equals(IPAddress.IPv6Loopback))
            {
                return;
            }

            cache.Set(address.ToString(), string.Empty, duration);
        }
Пример #26
0
        public override void Configure(PoolConfig poolConfig, ClusterConfig clusterConfig)
        {
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));
            Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));

            logger             = LogUtil.GetPoolScopedLogger(typeof(JobManagerBase <CryptonoteJob>), poolConfig);
            this.poolConfig    = poolConfig;
            this.clusterConfig = clusterConfig;
            extraPoolConfig    = poolConfig.Extra.SafeExtensionDataAs <CryptonotePoolConfigExtra>();

            // extract standard daemon endpoints
            daemonEndpoints = poolConfig.Daemons
                              .Where(x => string.IsNullOrEmpty(x.Category))
                              .Select(x =>
            {
                if (string.IsNullOrEmpty(x.HttpPath))
                {
                    x.HttpPath = CryptonoteConstants.DaemonRpcLocation;
                }

                return(x);
            })
                              .ToArray();

            if (clusterConfig.PaymentProcessing?.Enabled == true && poolConfig.PaymentProcessing?.Enabled == true)
            {
                // extract wallet daemon endpoints
                walletDaemonEndpoints = poolConfig.Daemons
                                        .Where(x => x.Category?.ToLower() == CryptonoteConstants.WalletDaemonCategory)
                                        .Select(x =>
                {
                    if (string.IsNullOrEmpty(x.HttpPath))
                    {
                        x.HttpPath = CryptonoteConstants.DaemonRpcLocation;
                    }

                    // cryptonote daemons only support digest auth
                    x.DigestAuth = true;

                    return(x);
                })
                                        .ToArray();

                if (walletDaemonEndpoints.Length == 0)
                {
                    logger.ThrowLogPoolStartupException("Wallet-RPC daemon is not configured (Daemon configuration for monero-pools require an additional entry of category \'wallet' pointing to the wallet daemon)");
                }
            }

            ConfigureDaemons();
        }
Пример #27
0
        /// <summary>
        /// Executes the request against all configured demons and returns the first successful response
        /// </summary>
        /// <typeparam name="TResponse"></typeparam>
        /// <param name="method"></param>
        /// <param name="payload"></param>
        /// <returns></returns>
        public async Task <DaemonResponse <TResponse> > ExecuteCmdSingleAsync <TResponse>(ILogger logger, string method, object payload = null, JsonSerializerSettings payloadJsonSerializerSettings = null)
            where TResponse : class
        {
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(method), $"{nameof(method)} must not be empty");

            logger.LogInvoke(new[] { "\"" + method + "\"" });

            var task = BuildRequestTask(logger, endPoints.First(), method, payload, CancellationToken.None, payloadJsonSerializerSettings);
            await Task.WhenAny(new[] { task });

            var result = MapDaemonResponse <TResponse>(0, task);

            return(result);
        }
Пример #28
0
        public ApiServer(
            IComponentContext ctx,
            IMapper mapper,
            IConnectionFactory cf,
            IBlockRepository blocksRepo,
            IPaymentRepository paymentsRepo,
            IStatsRepository statsRepo,
            IMasterClock clock,
            IMessageBus messageBus)
        {
            Contract.RequiresNonNull(ctx, nameof(ctx));
            Contract.RequiresNonNull(cf, nameof(cf));
            Contract.RequiresNonNull(statsRepo, nameof(statsRepo));
            Contract.RequiresNonNull(blocksRepo, nameof(blocksRepo));
            Contract.RequiresNonNull(paymentsRepo, nameof(paymentsRepo));
            Contract.RequiresNonNull(mapper, nameof(mapper));
            Contract.RequiresNonNull(clock, nameof(clock));
            Contract.RequiresNonNull(messageBus, nameof(messageBus));

            this.ctx          = ctx;
            this.cf           = cf;
            this.statsRepo    = statsRepo;
            this.blocksRepo   = blocksRepo;
            this.paymentsRepo = paymentsRepo;
            this.mapper       = mapper;
            this.clock        = clock;

            messageBus.Listen <BlockNotification>().Subscribe(OnBlockNotification);

            requestMap = new Dictionary <Regex, Func <HttpContext, Match, Task> >
            {
                { new Regex("^/api/pools$", RegexOptions.Compiled), GetPoolInfosAsync },
                { new Regex("^/api/pools/(?<poolId>[^/]+)/performance$", RegexOptions.Compiled), GetPoolPerformanceAsync },
                { new Regex("^/api/pools/(?<poolId>[^/]+)/miners$", RegexOptions.Compiled), PagePoolMinersAsync },
                { new Regex("^/api/pools/(?<poolId>[^/]+)/blocks$", RegexOptions.Compiled), PagePoolBlocksPagedAsync },
                { new Regex("^/api/pools/(?<poolId>[^/]+)/payments$", RegexOptions.Compiled), PagePoolPaymentsAsync },
                { new Regex("^/api/pools/(?<poolId>[^/]+)$", RegexOptions.Compiled), GetPoolInfoAsync },
                { new Regex("^/api/pools/(?<poolId>[^/]+)/miners/(?<address>[^/]+)/payments$", RegexOptions.Compiled), PageMinerPaymentsAsync },
                { new Regex("^/api/pools/(?<poolId>[^/]+)/miners/(?<address>[^/]+)/balancechanges$", RegexOptions.Compiled), PageMinerBalanceChangesAsync },
                { new Regex("^/api/pools/(?<poolId>[^/]+)/miners/(?<address>[^/]+)/earnings/daily", RegexOptions.Compiled), PageMinerEarningsByDayAsync },
                { new Regex("^/api/pools/(?<poolId>[^/]+)/miners/(?<address>[^/]+)/performance$", RegexOptions.Compiled), GetMinerPerformanceAsync },
                { new Regex("^/api/pools/(?<poolId>[^/]+)/miners/(?<address>[^/]+)$", RegexOptions.Compiled), GetMinerInfoAsync },
            };

            requestMapAdmin = new Dictionary <Regex, Func <HttpContext, Match, Task> >
            {
                { new Regex("^/api/admin/forcegc$", RegexOptions.Compiled), HandleForceGcAsync },
                { new Regex("^/api/admin/stats/gc$", RegexOptions.Compiled), HandleGcStatsAsync },
            };
        }
Пример #29
0
        /// <summary>
        /// Executes the requests against all configured demons and returns the first successful response array
        /// </summary>
        /// <returns></returns>
        public async Task <DaemonResponse <JToken>[]> ExecuteBatchAnyAsync(ILogger logger, params DaemonCmd[] batch)
        {
            Contract.RequiresNonNull(batch, nameof(batch));

            logger.LogInvoke(batch.Select(x => "\"" + x.Method + "\"").ToArray());

            var tasks = endPoints.Select(endPoint => BuildBatchRequestTask(logger, endPoint, batch)).ToArray();

            var taskFirstCompleted = await Task.WhenAny(tasks);

            var result = MapDaemonBatchResponse(0, taskFirstCompleted);

            return(result);
        }
Пример #30
0
        public CryptonoteJobManager(IComponentContext ctx, IMasterClock clock, IMessageBus messageBus) : base(ctx, messageBus)
        {
            Contract.RequiresNonNull(ctx, nameof(ctx));
            Contract.RequiresNonNull(clock, nameof(clock));
            Contract.RequiresNonNull(messageBus, nameof(messageBus));

            this.clock = clock;

            using (var rng = RandomNumberGenerator.Create())
            {
                instanceId = new byte[CryptonoteConstants.InstanceIdSize];
                rng.GetNonZeroBytes(instanceId);
            }
        }