コード例 #1
0
        public void Crytonight_Variant_1()
        {
            var blobConverted = "0106a2aaafd505583cf50bcc743d04d831d2b119dc94ad88679e359076ee3f18d258ee138b3b42580100a4b1e2f4baf6ab7109071ab59bc52dba740d1de99fa0ae0c4afd6ea9f40c5d87ec01".HexToByteArray();
            var buf           = new byte[32];

            LibCryptonight.Cryptonight(blobConverted, buf, 1);
            var result = buf.ToHexString();

            Assert.Equal("c41ec6434df8b2307ff3105ae15206f3fbdf5a99b35879c0a27b8b85a8e2704f", result);

            Array.Clear(buf, 0, buf.Length);

            LibCryptonight.Cryptonight(blobConverted, buf, 1);
            result = buf.ToHexString();
            Assert.Equal("c41ec6434df8b2307ff3105ae15206f3fbdf5a99b35879c0a27b8b85a8e2704f", result);
        }
コード例 #2
0
        public void Crytonight_Variant_4()
        {
            var blobConverted = "0106a2aaafd505583cf50bcc743d04d831d2b119dc94ad88679e359076ee3f18d258ee138b3b42580100a4b1e2f4baf6ab7109071ab59bc52dba740d1de99fa0ae0c4afd6ea9f40c5d87ec01".HexToByteArray();
            var buf           = new byte[32];

            LibCryptonight.Cryptonight(blobConverted, buf, CryptonightVariant.VARIANT_4, 0);
            var result = buf.ToHexString();

            Assert.Equal("3e69817268c70010f793d53ba1a9f12af21753c723c7d7990a8eefccc6d163ba", result);

            Array.Clear(buf, 0, buf.Length);

            LibCryptonight.Cryptonight(blobConverted, buf, CryptonightVariant.VARIANT_4, 0);
            result = buf.ToHexString();
            Assert.Equal("3e69817268c70010f793d53ba1a9f12af21753c723c7d7990a8eefccc6d163ba", result);
        }
コード例 #3
0
        public void Crytonight()
        {
            var blobConverted = "0106a2aaafd505583cf50bcc743d04d831d2b119dc94ad88679e359076ee3f18d258ee138b3b42580100a4b1e2f4baf6ab7109071ab59bc52dba740d1de99fa0ae0c4afd6ea9f40c5d87ec01".HexToByteArray();
            var buf           = new byte[32];

            LibCryptonight.Cryptonight(blobConverted, buf, 0);
            var result = buf.ToHexString();

            Assert.Equal("a845ffbdf83ae9a8ffa504a1011efbd5ed2294bb9da591d3b583740568402c00", result);

            Array.Clear(buf, 0, buf.Length);

            LibCryptonight.Cryptonight(blobConverted, buf, 0);
            result = buf.ToHexString();
            Assert.Equal("a845ffbdf83ae9a8ffa504a1011efbd5ed2294bb9da591d3b583740568402c00", result);
        }
コード例 #4
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.ContextAs <MoneroWorkerContext>();

            // validate nonce
            if (!MoneroConstants.RegexValidNonce.IsMatch(nonce))
            {
                throw new StratumException(StratumError.MinusOne, "malformed nonce");
            }

            // clone template
            Span <byte> blob = stackalloc byte[blobTemplate.Length];

            blobTemplate.CopyTo(blob);

            // inject extranonce
            var extraNonceBytes = BitConverter.GetBytes(workerExtraNonce.ToBigEndian());

            extraNonceBytes.CopyTo(blob.Slice(BlockTemplate.ReservedOffset, extraNonceBytes.Length));

            // inject nonce
            var nonceBytes = nonce.HexToByteArray();

            nonceBytes.CopyTo(blob.Slice(MoneroConstants.BlobNonceOffset, nonceBytes.Length));

            // convert
            var blobConverted = LibCryptonote.ConvertBlob(blob, blobTemplate.Length);

            if (blobConverted == null)
            {
                throw new StratumException(StratumError.MinusOne, "malformed blob");
            }

            // hash it
            Span <byte> headerHash = stackalloc byte[32];

            switch (coin)
            {
            case CoinType.AEON:
                LibCryptonight.CryptonightLight(blobConverted, headerHash, 0);
                break;

            case CoinType.XMR:
                var variant = blobConverted[0] >= 7 ? blobConverted[0] - 6 : 0;
                LibCryptonight.Cryptonight(blobConverted, headerHash, variant);
                break;

            default:
                LibCryptonight.Cryptonight(blobConverted, headerHash, 0);
                break;
            }

            var headerHashString = headerHash.ToHexString();

            if (headerHashString != workerHash)
            {
                throw new StratumException(StratumError.MinusOne, "bad hash");
            }

            // check difficulty
            var headerValue       = headerHash.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})");
                }
            }

            // Compute block hash
            Span <byte> blockHash = stackalloc byte[32];

            ComputeBlockHash(blobConverted, blockHash);

            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);
        }