Ejemplo n.º 1
0
        public void Should_Be_Converted_To_Real_Hash()
        {
            var headers = new HeaderHash(new Hash {
                { "foo", "bar" }
            });

            Assert.NotNull(headers as Hash);
        }
Ejemplo n.º 2
0
        public void Should_Return_Null_When_Delete_Is_Called_On_A_Non_Existent_Key()
        {
            var headers = new HeaderHash(new Hash {
                { "foo", "bar" }
            });

            Assert.Null(headers.Delete("Hello"));
        }
Ejemplo n.º 3
0
        public void Should_Return_The_Deleted_Value_When_Delete_Is_Called_On_An_Existing_Key()
        {
            var headers = new HeaderHash(new Hash {
                { "foo", "bar" }
            });

            Assert.AreEqual("bar", headers.Delete("Foo"));
        }
Ejemplo n.º 4
0
        public void Should_Check_Existence_of_Keys_Case_Insensitively()
        {
            var headers = new HeaderHash(new Hash {
                { "Content-MD5", "d5ff4e2a0 ..." }
            });

            Assert.IsTrue(headers.ContainsKey("content-md5"));
            Assert.IsFalse(headers.ContainsKey("ETag"));
        }
Ejemplo n.º 5
0
        public void Should_Convert_Array_Values_To_Strings_When_Converting_To_Hash()
        {
            var headers = new HeaderHash(new Hash {
                { "foo", new[] { "bar", "baz" } }
            });

            Assert.AreEqual(new Hash {
                { "foo", "bar\nbaz" }
            }, headers.ToHash());
        }
Ejemplo n.º 6
0
        public void Should_Avoid_Unnecessary_Object_Creation_If_Possible()
        {
            var a = new HeaderHash(new Hash {
                { "foo", "bar" }
            });
            var b = HeaderHash.Create(a);

            Assert.AreEqual(b.GetHashCode(), a.GetHashCode());
            Assert.AreEqual(a, b);
        }
Ejemplo n.º 7
0
        public void Should_Be_Able_To_Delete_The_Given_Key_Case_Insensitively()
        {
            var headers = new HeaderHash(new Hash {
                { "foo", "bar" }
            });

            headers.Remove("FOO");

            Assert.IsFalse(headers.ContainsKey("foo"));
            Assert.IsFalse(headers.ContainsKey("FOO"));
        }
Ejemplo n.º 8
0
        public dynamic[] Call(IDictionary <string, dynamic> environment)
        {
            var response = _app.Call(environment);
            var headers  = new HeaderHash(response[1]);

            if (!headers.ContainsKey("Content-Type") || headers["Content-Type"] == null)
            {
                headers["Content-Type"] = _contentType;
            }

            return(new[] { response[0], headers, response[2] });
        }
Ejemplo n.º 9
0
        public void Should_Retain_Header_Case()
        {
            var headers = new HeaderHash(new Hash {
                { "Content-MD5", "d5ff4e2a0 ..." }
            });

            headers["ETag"] = "Boo!";

            Assert.AreEqual(new Hash {
                { "Content-MD5", "d5ff4e2a0 ..." }, { "ETag", "Boo!" }
            }, headers);
        }
Ejemplo n.º 10
0
        public void Should_Convert_Array_Values_To_Strings_When_Responding_To_Each()
        {
            var headers = new HeaderHash(new Hash {
                { "foo", new[] { "bar", "baz" } }
            });

            headers.Each((key, value) =>
            {
                Assert.AreEqual("foo", key);
                Assert.AreEqual("bar\nbaz", value);
            });
        }
Ejemplo n.º 11
0
        public void Should_Replace_Hashes_Correctly()
        {
            var headers = new HeaderHash(new Hash {
                { "Foo-Bar", "baz" }
            });
            var hash = new Hash {
                { "foo", "bar" }
            };

            headers.Replace(hash);

            Assert.AreEqual("bar", headers["foo"]);
        }
Ejemplo n.º 12
0
        public dynamic[] Call(IDictionary <string, dynamic> environment)
        {
            var response = _app.Call(environment);
            var status   = response[0];
            var headers  = response[1];
            var body     = response[2];

            headers = new HeaderHash(headers);

            SetContentLength(status, headers, body);

            return(new[] { status, headers, body });
        }
Ejemplo n.º 13
0
        public void Should_Merge_Case_Insensitively()
        {
            var headers = new HeaderHash(new Hash {
                { "ETag", "HELLO" }, { "content-length", "123" }
            });

            var otherHash = new Hash {
                { "Etag", "WORLD" }, { "Content-Length", "321" }, { "Foo", "BAR" }
            };

            var merged = headers.Merge(otherHash);

            Assert.AreEqual(otherHash, merged);
        }
