Пример #1
0
        protected PayoutHandlerBase(IConnectionFactory cf, IMapper mapper,
                                    IShareRepository shareRepo,
                                    IBlockRepository blockRepo,
                                    IBalanceRepository balanceRepo,
                                    IPaymentRepository paymentRepo,
                                    IMasterClock clock,
                                    NotificationService notificationService)
        {
            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(notificationService, nameof(notificationService));

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

            BuildFaultHandlingPolicy();
        }
Пример #2
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), HandleGetPoolsAsync },
                { new Regex("^/api/pool/(?<poolId>[^/]+)/stats/hourly$", RegexOptions.Compiled), HandleGetPoolStatsAsync },
                { new Regex("^/api/pool/(?<poolId>[^/]+)/blocks$", RegexOptions.Compiled), HandleGetBlocksPagedAsync },
                { new Regex("^/api/pool/(?<poolId>[^/]+)/payments$", RegexOptions.Compiled), HandleGetPaymentsPagedAsync },
                { new Regex("^/api/pool/(?<poolId>[^/]+)/miner/(?<address>[^/]+)/stats$", RegexOptions.Compiled), HandleGetMinerStatsAsync },
            };
        }
Пример #3
0
        public void RespondError(object id, int code, string message)
        {
            Contract.RequiresNonNull(id, nameof(id));
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(message), $"{nameof(message)} must not be empty");

            Respond(new JsonRpcResponse(new JsonRpcException(code, message, null), id));
        }
Пример #4
0
        public override void Configure(PoolConfig poolConfig, ClusterConfig clusterConfig)
        {
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));
            Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));

            logger             = LogUtil.GetPoolScopedLogger(typeof(JobManagerBase <MoneroJob>), poolConfig);
            this.poolConfig    = poolConfig;
            this.clusterConfig = clusterConfig;

            // extract standard daemon endpoints
            daemonEndpoints = poolConfig.Daemons
                              .Where(x => string.IsNullOrEmpty(x.Category))
                              .ToArray();

            // extract wallet daemon endpoints
            walletDaemonEndpoints = poolConfig.Daemons
                                    .Where(x => x.Category?.ToLower() == MoneroConstants.WalletDaemonCategory)
                                    .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)", LogCat);
            }

            ConfigureDaemons();
        }
Пример #5
0
        public virtual async Task StartAsync()
        {
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));

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

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

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

                StartListeners(ipEndpoints);
                SetupStats();
                await UpdateBlockChainStatsAsync();

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

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

            catch (Exception ex)
            {
                logger.Error(ex);
                throw;
            }
        }
Пример #6
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 =>
            {
                var handler = new SocketsHttpHandler
                {
                    Credentials            = new NetworkCredential(endpoint.User, endpoint.Password),
                    PreAuthenticate        = true,
                    AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip,
                };

                if (endpoint.Ssl && !endpoint.ValidateCert)
                {
                    handler.SslOptions = new SslClientAuthenticationOptions
                    {
                        RemoteCertificateValidationCallback = ((sender, certificate, chain, errors) => true),
                    };
                }

                return(new HttpClient(handler));
            });
        }
Пример #7
0
        public void Send <T>(T payload)
        {
            Contract.RequiresNonNull(payload, nameof(payload));

            if (isAlive)
            {
                using (var stream = (RecyclableMemoryStream)streamManager.GetStream())
                {
                    using (var writer = new StreamWriter(stream, Encoding, 0x400, true))
                    {
                        Serializer.Serialize(writer, payload);
                    }

                    // append newline
                    stream.WriteByte(0xa);

                    // log it
                    logger.Trace(() => $"[{ConnectionId}] Sending: {Encoding.GetString(stream.GetBuffer(), 0, (int)stream.Length)}");

                    // copy buffer and queue up
                    var buf = ByteArrayPool.Rent((int)stream.Length);
                    Array.Copy(stream.GetBuffer(), buf, stream.Length);

                    SendInternal(new PooledArraySegment <byte>(buf, 0, (int)stream.Length));
                }
            }
        }
