Пример #1
0
        public MoneroPayoutHandler(
            IComponentContext ctx,
            IConnectionFactory cf,
            IMapper mapper,
            IShareRepository shareRepo,
            IBlockRepository blockRepo,
            IBalanceRepository balanceRepo,
            IPaymentRepository paymentRepo,
            IMasterClock clock,
            IMessageBus messageBus) :
            base(cf, mapper, shareRepo, blockRepo, balanceRepo, paymentRepo, clock, messageBus)
        {
            Contract.RequiresNonNull(ctx, nameof(ctx));
            Contract.RequiresNonNull(balanceRepo, nameof(balanceRepo));
            Contract.RequiresNonNull(paymentRepo, nameof(paymentRepo));

            this.ctx = ctx;
        }
        public EthereumPayoutHandler(
            IComponentContext ctx,
            IConnectionFactory cf,
            IMapper mapper,
            IShareRepository shareRepo,
            IBlockRepository blockRepo,
            IBalanceRepository balanceRepo,
            IPaymentRepository paymentRepo,
            IMasterClock clock,
            NotificationService notificationService) :
            base(cf, mapper, shareRepo, blockRepo, balanceRepo, paymentRepo, clock, notificationService)
        {
            Contract.RequiresNonNull(ctx, nameof(ctx));
            Contract.RequiresNonNull(balanceRepo, nameof(balanceRepo));
            Contract.RequiresNonNull(paymentRepo, nameof(paymentRepo));

            this.ctx = ctx;
        }
Пример #3
0
        public virtual Task ConfigureAsync(ClusterConfig clusterConfig, PoolConfig poolConfig)
        {
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));

            this.poolConfig    = poolConfig;
            this.clusterConfig = clusterConfig;

            coinProperties = BitcoinProperties.GetCoinProperties(poolConfig.Coin.Type, poolConfig.Coin.Algorithm);

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

            var jsonSerializerSettings = ctx.Resolve <JsonSerializerSettings>();

            daemon = new DaemonClient(jsonSerializerSettings);
            daemon.Configure(poolConfig.Daemons);

            return(Task.FromResult(true));
        }
Пример #4
0
        public EthereumJobManager(
            IComponentContext ctx,
            IMasterClock clock,
            IMessageBus messageBus,
            JsonSerializerSettings serializerSettings) :
            base(ctx, messageBus)
        {
            Contract.RequiresNonNull(ctx, nameof(ctx));
            Contract.RequiresNonNull(clock, nameof(clock));
            Contract.RequiresNonNull(messageBus, nameof(messageBus));

            this.clock = clock;

            serializer = new JsonSerializer
            {
                ContractResolver = serializerSettings.ContractResolver
            };
        }
Пример #5
0
        public void Configure(DaemonEndpointConfig[] endPoints, string rpcLocation = null,
                              string digestAuthRealm = null)
        {
            Contract.RequiresNonNull(endPoints, nameof(endPoints));
            Contract.Requires <ArgumentException>(endPoints.Length > 0, $"{nameof(endPoints)} must not be empty");

            this.endPoints   = endPoints;
            this.rpcLocation = rpcLocation;

            // create one HttpClient instance per endpoint that carries the associated credentials
            httpClients = endPoints.ToDictionary(endpoint => endpoint, endpoint =>
                                                 new HttpClient(new HttpClientHandler
            {
                Credentials            = new NetworkCredential(endpoint.User, endpoint.Password),
                PreAuthenticate        = true,
                AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
            }));
        }
Пример #6
0
        public virtual void Init(TBlockTemplate blockTemplate, string jobId,
                                 PoolConfig poolConfig, ClusterConfig clusterConfig, IMasterClock clock,
                                 IDestination poolAddressDestination, BitcoinNetworkType networkType,
                                 BitcoinExtraNonceProvider extraNonceProvider, bool isPoS, double shareMultiplier,
                                 IHashAlgorithm coinbaseHasher, IHashAlgorithm headerHasher, IHashAlgorithm blockHasher)
        {
            Contract.RequiresNonNull(blockTemplate, nameof(blockTemplate));
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));
            Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));
            Contract.RequiresNonNull(clock, nameof(clock));
            Contract.RequiresNonNull(poolAddressDestination, nameof(poolAddressDestination));
            Contract.RequiresNonNull(extraNonceProvider, nameof(extraNonceProvider));
            Contract.RequiresNonNull(coinbaseHasher, nameof(coinbaseHasher));
            Contract.RequiresNonNull(headerHasher, nameof(headerHasher));
            Contract.RequiresNonNull(blockHasher, nameof(blockHasher));
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty");

            this.poolConfig             = poolConfig;
            this.clusterConfig          = clusterConfig;
            this.clock                  = clock;
            this.poolAddressDestination = poolAddressDestination;
            this.networkType            = networkType;
            BlockTemplate               = blockTemplate;
            JobId      = jobId;
            Difficulty = new Target(new NBitcoin.BouncyCastle.Math.BigInteger(BlockTemplate.Target, 16)).Difficulty;

            extraNoncePlaceHolderLength = extraNonceProvider.PlaceHolder.Length;
            this.isPoS           = isPoS;
            this.shareMultiplier = shareMultiplier;

            this.coinbaseHasher = coinbaseHasher;
            this.headerHasher   = headerHasher;
            this.blockHasher    = blockHasher;

            blockTargetValue = BigInteger.Parse(BlockTemplate.Target, NumberStyles.HexNumber);

            previousBlockHashReversedHex = BlockTemplate.PreviousBlockhash
                                           .HexToByteArray()
                                           .ReverseByteOrder()
                                           .ToHexString();

            BuildMerkleBranches();
            BuildCoinbase();
        }