Ejemplo n.º 14
0
        public void Should_Overwrite_Case_Insensitively_And_Assume_The_New_Keys_Case()
        {
            var headers = new HeaderHash(new Hash {
                { "Foo-Bar", "baz" }
            });

            headers["foo-bar"] = "bizzle";

            Assert.AreEqual("bizzle", headers["FOO-BAR"]);
            Assert.AreEqual(1, headers.Count);
            Assert.AreEqual(new Hash {
                { "foo-bar", "bizzle" }
            }, headers.ToHash());
        }
Ejemplo n.º 15
0
        public Response(dynamic body = null, int status = 200, Hash header = null, Action <dynamic> block = null)
        {
            if (body == null)
            {
                body = new List <dynamic>();
            }

            if (header == null)
            {
                header = new Hash();
            }

            Headers = new HeaderHash(new Hash {
                { "Content-Type", "text/html" }
            }).Merge(header);
            Status = status;
            Body   = new List <dynamic>();
            Writer = str => Body.Add(str);

            if (Headers.ContainsKey("Transfer-Encoding") && Headers["Transfer-Encoding"] == "chunked")
            {
                Chunked = true;
            }

            if (body is string)
            {
                Write(body);
            }
            else if (body is IEnumerable)
            {
                new IterableAdapter(body).Each(part => Write(part.ToString()));
            }
            else
            {
                throw new ArgumentException("Must be iterable.", "body");
            }

            if (block != null)
            {
                block(this);
            }
        }