Пример #8
0
        public void Configure(ClusterConfig clusterConfig, PoolConfig poolConfig)
        {
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));

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

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

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

            var daemonEndpoints = poolConfig.Daemons
                                  .Where(x => string.IsNullOrEmpty(x.Category))
                                  .ToArray();

            daemon = new DaemonClient(jsonSerializerSettings);
            daemon.Configure(daemonEndpoints, MoneroConstants.DaemonRpcLocation);

            // configure wallet daemon
            var walletDaemonEndpoints = poolConfig.Daemons
                                        .Where(x => x.Category?.ToLower() == MoneroConstants.WalletDaemonCategory)
                                        .ToArray();

            walletDaemon = new DaemonClient(jsonSerializerSettings);
            walletDaemon.Configure(walletDaemonEndpoints, MoneroConstants.DaemonRpcLocation);
        }
Пример #9
0
        public async Task PayoutAsync(Balance[] balances)
        {
            Contract.RequiresNonNull(balances, nameof(balances));

            // simple balances first
            var simpleBalances = balances
                                 .Where(x => !x.Address.Contains(PayoutConstants.PayoutInfoSeperator))
                                 .ToArray();

            if (simpleBalances.Length > 0)
            {
                await PayoutBatch(simpleBalances);
            }

            // balances with paymentIds
            var extraConfig = poolConfig.PaymentProcessing.Extra.SafeExtensionDataAs <MoneroPoolPaymentProcessingConfigExtra>();

            var minimumPaymentToPaymentId = extraConfig?.MinimumPaymentToPaymentId ?? poolConfig.PaymentProcessing.MinimumPayment;

            var paymentIdBalances = balances.Except(simpleBalances)
                                    .Where(x => x.Amount >= minimumPaymentToPaymentId)
                                    .ToArray();

            foreach (var balance in paymentIdBalances)
            {
                await PayoutToPaymentId(balance);
            }
        }
Пример #10
0
        public void Respond <T>(T payload, object id)
        {
            Contract.RequiresNonNull(payload, nameof(payload));
            Contract.RequiresNonNull(id, nameof(id));

            Respond(new JsonRpcResponse <T>(payload, id));
        }
Пример #11
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");

            cache.Set(address.ToString(), string.Empty, duration);
        }
Пример #12
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 =>
            {
                var handler = new HttpClientHandler
                {
                    Credentials            = new NetworkCredential(endpoint.User, endpoint.Password),
                    PreAuthenticate        = true,
                    AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
                };

                if (endpoint.Ssl && !endpoint.ValidateCert)
                {
                    handler.ClientCertificateOptions = ClientCertificateOption.Manual;
                    handler.ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true;
                }

                HttpClient httpClient = new HttpClient(handler);
                httpClient.Timeout    = TimeSpan.FromSeconds(10);
                return(httpClient);
            });
        }
Пример #13
0
        protected PoolBase(IComponentContext ctx,
                           JsonSerializerSettings serializerSettings,
                           IConnectionFactory cf,
                           IStatsRepository statsRepo,
                           IMapper mapper,
                           IEnumerable <Meta <INotificationSender, NotificationSenderMetadataAttribute> > notificationSenders) : 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(notificationSenders, nameof(notificationSenders));

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

            Shares = shareSubject
                     .AsObservable()
                     .Synchronize();

            validShares = validSharesSubject
                          .AsObservable()
                          .Synchronize();

            invalidShares = invalidSharesSubject
                            .AsObservable()
                            .Synchronize();
        }
Пример #14
0
        protected PayoutHandlerBase(IConnectionFactory cf, IMapper mapper,
                                    IShareRepository shareRepo,
                                    IBlockRepository blockRepo,
                                    IBalanceRepository balanceRepo,
                                    IPaymentRepository paymentRepo,
                                    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(balanceRepo, nameof(balanceRepo));
            Contract.RequiresNonNull(paymentRepo, nameof(paymentRepo));
            Contract.RequiresNonNull(notificationSenders, nameof(notificationSenders));

            this.cf                  = cf;
            this.mapper              = mapper;
            this.shareRepo           = shareRepo;
            this.blockRepo           = blockRepo;
            this.balanceRepo         = balanceRepo;
            this.paymentRepo         = paymentRepo;
            this.notificationSenders = notificationSenders;

            BuildFaultHandlingPolicy();
        }