Пример #7
0
        public virtual async Task StartAsync(CancellationToken ct)
        {
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));

            logger.Info(() => $"[{LogCat}] Launching ...");

            try
            {
                SetupBanning(clusterConfig);
                await SetupJobManager(ct);

                InitStats();

                if (poolConfig.EnableInternalStratum == true)
                {
                    var ipEndpoints = poolConfig.Ports.Keys
                                      .Select(port => PoolEndpoint2IPEndpoint(port, poolConfig.Ports[port]))
                                      .ToArray();

                    StartListeners(ipEndpoints);
                }

                logger.Info(() => $"[{LogCat}] Online");
                OutputPoolInfo();
            }

            catch (PoolStartupAbortException)
            {
                // just forward these
                throw;
            }

            catch (TaskCanceledException)
            {
                // just forward these
                throw;
            }

            catch (Exception ex)
            {
                logger.Error(ex);
                throw;
            }
        }
Пример #8
0
        public void StartListeners(params IPEndPoint[] stratumPorts)
        {
            Contract.RequiresNonNull(stratumPorts, nameof(stratumPorts));

            foreach (var endpoint in stratumPorts)
            {
                // every port gets serviced by a dedicated loop thread
                var thread = new Thread(_ =>
                {
                    var loop = new Loop();

                    var listener = loop
                                   .CreateTcp()
                                   .NoDelay(true)
                                   .SimultaneousAccepts(false)
                                   .Listen(endpoint, (con, ex) =>
                    {
                        if (ex == null)
                        {
                            OnClientConnected(con, endpoint, loop);
                        }
                        else
                        {
                            logger.Error(() => $"[{LogCat}] Connection error state: {ex.Message}");
                        }
                    });

                    lock (ports)
                    {
                        ports[endpoint.Port] = listener;
                    }

                    loop.RunDefault();
                })
                {
                    Name = $"UvLoop Thread Port {endpoint.Port}"
                };

                thread.Start();

                logger.Info(() => $"[{LogCat}] Stratum port {endpoint.Address}:{endpoint.Port} online");
            }
        }
Пример #9
0
        public override Task ConfigureAsync(ClusterConfig clusterConfig, PoolConfig poolConfig)
        {
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));

            this.poolConfig    = poolConfig;
            this.clusterConfig = clusterConfig;

            extraPoolConfig = poolConfig.Extra.SafeExtensionDataAs <BitcoinDaemonEndpointConfigExtra>();
            extraPoolPaymentProcessingConfig = poolConfig.PaymentProcessing.Extra.SafeExtensionDataAs <BitcoinPoolPaymentProcessingConfigExtra>();
            coinProperties = BitcoinProperties.GetCoinProperties(poolConfig.Coin.Type, poolConfig.Coin.Algorithm);

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

            var jsonSerializerSettings = ctx.Resolve <JsonSerializerSettings>();

            daemon = new DaemonClient(jsonSerializerSettings);
            daemon.Configure(poolConfig.Daemons);

            return(Task.FromResult(true));
        }
Пример #10
0
        public PayoutManager(IComponentContext ctx,
                             IConnectionFactory cf,
                             IBlockRepository blockRepo,
                             IShareRepository shareRepo,
                             IBalanceRepository balanceRepo,
                             IEnumerable <Meta <INotificationSender, NotificationSenderMetadataAttribute> > notificationSenders)
        {
            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(notificationSenders, nameof(notificationSenders));

            this.ctx                 = ctx;
            this.cf                  = cf;
            this.blockRepo           = blockRepo;
            this.shareRepo           = shareRepo;
            this.balanceRepo         = balanceRepo;
            this.notificationSenders = notificationSenders;
        }
