public static BigInteger ToBigInteger(this PooledArraySegment <byte> value) { var buf = new byte[value.Size + 1]; Array.Copy(value.Array, value.Offset, buf, 0, value.Size); return(new BigInteger(buf)); }
public static BigInteger ToBigInteger(this PooledArraySegment <byte> value) { // TODO: can be improved by using the BigInteger(Span<T> buf) constructor coming in .Net core 2.1 var buf = new byte[value.Size + 1]; Array.Copy(value.Array, value.Offset, buf, 0, value.Size); return(new BigInteger(buf)); }
protected virtual void OnReceive(StratumClient client, PooledArraySegment <byte> data) { // get off of LibUV event-loop-thread immediately Task.Run(async() => { using (data) { JsonRpcRequest request = null; try { // boot pre-connected clients if (banManager?.IsBanned(client.RemoteEndpoint.Address) == true) { logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] Disconnecting banned client @ {client.RemoteEndpoint.Address}"); DisconnectClient(client); return; } // de-serialize logger.Trace(() => $"[{LogCat}] [{client.ConnectionId}] Received request data: {StratumConstants.Encoding.GetString(data.Array, 0, data.Size)}"); request = client.DeserializeRequest(data); // dispatch if (request != null) { logger.Debug(() => $"[{LogCat}] [{client.ConnectionId}] Dispatching request '{request.Method}' [{request.Id}]"); await OnRequestAsync(client, new Timestamped <JsonRpcRequest>(request, clock.Now)); } else { logger.Trace(() => $"[{LogCat}] [{client.ConnectionId}] Unable to deserialize request"); } } catch (JsonReaderException jsonEx) { // junk received (no valid json) logger.Error(() => $"[{LogCat}] [{client.ConnectionId}] Connection json error state: {jsonEx.Message}"); if (clusterConfig.Banning?.BanOnJunkReceive.HasValue == false || clusterConfig.Banning?.BanOnJunkReceive == true) { logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] Banning client for sending junk"); banManager?.Ban(client.RemoteEndpoint.Address, TimeSpan.FromMinutes(30)); } } catch (Exception ex) { if (request != null) { logger.Error(ex, () => $"[{LogCat}] [{client.ConnectionId}] Error processing request {request.Method} [{request.Id}]"); } } } }); }
public JsonRpcRequest DeserializeRequest(PooledArraySegment <byte> data) { using (var stream = new MemoryStream(data.Array, data.Offset, data.Size)) { using (var reader = new StreamReader(stream, StratumConstants.Encoding)) { using (var jreader = new JsonTextReader(reader)) { return(serializer.Deserialize <JsonRpcRequest>(jreader)); } } } }
private string EncodeBlob(uint workerExtraNonce) { // clone template using (var blob = new PooledArraySegment <byte>(_blobTemplate.Length)) { Buffer.BlockCopy(_blobTemplate, 0, blob.Array, 0, _blobTemplate.Length); // inject extranonce (big-endian at the beginning of the reserved area of the blob) var extraNonceBytes = BitConverter.GetBytes(workerExtraNonce.ToBigEndian()); Buffer.BlockCopy(extraNonceBytes, 0, blob.Array, (int)BlockTemplate.ReservedOffset, extraNonceBytes.Length); return(LibCryptonote.ConvertBlob(blob.Array, _blobTemplate.Length).ToHexString()); } }
private void SendInternal(PooledArraySegment <byte> buffer) { Contract.RequiresNonNull(buffer, nameof(buffer)); try { sendQueue.Enqueue(buffer); sendQueueDrainer.Send(); } catch (ObjectDisposedException) { buffer.Dispose(); } }
private JsonRpcRequest DeserializeRequest(PooledArraySegment <byte> data) { using (data) { using (var stream = new MemoryStream(data.Array, data.Offset, data.Size)) { using (var reader = new StreamReader(stream, Encoding.UTF8)) { using (var jreader = new JsonTextReader(reader)) { return(serializer.Deserialize <JsonRpcRequest>(jreader)); } } } } }
public static PooledArraySegment <byte> CryptonightHashFast(byte[] data) { Assertion.RequiresNonNull(data, nameof(data)); var result = new PooledArraySegment <byte>(32); fixed(byte *input = data) { fixed(byte *output = result.Array) { cn_fast_hash(input, output, (uint)data.Length); } } return(result); }
private JsonRpcRequest ParseRequest(PooledArraySegment <byte> data) { using (data) { using (var stream = new MemoryStream(data.Array, 0, data.Size)) { using (var reader = new StreamReader(stream, StratumClient <TClientContext> .Encoding)) { using (var jreader = new JsonTextReader(reader)) { return(StratumClient <TClientContext> .Serializer.Deserialize <JsonRpcRequest>(jreader)); } } } } }
public static PooledArraySegment <byte> CryptonightHashSlowLite(byte[] data) { Contract.RequiresNonNull(data, nameof(data)); var result = new PooledArraySegment <byte>(32); fixed(byte *input = data) { fixed(byte *output = result.Array) { cn_slow_hash_lite(input, output, (uint)data.Length); } } return(result); }
public static PooledArraySegment <byte> CryptonightHashFast(byte[] data) { Enforce.ArgumentNotNull(() => data); var result = new PooledArraySegment <byte>(32); fixed(byte *input = data) { fixed(byte *output = result.Array) { cn_fast_hash(input, output, (uint)data.Length); } } return(result); }
public static PooledArraySegment <byte> CryptonightHeavy(byte[] data, int variant) { Contract.RequiresNonNull(data, nameof(data)); var result = new PooledArraySegment <byte>(32); fixed(byte *input = data) { fixed(byte *output = result.Array) { cryptonight_heavy(input, output, (uint)data.Length, variant); } } return(result); }
protected virtual void OnReceive(StratumClient client, PooledArraySegment <byte> data) { // get off of LibUV event-loop-thread immediately Task.Run(async() => { using (data) { JsonRpcRequest request = null; try { // de-serialize _logger.Verbose($"[{client.ConnectionId}] Received request data:\n {StratumConstants.Encoding.GetString(data.Array, 0, data.Size).FormatJson()}"); request = client.DeserializeRequest(data); // dispatch if (request != null) { _logger.Debug($"[{client.ConnectionId}] Dispatching request '{request.Method}' [{request.Id}]"); await _pool.OnRequestAsync(client, new Timestamped <JsonRpcRequest>(request, MasterClock.Now)); } else { _logger.Verbose($"[{client.ConnectionId}] Unable to deserialize request"); } } catch (JsonReaderException jsonEx) { // junk received (no valid json) _logger.Error($"[{client.ConnectionId}] Connection json error state: {jsonEx.Message}"); } catch (Exception ex) { if (request != null) { _logger.Error(ex, $"[{client.ConnectionId}] Error processing request {request.Method} [{request.Id}]"); } } } }); }
public (Share Share, string BlobHex, string BlobHash) ProcessShare(string nonce, uint workerExtraNonce, string workerHash, StratumClient worker) { Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(nonce), $"{nameof(nonce)} must not be empty"); Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(workerHash), $"{nameof(workerHash)} must not be empty"); Contract.Requires <ArgumentException>(workerExtraNonce != 0, $"{nameof(workerExtraNonce)} must not be empty"); var context = worker.GetContextAs <MoneroWorkerContext>(); // validate nonce if (!MoneroConstants.RegexValidNonce.IsMatch(nonce)) { throw new StratumException(StratumError.MinusOne, "malformed nonce"); } // clone template using (var blob = new PooledArraySegment <byte>(blobTemplate.Length)) { Buffer.BlockCopy(blobTemplate, 0, blob.Array, 0, blobTemplate.Length); // inject extranonce var extraNonceBytes = BitConverter.GetBytes(workerExtraNonce.ToBigEndian()); Buffer.BlockCopy(extraNonceBytes, 0, blob.Array, (int)BlockTemplate.ReservedOffset, extraNonceBytes.Length); // inject nonce var nonceBytes = nonce.HexToByteArray(); Buffer.BlockCopy(nonceBytes, 0, blob.Array, MoneroConstants.BlobNonceOffset, nonceBytes.Length); // convert var blobConverted = LibCryptonote.ConvertBlob(blob.Array, blobTemplate.Length); if (blobConverted == null) { throw new StratumException(StratumError.MinusOne, "malformed blob"); } // hash it using (var hashSeg = hashSlow(blobConverted)) { var hash = hashSeg.ToHexString(); if (hash != workerHash) { throw new StratumException(StratumError.MinusOne, "bad hash"); } // check difficulty var headerValue = hashSeg.ToBigInteger(); var shareDiff = (double)new BigRational(MoneroConstants.Diff1b, headerValue); var stratumDifficulty = context.Difficulty; var ratio = shareDiff / stratumDifficulty; var isBlockCandidate = shareDiff >= BlockTemplate.Difficulty; // test if share meets at least workers current difficulty if (!isBlockCandidate && ratio < 0.99) { // check if share matched the previous difficulty from before a vardiff retarget if (context.VarDiff?.LastUpdate != null && context.PreviousDifficulty.HasValue) { ratio = shareDiff / context.PreviousDifficulty.Value; if (ratio < 0.99) { throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})"); } // use previous difficulty stratumDifficulty = context.PreviousDifficulty.Value; } else { throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})"); } } using (var blockHash = ComputeBlockHash(blobConverted)) { var result = new Share { BlockHeight = BlockTemplate.Height, IsBlockCandidate = isBlockCandidate, BlockHash = blockHash.ToHexString(), Difficulty = stratumDifficulty, }; var blobHex = blob.ToHexString(); var blobHash = blockHash.ToHexString(); return(result, blobHex, blobHash); } } } }
public static PooledArraySegment <T> ReverseArray <T>(this PooledArraySegment <T> arr) { Array.Reverse(arr.Array, arr.Offset, arr.Size); return(arr); }
public static string ToHexString(this PooledArraySegment <byte> value, bool withPrefix = false) { return(ToHexString(value.Array, value.Offset, value.Size, withPrefix)); }
private string GetString(PooledArraySegment <byte> seg) { return(Encoding.UTF8.GetString(seg.Array, seg.Offset, seg.Size)); }