Пример #15
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 <MoneroPoolPaymentProcessingConfigExtra>();

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

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

            var daemonEndpoints = poolConfig.Daemons
                                  .Where(x => string.IsNullOrEmpty(x.Category))
                                  .ToArray();

            daemon = new DaemonClient(jsonSerializerSettings);
            daemon.Configure(daemonEndpoints, MoneroConstants.DaemonRpcLocation);

            // configure wallet daemon
            var walletDaemonEndpoints = poolConfig.Daemons
                                        .Where(x => x.Category?.ToLower() == MoneroConstants.WalletDaemonCategory)
                                        .ToArray();

            walletDaemon = new DaemonClient(jsonSerializerSettings);
            walletDaemon.Configure(walletDaemonEndpoints, MoneroConstants.DaemonRpcLocation);

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

            walletSupportsTransferSplit = response.Error.Code != MoneroConstants.MoneroRpcMethodNotFound;
        }
Пример #16
0
        protected PoolBase(IComponentContext ctx,
                           JsonSerializerSettings serializerSettings,
                           IConnectionFactory cf,
                           IStatsRepository statsRepo,
                           IMapper mapper,
                           IMasterClock clock,
                           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(clock, nameof(clock));
            Contract.RequiresNonNull(notificationService, nameof(notificationService));

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

            Shares = shareSubject
                     .Synchronize();
        }
Пример #17
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();
        }
Пример #18
0
        public void StartListeners(string id, params IPEndPoint[] stratumPorts)
        {
            Contract.RequiresNonNull(stratumPorts, nameof(stratumPorts));

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

                    try
                    {
                        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;
                        }
                    }

                    catch (Exception ex)
                    {
                        logger.Error(ex, $"[{LogCat}] {ex}");
                        throw;
                    }

                    logger.Info(() => $"[{LogCat}] Stratum port {endpoint.Address}:{endpoint.Port} online");

                    try
                    {
                        loop.RunDefault();
                    }

                    catch (Exception ex)
                    {
                        logger.Error(ex, $"[{LogCat}] {ex}");
                    }
                })
                {
                    Name = $"UvLoopThread {id}:{endpoint.Port}"
                };

                thread.Start();
            }
        }
Пример #19
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;

            case CoinType.XMR:
                hashSlow = buf =>
                {
                    // PoW variant
                    var variant = buf[0] >= 7 ? buf[0] - 6 : 0;

                    return(LibCryptonote.CryptonightHashSlow(buf, variant));
                };
                break;

            default:
                hashSlow = buf => LibCryptonote.CryptonightHashSlow(buf, 0);
                break;
            }

            BlockTemplate = blockTemplate;
            PrepareBlobTemplate(instanceId);
        }
Пример #20
0
        public bool IsBanned(IPAddress address)
        {
            Contract.RequiresNonNull(address, nameof(address));

            var result = cache.Get(address.ToString());

            return(result != null);
        }
Пример #21
0
        protected JobManagerBase(IComponentContext ctx, IMessageBus messageBus)
        {
            Contract.RequiresNonNull(ctx, nameof(ctx));
            Contract.RequiresNonNull(messageBus, nameof(messageBus));

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

            this.ctx   = ctx;
            this.clock = clock;
        }
Пример #23
0
        public override async Task PayoutAsync(Balance[] balances)
        {
            Contract.RequiresNonNull(balances, nameof(balances));

            // build args
            var amounts = balances
                          .Where(x => x.Amount > 0)
                          .ToDictionary(x => x.Address, x => Math.Round(x.Amount, 8));

            if (amounts.Count == 0)
            {
                return;
            }

            logger.Info(() => $"[{LogCategory}] Paying out {FormatAmount(balances.Sum(x => x.Amount))} to {balances.Length} addresses");

            var smr = new SendManyRequest();

            smr.FromAccount = String.Empty;
            smr.Amounts     = amounts;
            smr.FloData     = "MiningCore payout";

            if (extraPoolPaymentProcessingConfig?.MinersPayTxFees == true)
            {
                // distribute transaction fee equally over all recipients
                var subtractFeesFrom = amounts.Keys.ToArray();
                smr.SubtractFeeFrom = subtractFeesFrom;
            }

            // send command
            var result = await daemon.ExecuteCmdSingleAsync <string>(BitcoinCommands.SendMany, smr, new JsonSerializerSettings());

            if (result.Error == null)
            {
                var txId = result.Response;

                // check result
                if (string.IsNullOrEmpty(txId))
                {
                    logger.Error(() => $"[{LogCategory}] {BitcoinCommands.SendMany} did not return a transaction id!");
                }
                else
                {
                    logger.Info(() => $"[{LogCategory}] Payout transaction id: {txId}");
                }

                PersistPayments(balances, txId);

                NotifyPayoutSuccess(poolConfig.Id, balances, new[] { txId }, null);
            }

            else
            {
                logger.Error(() => $"[{LogCategory}] {BitcoinCommands.SendMany} returned error: {result.Error.Message} code {result.Error.Code}");

                NotifyPayoutFailure(poolConfig.Id, balances, $"{BitcoinCommands.SendMany} returned error: {result.Error.Message} code {result.Error.Code}", null);
            }
        }