Пример #11
0
        public PayoutManager(IComponentContext ctx,
                             IConnectionFactory cf,
                             IBlockRepository blockRepo,
                             IShareRepository shareRepo,
                             IBalanceRepository balanceRepo,
                             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;
        }
Пример #12
0
        public ApiServer(
            IMapper mapper,
            IConnectionFactory cf,
            IBlockRepository blocksRepo,
            IPaymentRepository paymentsRepo,
            IStatsRepository statsRepo,
            IMasterClock clock)
        {
            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));

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

            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>[^/]+)/performance$", RegexOptions.Compiled), GetMinerPerformanceAsync },
                { new Regex("^/api/pools/(?<poolId>[^/]+)/miners/(?<address>[^/]+)$", RegexOptions.Compiled), GetMinerInfoAsync },

                // admin api
                { new Regex("^/api/admin/forcegc$", RegexOptions.Compiled), HandleForceGcAsync },
                { new Regex("^/api/admin/stats/gc$", RegexOptions.Compiled), HandleGcStatsAsync },
            };
        }
Пример #13
0
        public ShareRecorder(IConnectionFactory cf, IMapper mapper,
                             JsonSerializerSettings jsonSerializerSettings,
                             IShareRepository shareRepo, IBlockRepository blockRepo,
                             IEnumerable <Meta <INotificationSender, NotificationSenderMetadataAttribute> > notificationSenders)
        {
            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(notificationSenders, nameof(notificationSenders));

            this.cf     = cf;
            this.mapper = mapper;
            this.jsonSerializerSettings = jsonSerializerSettings;
            this.notificationSenders    = notificationSenders;

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

            BuildFaultHandlingPolicy();
        }
Пример #14
0
        public void Send <T>(T payload)
        {
            Contract.RequiresNonNull(payload, nameof(payload));

            if (isAlive)
            {
                var buf = ArrayPool <byte> .Shared.Rent(MaxOutboundRequestLength);

                try
                {
                    using (var stream = new MemoryStream(buf, true))
                    {
                        stream.SetLength(0);
                        int size;

                        using (var writer = new StreamWriter(stream, StratumConstants.Encoding))
                        {
                            serializer.Serialize(writer, payload);
                            writer.Flush();

                            // append newline
                            stream.WriteByte(0xa);
                            size = (int)stream.Position;
                        }

                        logger.Trace(() => $"[{ConnectionId}] Sending: {StratumConstants.Encoding.GetString(buf, 0, size)}");

                        SendInternal(new PooledArraySegment <byte>(buf, 0, size));
                    }
                }

                catch (Exception)
                {
                    ArrayPool <byte> .Shared.Return(buf);

                    throw;
                }
            }
        }
Пример #15
0
        protected PoolBase(IComponentContext ctx,
                           JsonSerializerSettings serializerSettings,
                           IConnectionFactory cf,
                           IStatsRepository statsRepo,
                           IMapper mapper,
                           NotificationService notificationService) : base(ctx)
        {
            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(notificationService, nameof(notificationService));

            this.serializerSettings = serializerSettings;
            this.cf                  = cf;
            this.statsRepo           = statsRepo;
            this.mapper              = mapper;
            this.notificationService = notificationService;

            Shares = shareSubject
                     .Synchronize();
        }
Пример #16
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>(string method,
                                                                                        object payload = null, JsonSerializerSettings payloadJsonSerializerSettings = null)
            where TResponse : class
        {
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(method), $"{nameof(method)} must not be empty");

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

            try
            {
                await Task.WhenAll(tasks);
            }

            catch (Exception)
            {
                // ignored
            }

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

            return(results);
        }
Пример #17
0
        public MoneroJob(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");

            switch (poolConfig.Coin.Type)
            {
            case CoinType.AEON:
                hashSlow = LibCryptonote.CryptonightHashSlowLite;
                break;

            default:
                hashSlow = LibCryptonote.CryptonightHashSlow;
                break;
            }

            BlockTemplate = blockTemplate;
            PrepareBlobTemplate(instanceId);
        }
Пример #18
0
        public virtual async Task StartAsync()
        {
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));

            logger.Info(() => $"[{LogCat}] Launching ...");

            try
            {
                SetupBanning(clusterConfig);
                SetupTelemetry();
                await SetupJobManager();

                var ipEndpoints = poolConfig.Ports.Keys
                                  .Select(port => PoolEndpoint2IPEndpoint(port, poolConfig.Ports[port]))
                                  .ToArray();

                StartListeners(ipEndpoints);
                SetupStats();
                SetupAdminNotifications();

                logger.Info(() => $"[{LogCat}] Online");

                OutputPoolInfo();
            }

            catch (PoolStartupAbortException)
            {
                // just forward these
                throw;
            }

            catch (Exception ex)
            {
                logger.Error(ex);
                throw;
            }
        }