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; }
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)); }
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 }; }
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 })); }
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(); }
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; } }
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"); } }
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)); }
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; }
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; }
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 }, }; }
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(); }
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; } } }
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(); }
/// <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); }
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); }
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; } }