public override async Task OnRequestAsync(IStratumClient client, Timestamped <JsonRpcRequest> timeStampedRequest) { var request = timeStampedRequest.Value; var context = client.GetContextAs <MoneroWorkerContext>(); switch (request.Method) { case MoneroStratumMethods.Login: OnLogin(client, timeStampedRequest); break; case MoneroStratumMethods.GetJob: OnGetJob(client, timeStampedRequest); break; case MoneroStratumMethods.Submit: await OnSubmitAsync(client, timeStampedRequest); break; case MoneroStratumMethods.KeepAlive: context.LastActivity = MasterClock.Now; // recognize activity. break; default: _logger.Debug($"[{client.ConnectionId}] Unsupported RPC request: {JsonConvert.SerializeObject(request, Globals.JsonSerializerSettings)}"); client.RespondError(StratumError.Other, $"Unsupported request {request.Method}", request.Id); break; } }
public void OnConnect(IStratumClient client) { var context = CreateClientContext(); // create worker context. context.Initialize(7500); client.SetContext(context); EnsureNoZombie(client); // make sure client communicates within a set period of time. }
public MoneroJobParams CreateWorkerJob(IStratumClient client) { var context = client.GetContextAs <MoneroWorkerContext>(); var workerJob = new MoneroWorkerJob(_workerJobCounter.GetNext(), BlockTemplate.Height, context.Difficulty, ++extraNonce); var blob = EncodeBlob(workerJob.ExtraNonce); var target = EncodeTarget(workerJob.Difficulty); return(null); }
private void EnsureNoZombie(IStratumClient client) { Observable.Timer(MasterClock.Now.AddSeconds(10)) // wait 10 seconds. .Take(1) .Subscribe(_ => { if (client.LastReceive.HasValue) // if the worker has send some data, { return; // skip him. } _logger.Information($"[{client.ConnectionId}] Booting zombie-worker (post-connect silence)"); PoolContext.StratumServer.DisconnectClient(client); // else boot him from our server. }); }
/// <summary> /// Listen for incoming connection requests and fires event when new client is connected. /// </summary> public async Task ListenAsync() { _listenCts = new CancellationTokenSource(); while (true) { IStratumClient client = await AcceptClientAsync(); if (_listenCts.IsCancellationRequested) { return; } OnClientConnected(new ClientEventArgs(client)); } }
public void DisconnectClient(IStratumClient client) { var subscriptionId = client.ConnectionId; client.Disconnect(); if (!string.IsNullOrEmpty(subscriptionId)) { // unregister client lock (_clients) { _clients.Remove(subscriptionId); } } _pool.OnDisconnect(subscriptionId); }
public ClientEventArgs(IStratumClient client) { Client = client; }
private async Task OnSubmitAsync(IStratumClient client, Timestamped <JsonRpcRequest> tsRequest) { }
private void OnGetJob(IStratumClient client, Timestamped <JsonRpcRequest> tsRequest) { }
private void OnLogin(IStratumClient client, Timestamped <JsonRpcRequest> tsRequest) { var request = tsRequest.Value; var context = client.GetContextAs <MoneroWorkerContext>(); if (request.Id == null) { client.RespondError(StratumError.MinusOne, "missing request id", request.Id); return; } var loginRequest = request.ParamsAs <MoneroLoginRequest>(); if (string.IsNullOrEmpty(loginRequest?.Login)) { client.RespondError(StratumError.MinusOne, "missing login", request.Id); return; } // extract worker & miner. var split = loginRequest.Login.Split('.'); context.MinerName = split[0]; context.WorkerName = split.Length > 1 ? split[1] : null; // set useragent. context.UserAgent = loginRequest.UserAgent; // set payment-id if any. var index = context.MinerName.IndexOf('#'); if (index != -1) { context.MinerName = context.MinerName.Substring(0, index); context.PaymentId = context.MinerName.Substring(index + 1); } var hasValidAddress = ValidateAddress(context.MinerName); context.IsAuthorized = context.IsSubscribed = hasValidAddress; if (!context.IsAuthorized) { client.RespondError(StratumError.MinusOne, "invalid login", request.Id); return; } var loginResponse = new MoneroLoginResponse { Id = client.ConnectionId, Job = ((MoneroJobManager)PoolContext.JobManager).CurrentJob.CreateWorkerJob(client) }; client.Respond(loginResponse, request.Id); // log association _logger.Information($"[{client.ConnectionId}] = {loginRequest.Login} = {client.RemoteEndpoint.Address}"); // recognize activity. context.LastActivity = MasterClock.Now; }
public abstract Task OnRequestAsync(IStratumClient client, Timestamped <JsonRpcRequest> timeStampedRequest);