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));
        }
Exemple #2
0
        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}]");
                        }
                    }
                }
            });
        }
Exemple #4
0
 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));
             }
         }
     }
 }
Exemple #5
0
        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();
            }
        }
Exemple #7
0
 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));
                 }
             }
         }
     }
 }
Exemple #10
0
        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);
        }
Exemple #11
0
        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);
        }
Exemple #12
0
        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}]");
                        }
                    }
                }
            });
        }
Exemple #14
0
        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);
                    }
                }
            }
        }
Exemple #15
0
 public static PooledArraySegment <T> ReverseArray <T>(this PooledArraySegment <T> arr)
 {
     Array.Reverse(arr.Array, arr.Offset, arr.Size);
     return(arr);
 }
Exemple #16
0
 public static string ToHexString(this PooledArraySegment <byte> value, bool withPrefix = false)
 {
     return(ToHexString(value.Array, value.Offset, value.Size, withPrefix));
 }
Exemple #17
0
 private string GetString(PooledArraySegment <byte> seg)
 {
     return(Encoding.UTF8.GetString(seg.Array, seg.Offset, seg.Size));
 }