Ejemplo n.º 16
0
        public Share(IStratumMiner miner, UInt64 jobId, IJob job, string extraNonce2, string nTimeString,
                     string nonceString)
        {
            _logger.Debug("Entering share constructor: {0}", nonceString);
            Miner = miner;
            JobId = jobId;
            Job   = job;
            Error = ShareError.None;

            var submitTime = TimeHelpers.NowInUnixTimestamp(); // time we recieved the share from miner.

            if (Job == null)
            {
                _logger.Error("Job is null");
                Error = ShareError.JobNotFound;
                return;
            }

            if (extraNonce2 == null)
            {
                _logger.Error("extraNonce2 is NULL!");
            }

            // check size of miner supplied extraNonce2
            if (extraNonce2.Length / 2 != ExtraNonce.ExpectedExtraNonce2Size)
            {
                _logger.Error("Incorrect Extranonce2 size: {0} while expecting {1}", extraNonce2.Length, ExtraNonce.ExpectedExtraNonce2Size * 2);
                Error = ShareError.IncorrectExtraNonce2Size;
                return;
            }
            ExtraNonce2 = Convert.ToUInt32(extraNonce2, 16); // set extraNonce2 for the share.


            if (nTimeString == null)
            {
                _logger.Error("nTimeString is NULL!");
            }
            // check size of miner supplied nTime.
            if (nTimeString.Length != 8)
            {
                _logger.Error("nTimeString length !=8: {0}", nTimeString.Length);
                Error = ShareError.IncorrectNTimeSize;
                return;
            }
            NTime = Convert.ToUInt32(nTimeString, 16); // read ntime for the share

            // make sure NTime is within range.
            if (NTime < job.BlockTemplate.CurTime || NTime > submitTime + 7200)
            {
                _logger.Error("NTime Out Of Range!");
                Error = ShareError.NTimeOutOfRange;
                return;
            }


            if (nonceString == null)
            {
                _logger.Error("nonceString is NULL!");
            }
            // check size of miner supplied nonce.
            if (nonceString.Length != 8)
            {
                _logger.Error("nonceString.Length != 8: {0}", nonceString.Length);
                Error = ShareError.IncorrectNonceSize;
                return;
            }
            Nonce = Convert.ToUInt32(nonceString, 16); // nonce supplied by the miner for the share.

            if (miner == null)
            {
                _logger.Error("miner is NULL!");
            }

            // set job supplied parameters.
            Height      = job.BlockTemplate.Height; // associated job's block height.
            ExtraNonce1 = miner.ExtraNonce;         // extra nonce1 assigned to miner.

            // check for duplicate shares.
            if (!Job.RegisterShare(this)) // try to register share with the job and see if it's duplicated or not.
            {
                _logger.Error("Duplicate share: {0:l}", nonceString);
                Error = ShareError.DuplicateShare;
                return;
            }

            _logger.Debug("Serialize Share {0}", nonceString);
            // construct the coinbase.
            CoinbaseBuffer = Serializers.SerializeCoinbase(Job, ExtraNonce1, ExtraNonce2);
            CoinbaseHash   = Coin.Coinbase.Utils.HashCoinbase(CoinbaseBuffer);

            // create the merkle root.
            MerkleRoot = Job.MerkleTree.WithFirst(CoinbaseHash).ReverseBuffer();

            // create the block headers
            _logger.Debug("Getting Header buffer for Share {0}", nonceString);
            HeaderBuffer = Serializers.SerializeHeader(Job, MerkleRoot, NTime, Nonce);
            HeaderHash   = Job.HashAlgorithm.Hash(HeaderBuffer);
            _logger.Debug("Got share {0} of length: {1}\nPOW: {2,64:l}\nTGT: {3,64:l}", nonceString, HeaderHash.Length,
                          HeaderHash.ReverseBytes().ToHexString(), Job.Target.ToByteArray().ReverseBytes().ToHexString()
                          );
            HeaderValue = new BigInteger(HeaderHash);

            // calculate the share difficulty
            Difficulty = ((double)new BigRational(AlgorithmManager.Diff1, HeaderValue)) * Job.HashAlgorithm.Multiplier;

            // calculate the block difficulty
            BlockDiffAdjusted = Job.Difficulty * Job.HashAlgorithm.Multiplier;


            /*
             * Test false pozitive block candidates: negative bigints were the problem
             * byte[] testbytes = new byte[] {
             *  0xf7, 0xdf, 0xed, 0xbd,
             *  0x9a, 0x2b, 0xa5, 0x1f,
             *  0x7b, 0x0d, 0x68, 0x76,
             *  0xbe, 0x1f, 0x18, 0xd6,
             *  0x2d, 0x49, 0x94, 0x91,
             *  0x69, 0x11, 0x39, 0x41,
             *  0xdf, 0x1f, 0x25, 0xdb,
             *  0x9b, 0x4e, 0x97, 0xb7
             * };
             * string teststr = testbytes.ReverseBuffer().ToHexString();
             * HeaderValue = new BigInteger(testbytes);
             */

            // check if block candicate
            if (Job.Target >= HeaderValue)
            //if (true) //for Debug only
            {
                IsBlockCandidate = true;
                BlockHex         = Serializers.SerializeBlock(Job, HeaderBuffer, CoinbaseBuffer, miner.Pool.Config.Coin.Options.IsProofOfStakeHybrid);
                BlockHash        = HeaderBuffer.DoubleDigest().ReverseBuffer();

                try
                {
                    _logger.Debug("Job.Target is greater than or equal HeaderValue(POW-SCRYPT)!!!:\n{9}\n{10}\n\n" +
                                  "Big-Endian values for Block Header:\n" +
                                  "job.BlockTemplate.Version={0}\n" +
                                  "job.PreviousBlockHash={1}\n" +
                                  "MerkleRoot={2}\n" +
                                  "NTime={3}\n" +
                                  "job.EncodedDifficulty={4}\n" +
                                  "Nonce={5}\n" +
                                  "==============\n" +
                                  "result={6}\n\n" +
                                  "Big-Endian:\n" +
                                  "BlockHex={7}\n" +
                                  "BlockHash(2xSHA256)={8}\n",
                                  job.BlockTemplate.Version,
                                  BitConverter.ToString(job.PreviousBlockHash.HexToByteArray()).Replace("-", string.Empty),
                                  BitConverter.ToString(MerkleRoot).Replace("-", string.Empty),
                                  NTime,
                                  job.EncodedDifficulty,
                                  Nonce,
                                  BitConverter.ToString(HeaderBuffer).Replace("-", string.Empty),
                                  BlockHex,
                                  BitConverter.ToString(BlockHash).Replace("-", string.Empty),
                                  Job.Target.ToByteArray().ReverseBuffer().ToHexString(),
                                  HeaderValue.ToByteArray().ReverseBuffer().ToHexString()
                                  );
                }
                catch (Exception e)
                {
                    _logger.Error(e, "Something has happened while logging");
                }
            }
            else
            {
                IsBlockCandidate = false;
                BlockHash        = HeaderBuffer.DoubleDigest().ReverseBuffer();

                // Check if share difficulty reaches miner difficulty.
                var lowDifficulty = Difficulty / miner.Difficulty < 0.99; // share difficulty should be equal or more then miner's target difficulty.

                if (!lowDifficulty)                                       // if share difficulty is high enough to match miner's current difficulty.
                {
                    return;                                               // just accept the share.
                }
                if (Difficulty >= miner.PreviousDifficulty)               // if the difficulty matches miner's previous difficulty before the last vardiff triggered difficulty change
                {
                    return;                                               // still accept the share.
                }
                // if the share difficulty can't match miner's current difficulty or previous difficulty
                Error = ShareError.LowDifficultyShare; // then just reject the share with low difficult share error.
            }
        }