Пример #24
0
        public void Start(ClusterConfig clusterConfig)
        {
            Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));
            this.clusterConfig = clusterConfig;

            logger.Info(() => $"Launching ...");
            StartApi(clusterConfig);
            StartAdminApi(clusterConfig);
        }
Пример #25
0
        public void Respond <T>(JsonRpcResponse <T> response)
        {
            Contract.RequiresNonNull(response, nameof(response));

            lock (rpcCon)
            {
                rpcCon?.Send(response);
            }
        }
Пример #26
0
        public void Notify <T>(JsonRpcRequest <T> request)
        {
            Contract.RequiresNonNull(request, nameof(request));

            lock (rpcCon)
            {
                rpcCon?.Send(request);
            }
        }
Пример #27
0
        public virtual void Configure(PoolConfig poolConfig, ClusterConfig clusterConfig)
        {
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));
            Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));

            logger             = LogUtil.GetPoolScopedLogger(typeof(PoolBase <TWorkerContext>), poolConfig);
            this.poolConfig    = poolConfig;
            this.clusterConfig = clusterConfig;
        }
Пример #28
0
        public async Task PayoutAsync(Balance[] balances)
        {
            Contract.RequiresNonNull(balances, nameof(balances));

            // build args
            var amounts = balances
                          .Where(x => x.Amount > 0)
                          .ToDictionary(x => x.Address, x => Math.Round(x.Amount, 8));

            if (amounts.Count == 0)
            {
                return;
            }

            logger.Info(() => $"[{LogCategory}] Paying out {FormatAmount(balances.Sum(x => x.Amount))} to {balances.Length} addresses");

            var subtractFeesFrom = amounts.Keys.ToArray();

            var args = new object[]
            {
                string.Empty,           // default account
                amounts,                // addresses and associated amounts
                1,                      // only spend funds covered by this many confirmations
                "MiningCore Payout",    // comment
                subtractFeesFrom        // distribute transaction fee equally over all recipients
            };

            // send command
            var result = await daemon.ExecuteCmdSingleAsync <string>(BitcoinCommands.SendMany, args, new JsonSerializerSettings());

            if (result.Error == null)
            {
                var txId = result.Response;

                // check result
                if (string.IsNullOrEmpty(txId))
                {
                    logger.Error(() => $"[{LogCategory}] Daemon command '{BitcoinCommands.SendMany}' did not return a transaction id!");
                }
                else
                {
                    logger.Info(() => $"[{LogCategory}] Payout transaction id: {txId}");
                }

                PersistPayments(balances, txId);

                NotifyPayoutSuccess(balances, new [] { txId }, null);
            }

            else
            {
                logger.Error(() => $"[{LogCategory}] Daemon command '{BitcoinCommands.SendMany}' returned error: {result.Error.Message} code {result.Error.Code}");

                NotifyPayoutFailure(balances, $"Daemon command '{BitcoinCommands.SendMany}' returned error: {result.Error.Message} code {result.Error.Code}", null);
            }
        }
Пример #29
0
        public virtual void Init(TBlockTemplate blockTemplate, string jobId,
                                 PoolConfig poolConfig, ClusterConfig clusterConfig, IMasterClock clock,
                                 IDestination poolAddressDestination, BitcoinNetworkType networkType,
                                 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(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 = BitcoinExtraNonceProvider.PlaceHolderLength;
            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();

            jobParams = new object[]
            {
                JobId,
                previousBlockHashReversedHex,
                coinbaseInitialHex,
                coinbaseFinalHex,
                merkleBranchesHex,
                BlockTemplate.Version.ToStringHex8(),
                BlockTemplate.Bits,
                BlockTemplate.CurTime.ToStringHex8(),
                false
            };
        }
Пример #30
0
        public EthereumJobManager(
            IComponentContext ctx,
            IMasterClock clock) :
            base(ctx)
        {
            Contract.RequiresNonNull(ctx, nameof(ctx));
            Contract.RequiresNonNull(clock, nameof(clock));

            this.clock = clock;
        }