Ejemplo n.º 17
0
        public Share(IStratumMiner miner, UInt64 jobId, IJob job, string extraNonce2, string nTimeString, string nonceString)
        {
            Miner = miner;
            JobId = jobId;
            Job   = job;
            Error = ShareError.None;

            UInt64 submitTime = TimeHelpers.NowInUnixTime64(); // time we recieved the share from miner.

            if (Job == null)
            {
                Error = ShareError.JobNotFound;
                return;
            }

            // check size of miner supplied extraNonce2
            if (extraNonce2.Length / 2 != ExtraNonce.ExpectedExtraNonce2Size)
            {
                Error = ShareError.IncorrectExtraNonce2Size;
                return;
            }
            ExtraNonce2 = Convert.ToUInt32(extraNonce2, 16); // set extraNonce2 for the share.

            // check size of miner supplied nTime.
            if (nTimeString.Length != 16)
            {
                Error = ShareError.IncorrectNTimeSize;
                return;
            }
            NTime = Convert.ToUInt64(nTimeString, 16); // read ntime for the share

            // make sure NTime is within range.
            if (NTime < job.BlockTemplate.CurTime || NTime > submitTime + 7200)
            {
                Error = ShareError.NTimeOutOfRange;
                return;
            }

            // check size of miner supplied nonce.
            if (nonceString.Length != 16)
            {
                Error = ShareError.IncorrectNonceSize;
                return;
            }
            Nonce = Convert.ToUInt64(nonceString, 16); // nonce supplied by the miner for the share.

            // set job supplied parameters.
            Height      = job.BlockTemplate.Height; // associated job's block height.
            ExtraNonce1 = miner.ExtraNonce;         // extra nonce1 assigned to miner.

            // check for duplicate shares.
            if (!Job.RegisterShare(this)) // try to register share with the job and see if it's duplicated or not.
            {
                Error = ShareError.DuplicateShare;
                return;
            }

            // construct the coinbase.
            CoinbaseBuffer = Serializers.SerializeCoinbase(Job, ExtraNonce1, ExtraNonce2);
            CoinbaseHash   = Coin.Coinbase.Utils.HashCoinbase(CoinbaseBuffer);
            var coinbaseNoSigBuffer = Serializers.SerializeCoinbaseForTxId(Job, ExtraNonce1, ExtraNonce2);

            CoinbaseTxId = Coin.Coinbase.Utils.HashCoinbase(coinbaseNoSigBuffer);

            // create the merkle root.
            MerkleRoot = Job.MerkleTree.WithFirst(CoinbaseHash).ReverseBuffer();

            // create the block headers
            HeaderBuffer        = Serializers.SerializeHeader(Job, MerkleRoot, NTime, Nonce);
            HeaderBufferForHash = Serializers.SerializeHeaderForHash(Job, MerkleRoot, NTime, Nonce);
            HeaderHash          = Job.HashAlgorithm.Hash(HeaderBufferForHash, miner.Pool.Config.Coin.Options);
            HeaderHashValue     = new BigInteger(HeaderHash);

            // calculate the share difficulty
            Difficulty = ((double)new BigRational(Algorithms.Diff1, HeaderHashValue)) * Job.HashAlgorithm.Multiplier;
            BigInteger minerTarget = (new BigRational(Algorithms.Diff1, new BigInteger((uint)miner.Difficulty)) * Job.HashAlgorithm.Multiplier).GetWholePart();

            // calculate the block difficulty
            BlockDiffAdjusted = Job.Difficulty * Job.HashAlgorithm.Multiplier;

            // check if block candicate
            if (Job.Target >= HeaderHashValue)
            {
                IsBlockCandidate = true;
                BlockHex         = Serializers.SerializeBlock(Job, HeaderBuffer, CoinbaseBuffer);
                BlockHash        = HeaderHash.ReverseBuffer(); //HeaderBuffer.DoubleDigest().ReverseBuffer(); // TODO: make sure this is okay!
            }
            else
            {
                IsBlockCandidate = false;
                BlockHash        = HeaderHash.ReverseBuffer();//HeaderBuffer.DoubleDigest().ReverseBuffer();

                // Check if share difficulty reaches miner difficulty.
                var lowDifficulty = Difficulty / miner.Difficulty < 0.99; // share difficulty should be equal or more then miner's target difficulty.

                if (!lowDifficulty)                                       // if share difficulty is high enough to match miner's current difficulty.
                {
                    return;                                               // just accept the share.
                }
                if (Difficulty >= miner.PreviousDifficulty)               // if the difficulty matches miner's previous difficulty before the last vardiff triggered difficulty change
                {
                    return;                                               // still accept the share.
                }
                // if the share difficulty can't match miner's current difficulty or previous difficulty
                Error = ShareError.LowDifficultyShare; // then just reject the share with low difficult share error.
            }
        }