コード例 #1
0
        /// <summary>
        /// Processes the share.
        /// </summary>
        /// <param name="miner">The miner.</param>
        /// <param name="jobId">The job identifier.</param>
        /// <param name="extraNonce2">The extra nonce2.</param>
        /// <param name="nTimeString">The n time string.</param>
        /// <param name="nonceString">The nonce string.</param>
        /// <returns></returns>
        public IShare ProcessShare(IStratumMiner miner, string jobId, string extraNonce2, string nTimeString, string nonceString, string cycle)
        {
            // check if the job exists
            var id  = Convert.ToUInt64(jobId, 16);
            var job = _jobTracker.Get(id);

            string[] cycleEdgesStrs = cycle.Split(',');
            UInt32[] cycleEdges     = new UInt32[cycleEdgesStrs.Length];

            for (var i = 0; i < cycleEdgesStrs.Length; i++)
            {
                cycleEdges[i] = Convert.ToUInt32(cycleEdgesStrs[i], 16);
            }

            // create the share
            var share = new Share(miner, id, job, extraNonce2, nTimeString, nonceString, cycleEdges);

            if (share.IsValid)
            {
                HandleValidShare(share);
            }
            else
            {
                HandleInvalidShare(share);
            }

            OnShareSubmitted(new ShareEventArgs(miner));  // notify the listeners about the share.

            return(share);
        }
コード例 #2
0
ファイル: ShareManager.cs プロジェクト: tross2015/CoiniumServ
        /// <summary>
        /// Processes the share.
        /// </summary>
        /// <param name="miner">The miner.</param>
        /// <param name="jobId">The job identifier.</param>
        /// <param name="extraNonce2">The extra nonce2.</param>
        /// <param name="nTimeString">The n time string.</param>
        /// <param name="nonceString">The nonce string.</param>
        /// <returns></returns>
        public IShare ProcessShare(IStratumMiner miner, string jobId, string extraNonce2, string nTimeString, string nonceString)
        {
            // check if the job exists
            var id  = Convert.ToUInt64(jobId, 16);
            var job = _jobTracker.Get(id);

            _logger.Debug("TakeShare before share constructor: nonce={0:l}, extranonce2={1:l}", nonceString, extraNonce2);
            // create the share
            var share = new Share(miner, id, job, extraNonce2, nTimeString, nonceString);



            if (share.IsValid)
            {
                HandleValidShare(share);
            }
            else
            {
                HandleInvalidShare(share);
            }

            OnShareSubmitted(new ShareEventArgs(miner));  // notify the listeners about the share.

            return(share);
        }
コード例 #3
0
        public void UpdateDifficulty(IStratumMiner miner)
        {
            try
            {
                if (!IsEnabled)
                    return;

                using (var connection = new MySqlConnection(_mySqlProvider.ConnectionString))
                {
                    connection.Execute(
                        "UPDATE pool_worker SET difficulty = @difficulty WHERE username = @username", new
                        {
                            difficulty = miner.Difficulty,
                            username = miner.Username
                        });
                }
            }
            catch (Exception e)
            {
                _logger.Error("An exception occured while updating difficulty for miner; {0:l}", e.Message);
            }
        }
コード例 #4
0
ファイル: ShareManager.cs プロジェクト: zz0412/ZCoiniumServ
        /// <summary>
        /// Processes the share.
        /// </summary>
        /// <param name="miner">The miner.</param>
        /// <param name="jobId">The job identifier.</param>
        /// <param name="extraNonce2">The extra nonce2.</param>
        /// <param name="nTimeString">The n time string.</param>
        /// <param name="nonceString">The nonce string.</param>
        /// <returns></returns>
        public IShare ProcessShare(IStratumMiner miner, string jobId, string nTime, string extraNonce2, string equihashSolution)
        {
            // check if the job exists
            var id  = Convert.ToUInt64(jobId, 16);
            var job = _jobTracker.Get(id);

            // create the share
            var share = new Share(miner, id, job, extraNonce2, nTime, equihashSolution);

            if (share.IsValid)
            {
                HandleValidShare(share);
            }
            else
            {
                HandleInvalidShare(share);
            }

            OnShareSubmitted(new ShareEventArgs(miner));  // notify the listeners about the share.

            return(share);
        }
コード例 #5
0
        /// <summary>
        /// Processes the share.
        /// </summary>
        /// <param name="miner">The miner.</param>
        /// <param name="jobId">The job identifier.</param>
        /// <param name="extraNonce2">The extra nonce2.</param>
        /// <param name="nTimeString">The n time string.</param>
        /// <param name="nonceString">The nonce string.</param>
        /// <returns></returns>
        public IShare ProcessShare(IStratumMiner miner, string jobId, string extraNonce2, string nTimeString, string nonceString, string jobPayoutUser)
        {
            // check if the job exists
            var   id  = Convert.ToUInt64(jobId, 16);
            var   job = _jobTracker.Get(id);
            Share share;

            if (!job.MetronomeHash.Equals(MetronomeTracker.CurrentMetronomeHash) ||
                BigInteger.Parse(MetronomeTracker.CurrentMetronomeHash, System.Globalization.NumberStyles.HexNumber).IsZero)
            {
                share       = new Share(miner, id, null, extraNonce2, nTimeString, nonceString);
                share.Error = ShareError.InsideSleepWindow;
            }
            else
            {
                // create the share
                share = new Share(miner, id, job, extraNonce2, nTimeString, nonceString);
            }

            share.PayoutUser = jobPayoutUser;

            if (share.IsValid)
            {
                HandleValidShare(share);
            }
            else
            {
                HandleInvalidShare(share);
            }

            if (share.Error != ShareError.InsideSleepWindow)
            {
                OnShareSubmitted(new ShareEventArgs(miner));  // notify the listeners about the share.
            }

            return(share);
        }
コード例 #6
0
        public void UpdateDifficulty(IStratumMiner miner)
        {
            try
            {
                if (!IsEnabled)
                {
                    return;
                }

                using (var connection = new MySqlConnection(_mySqlProvider.ConnectionString))
                {
                    connection.Execute(
                        "UPDATE pool_worker SET difficulty = @difficulty WHERE username = @username", new
                    {
                        difficulty = miner.Difficulty,
                        username   = miner.Username
                    });
                }
            }
            catch (Exception e)
            {
                _logger.Error("An exception occured while updating difficulty for miner; {0:l}", e.Message);
            }
        }
コード例 #7
0
        /// <summary>
        /// Processes the share.
        /// </summary>
        /// <param name="miner">The miner.</param>
        /// <param name="jobId">The job identifier.</param>
        /// <param name="extraNonce2">The extra nonce2.</param>
        /// <param name="nTimeString">The n time string.</param>
        /// <param name="nonceString">The nonce string.</param>
        /// <returns></returns>
        public IShare ProcessShare(IStratumMiner miner, string jobId, string extraNonce2, string nTimeString, string nonceString)
        {
            // check if the job exists
            var id = Convert.ToUInt64(jobId, 16);
            var job = _jobTracker.Get(id);

            // create the share
            var share = new Share(miner, id, job, extraNonce2, nTimeString, nonceString);

            if (share.IsValid)
                HandleValidShare(share);
            else
                HandleInvalidShare(share);

            OnShareSubmitted(new ShareEventArgs(miner));  // notify the listeners about the share.

            return share;
        }
コード例 #8
0
        public ShareTests()
        {
            /*
             *  -- create-generation start --
             *  rpcData: {"version":2,"previousblockhash":"1c4eb88e47564cb796b5c6648c74bec51d7215ac12fc4168b14827aac74a8062","transactions":[{"data":"010000000332a82e92f522deee69b09e27858ba9b87585f2a4913ef71018df40909032fdc3000000006a473044022019ca05cb880a04f0d842268b7e75ac6d2695fc544df033e3daeb29239251a8970220031f6336767f2ea617347484e1290ec0bdcc71056ea2d3084e75384905250ec50121030dd394118fb66ca288bff71d8ea762678783b005770f7f9ba4128233191e0847ffffffff086747cbd339b21b950774186091653a7b8f5751b00a906ff6f5561b3a6fcee6010000006b4830450221009ae1ba9a216d313cc592fc2c1ef08f1e0e555a32b6c1b305f685ac882d38356b0220243106bbb5bb76dde142e574cba8f30c1e2f7059e8e9161770396fbd2b50420f0121030dd394118fb66ca288bff71d8ea762678783b005770f7f9ba4128233191e0847ffffffffe2f15804b1e41c36c925c6f64f219b2bdb3c9fbff4c97a4f0e8c7f31d7e6f2af000000006b48304502200be8894fdd7f5c19be248a979c08bbf2395f606e038c3e02c0266474c03699ab022100ff5de87086e487410f5d7b68012655ca6d814f0caeb9ca42d9c425a90f68b3030121030dd394118fb66ca288bff71d8ea762678783b005770f7f9ba4128233191e0847ffffffff02a0f01900000000001976a9141c50209a1dfdf53313d237b75e9aeb553ca1dfda88ac00e1f505000000001976a914cbb9a3e7a7c1651b1006f876f08b40be85b274f588ac00000000","hash":"dc3a80ec6c45aa489453b2c4abf6761eb6656d949e26d01793458c166640e5f3","depends":[],"fee":0,"sigops":2}],"coinbaseaux":{"flags":"062f503253482f"},"coinbasevalue":5000000000,"target":"00000048d4f70000000000000000000000000000000000000000000000000000","mintime":1403691059,"mutable":["time","transactions","prevblock"],"noncerange":"00000000ffffffff","sigoplimit":20000,"sizelimit":1000000,"curtime":1403691825,"bits":"1d48d4f7","height":315152}
             *
             *  -- scriptSigPart data --
             *  -> height: 315152 serialized: 0310cf04
             *  -> coinbase: 062f503253482f hex: 062f503253482f
             *  -> date: 1403691824760 final:1403691824 serialized: 0430a3aa53
             *  -- p1 data --
             *  txVersion: 1 packed: 01000000
             *  txInputsCount: 1 varIntBuffer: 01
             *  txInPrevOutHash: 0 uint256BufferFromHash: 0000000000000000000000000000000000000000000000000000000000000000
             *  txInPrevOutIndex: 4294967295 packUInt32LE: ffffffff
             *  scriptSigPart1.length: 17 extraNoncePlaceholder.length:8 scriptSigPart2.length:14 all: 39 varIntBuffer: 27
             *  scriptSigPart1: 0310cf04062f503253482f0430a3aa5308
             *  p1: 01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff270310cf04062f503253482f0430a3aa5308
             *  -- generateOutputTransactions --
             *  block-reward: 5000000000
             *  recipient-reward: 50000000 packInt64LE: 80f0fa0200000000
             *  lenght: 25 varIntBuffer: 19
             *  script: 76a9147d576fbfca48b899dc750167dd2a2a6572fff49588ac
             *  pool-reward: 4950000000 packInt64LE: 80010b2701000000
             *  lenght: 25 varIntBuffer: 19
             *  script: 76a914329035234168b8da5af106ceb20560401236849888ac
             *  txOutputBuffers.lenght : 2 varIntBuffer: 02
             *  -- p2 --
             *  scriptSigPart2: 0d2f6e6f64655374726174756d2f
             *  txInSequence: 0 packUInt32LE: 00000000
             *  outputTransactions: 0280010b27010000001976a914329035234168b8da5af106ceb20560401236849888ac80f0fa02000000001976a9147d576fbfca48b899dc750167dd2a2a6572fff49588ac
             *  txLockTime: 0 packUInt32LE: 00000000
             *  txComment:
             *  p2: 0d2f6e6f64655374726174756d2f000000000280010b27010000001976a914329035234168b8da5af106ceb20560401236849888ac80f0fa02000000001976a9147d576fbfca48b899dc750167dd2a2a6572fff49588ac00000000
             *
             *  getJobParams: ["2","c74a8062b14827aa12fc41681d7215ac8c74bec596b5c66447564cb71c4eb88e","01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff270310cf04062f503253482f0430a3aa5308","0d2f6e6f64655374726174756d2f000000000280010b27010000001976a914329035234168b8da5af106ceb20560401236849888ac80f0fa02000000001976a9147d576fbfca48b899dc750167dd2a2a6572fff49588ac00000000",["f3e54066168c459317d0269e946d65b61e76f6abc4b2539448aa456cec803adc"],"00000002","1d48d4f7","53aaa331",true]
             */

            // daemon client
            _daemonClient = Substitute.For <IDaemonClient>();
            _daemonClient.ValidateAddress(Arg.Any <string>()).Returns(new ValidateAddress {
                IsValid = true
            });

            // block template
            const string json = "{\"result\":{\"version\":2,\"previousblockhash\":\"1c4eb88e47564cb796b5c6648c74bec51d7215ac12fc4168b14827aac74a8062\",\"transactions\":[{\"data\":\"010000000332a82e92f522deee69b09e27858ba9b87585f2a4913ef71018df40909032fdc3000000006a473044022019ca05cb880a04f0d842268b7e75ac6d2695fc544df033e3daeb29239251a8970220031f6336767f2ea617347484e1290ec0bdcc71056ea2d3084e75384905250ec50121030dd394118fb66ca288bff71d8ea762678783b005770f7f9ba4128233191e0847ffffffff086747cbd339b21b950774186091653a7b8f5751b00a906ff6f5561b3a6fcee6010000006b4830450221009ae1ba9a216d313cc592fc2c1ef08f1e0e555a32b6c1b305f685ac882d38356b0220243106bbb5bb76dde142e574cba8f30c1e2f7059e8e9161770396fbd2b50420f0121030dd394118fb66ca288bff71d8ea762678783b005770f7f9ba4128233191e0847ffffffffe2f15804b1e41c36c925c6f64f219b2bdb3c9fbff4c97a4f0e8c7f31d7e6f2af000000006b48304502200be8894fdd7f5c19be248a979c08bbf2395f606e038c3e02c0266474c03699ab022100ff5de87086e487410f5d7b68012655ca6d814f0caeb9ca42d9c425a90f68b3030121030dd394118fb66ca288bff71d8ea762678783b005770f7f9ba4128233191e0847ffffffff02a0f01900000000001976a9141c50209a1dfdf53313d237b75e9aeb553ca1dfda88ac00e1f505000000001976a914cbb9a3e7a7c1651b1006f876f08b40be85b274f588ac00000000\",\"hash\":\"dc3a80ec6c45aa489453b2c4abf6761eb6656d949e26d01793458c166640e5f3\",\"depends\":[],\"fee\":0,\"sigops\":2}],\"coinbaseaux\":{\"flags\":\"062f503253482f\"},\"coinbasevalue\":5000000000,\"target\":\"00000048d4f70000000000000000000000000000000000000000000000000000\",\"mintime\":1403691059,\"mutable\":[\"time\",\"transactions\",\"prevblock\"],\"noncerange\":\"00000000ffffffff\",\"sigoplimit\":20000,\"sizelimit\":1000000,\"curtime\":1403691825,\"bits\":\"1d48d4f7\",\"height\":315152},\"error\":null,\"id\":1}";
            var          blockTemplateObject = JsonConvert.DeserializeObject <DaemonResponse <BlockTemplate> >(json);

            _blockTemplate = blockTemplateObject.Result;

            // extra nonce
            _extraNonce = Substitute.For <ExtraNonce>((UInt32)0);

            // signature script
            _signatureScript = Substitute.For <SignatureScript>(
                _blockTemplate.Height,
                _blockTemplate.CoinBaseAux.Flags,
                1403691824760,
                (byte)_extraNonce.ExtraNoncePlaceholder.Length,
                "/nodeStratum/");

            // outputs
            _outputs = Substitute.For <Outputs>(_daemonClient);
            double blockReward = 5000000000; // the amount rewarded by the block.

            // sample reward recipient
            var rewardsConfig = Substitute.For <IRewardsConfig>();
            var amount        = blockReward * 0.01;

            blockReward -= amount;
            var rewards = new Dictionary <string, float> {
                { "mrwhWEDnU6dUtHZJ2oBswTpEdbBHgYiMji", (float)amount }
            };

            rewardsConfig.GetEnumerator().Returns(rewards.GetEnumerator());
            foreach (var pair in rewards)
            {
                _outputs.AddRecipient(pair.Key, pair.Value);
            }

            // sample pool wallet
            var walletConfig = Substitute.For <IWalletConfig>();

            walletConfig.Adress.Returns("mk8JqN1kNWju8o3DXEijiJyn7iqkwktAWq");
            _outputs.AddPoolWallet(walletConfig.Adress, blockReward);

            var metaConfig = Substitute.For <IMetaConfig>();

            // generation transaction
            _generationTransaction = Substitute.For <GenerationTransaction>(_extraNonce, _daemonClient, _blockTemplate, walletConfig, rewardsConfig, metaConfig, false);
            //_generationTransaction.Inputs.First().SignatureScript = _signatureScript;
            //_generationTransaction.Outputs = _outputs;
            _generationTransaction.Create();

            // hash algorithm
            _hashAlgorithm = Substitute.For <Scrypt>();

            // the job.
            _job = new Job(2, _hashAlgorithm, _blockTemplate, _generationTransaction)
            {
                CleanJobs = true
            };

            // the job tracker.
            _jobTracker = Substitute.For <IJobTracker>();
            _jobTracker.Get(2).Returns(_job);

            // the job manager.
            _jobManager = Substitute.For <IJobManager>();
            _jobManager.ExtraNonce.Next().Returns((UInt32)0x58000000);

            // coin config
            _miner = Substitute.For <IStratumMiner>();
            _miner.ExtraNonce.Returns((UInt32)0x58000000);
        }
コード例 #9
0
 public void UpdateDifficulty(IStratumMiner miner)
 {
     return;
 }
コード例 #10
0
ファイル: Share.cs プロジェクト: tross2015/CoiniumServ
        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.
            }
        }
コード例 #11
0
 public void UpdateDifficulty(IStratumMiner miner)
 {
     return;
 }
コード例 #12
0
 public void UpdateDifficulty(IStratumMiner miner)
 {
     // as we don't have an actual persistance layer, we can't write difficulty update information.
     return;
 }
コード例 #13
0
ファイル: StratumContext.cs プロジェクト: turbobit/merit-pool
 public StratumContext(IStratumMiner miner)
 {
     Miner = miner;
 }
コード例 #14
0
ファイル: Share.cs プロジェクト: icede/CoiniumServ-develop
        public Share(IStratumMiner miner, UInt64 jobId, IJob job, string extraNonce2, string nTimeString, string nonceString)
        {
            Miner = miner;
            JobId = jobId;
            Job = job;
            Error = ShareError.None;

            var submitTime = TimeHelpers.NowInUnixTimestamp(); // 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 != 8)
            {
                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)
            {
                Error = ShareError.NTimeOutOfRange;
                return;
            }

            // check size of miner supplied nonce.
            if (nonceString.Length != 8)
            {
                Error = ShareError.IncorrectNonceSize;
                return;
            }
            Nonce = Convert.ToUInt32(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);

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

            // create the block headers
            HeaderBuffer = Serializers.SerializeHeader(Job, MerkleRoot, NTime, Nonce);
            HeaderHash = Job.HashAlgorithm.Hash(HeaderBuffer);
            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;

            // check if block candicate
            if (Job.Target >= HeaderValue)
            {
                IsBlockCandidate = true;
                BlockHex = Serializers.SerializeBlock(Job, HeaderBuffer, CoinbaseBuffer, miner.Pool.Config.Coin.Options.IsProofOfStakeHybrid);
                BlockHash = HeaderBuffer.DoubleDigest().ReverseBuffer();
            }
            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.
            }
        }
コード例 #15
0
 public StratumContext(IStratumMiner miner)
 {
     Miner = miner;
 }
コード例 #16
0
 public ShareEventArgs(IStratumMiner miner)
 {
     Miner = miner;
 }
コード例 #17
0
ファイル: Share.cs プロジェクト: nuggetbram/coinium-whrl
        public Share(IStratumMiner miner, UInt64 jobId, IJob job, string extraNonce2, string nTimeString, string nonceString)
        {
            Miner = miner;
            JobId = jobId;
            Job = job;
            Error = ShareError.None;

            // TODO: add extranonce2 size check!.
            // TODO: add duplicate share check.
            // TODO: add nTime out of range check

            if (Job == null)
            {
                Error = ShareError.JobNotFound;
                Log.ForContext<Share>().Warning("Job doesn't exist: {0}", JobId);
                return;
            }

            // check miner supplied nTime.
            if (nTimeString.Length != 8)
            {
                Error = ShareError.IncorrectNTimeSize;
                Log.ForContext<Share>().Warning("Incorrect size of nTime");
                return;
            }

            NTime = Convert.ToUInt32(nTimeString, 16); // ntime for the share

            // check miner supplied nonce.
            if (nonceString.Length != 8)
            {
                Error = ShareError.IncorrectNonceSize;
                Log.ForContext<Share>().Warning("incorrect size of nonce");
                return;
            }

            Nonce = Convert.ToUInt32(nonceString, 16); // nonce supplied by the miner for the share.

            // check miner supplied extraNonce2
            ExtraNonce2 = Convert.ToUInt32(extraNonce2, 16);

            // check job supplied parameters.
            Height = job.BlockTemplate.Height;
            ExtraNonce1 = miner.ExtraNonce; // extra nonce1 assigned to miner.

            // 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
            HeaderBuffer = Serializers.SerializeHeader(Job, MerkleRoot, NTime, Nonce);
            HeaderHash = Job.HashAlgorithm.Hash(HeaderBuffer, miner.Pool.Config.Coin.Options);
            HeaderValue = new BigInteger(HeaderHash);

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

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

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

                // Check if share difficulty reaches miner difficulty.
                if (Difficulty / 16 < 0.99)
                {
                    // todo: add low difficulty share check.
                }
            }
        }
コード例 #18
0
 public ShareEventArgs(IStratumMiner miner)
 {
     Miner = miner;
 }
コード例 #19
0
        public ShareTests()
        {
            /*
                -- create-generation start --
                rpcData: {"version":2,"previousblockhash":"1c4eb88e47564cb796b5c6648c74bec51d7215ac12fc4168b14827aac74a8062","transactions":[{"data":"010000000332a82e92f522deee69b09e27858ba9b87585f2a4913ef71018df40909032fdc3000000006a473044022019ca05cb880a04f0d842268b7e75ac6d2695fc544df033e3daeb29239251a8970220031f6336767f2ea617347484e1290ec0bdcc71056ea2d3084e75384905250ec50121030dd394118fb66ca288bff71d8ea762678783b005770f7f9ba4128233191e0847ffffffff086747cbd339b21b950774186091653a7b8f5751b00a906ff6f5561b3a6fcee6010000006b4830450221009ae1ba9a216d313cc592fc2c1ef08f1e0e555a32b6c1b305f685ac882d38356b0220243106bbb5bb76dde142e574cba8f30c1e2f7059e8e9161770396fbd2b50420f0121030dd394118fb66ca288bff71d8ea762678783b005770f7f9ba4128233191e0847ffffffffe2f15804b1e41c36c925c6f64f219b2bdb3c9fbff4c97a4f0e8c7f31d7e6f2af000000006b48304502200be8894fdd7f5c19be248a979c08bbf2395f606e038c3e02c0266474c03699ab022100ff5de87086e487410f5d7b68012655ca6d814f0caeb9ca42d9c425a90f68b3030121030dd394118fb66ca288bff71d8ea762678783b005770f7f9ba4128233191e0847ffffffff02a0f01900000000001976a9141c50209a1dfdf53313d237b75e9aeb553ca1dfda88ac00e1f505000000001976a914cbb9a3e7a7c1651b1006f876f08b40be85b274f588ac00000000","hash":"dc3a80ec6c45aa489453b2c4abf6761eb6656d949e26d01793458c166640e5f3","depends":[],"fee":0,"sigops":2}],"coinbaseaux":{"flags":"062f503253482f"},"coinbasevalue":5000000000,"target":"00000048d4f70000000000000000000000000000000000000000000000000000","mintime":1403691059,"mutable":["time","transactions","prevblock"],"noncerange":"00000000ffffffff","sigoplimit":20000,"sizelimit":1000000,"curtime":1403691825,"bits":"1d48d4f7","height":315152}

                -- scriptSigPart data --
                -> height: 315152 serialized: 0310cf04
                -> coinbase: 062f503253482f hex: 062f503253482f
                -> date: 1403691824760 final:1403691824 serialized: 0430a3aa53
                -- p1 data --
                txVersion: 1 packed: 01000000
                txInputsCount: 1 varIntBuffer: 01
                txInPrevOutHash: 0 uint256BufferFromHash: 0000000000000000000000000000000000000000000000000000000000000000
                txInPrevOutIndex: 4294967295 packUInt32LE: ffffffff
                scriptSigPart1.length: 17 extraNoncePlaceholder.length:8 scriptSigPart2.length:14 all: 39 varIntBuffer: 27
                scriptSigPart1: 0310cf04062f503253482f0430a3aa5308
                p1: 01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff270310cf04062f503253482f0430a3aa5308
                -- generateOutputTransactions --
                block-reward: 5000000000
                recipient-reward: 50000000 packInt64LE: 80f0fa0200000000
                lenght: 25 varIntBuffer: 19
                script: 76a9147d576fbfca48b899dc750167dd2a2a6572fff49588ac
                pool-reward: 4950000000 packInt64LE: 80010b2701000000
                lenght: 25 varIntBuffer: 19
                script: 76a914329035234168b8da5af106ceb20560401236849888ac
                txOutputBuffers.lenght : 2 varIntBuffer: 02
                -- p2 --
                scriptSigPart2: 0d2f6e6f64655374726174756d2f
                txInSequence: 0 packUInt32LE: 00000000
                outputTransactions: 0280010b27010000001976a914329035234168b8da5af106ceb20560401236849888ac80f0fa02000000001976a9147d576fbfca48b899dc750167dd2a2a6572fff49588ac
                txLockTime: 0 packUInt32LE: 00000000
                txComment:
                p2: 0d2f6e6f64655374726174756d2f000000000280010b27010000001976a914329035234168b8da5af106ceb20560401236849888ac80f0fa02000000001976a9147d576fbfca48b899dc750167dd2a2a6572fff49588ac00000000

                getJobParams: ["2","c74a8062b14827aa12fc41681d7215ac8c74bec596b5c66447564cb71c4eb88e","01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff270310cf04062f503253482f0430a3aa5308","0d2f6e6f64655374726174756d2f000000000280010b27010000001976a914329035234168b8da5af106ceb20560401236849888ac80f0fa02000000001976a9147d576fbfca48b899dc750167dd2a2a6572fff49588ac00000000",["f3e54066168c459317d0269e946d65b61e76f6abc4b2539448aa456cec803adc"],"00000002","1d48d4f7","53aaa331",true]
             */

            // daemon client
            _daemonClient = Substitute.For<IDaemonClient>();
            _daemonClient.ValidateAddress(Arg.Any<string>()).Returns(new ValidateAddress { IsValid = true });

            // block template
            const string json = "{\"result\":{\"version\":1,\"previousblockhash\":\"1c4eb88e47564cb796b5c6648c74bec51d7215ac12fc4168b14827aac74a8062\",\"transactions\":[{\"data\":\"010000000332a82e92f522deee69b09e27858ba9b87585f2a4913ef71018df40909032fdc3000000006a473044022019ca05cb880a04f0d842268b7e75ac6d2695fc544df033e3daeb29239251a8970220031f6336767f2ea617347484e1290ec0bdcc71056ea2d3084e75384905250ec50121030dd394118fb66ca288bff71d8ea762678783b005770f7f9ba4128233191e0847ffffffff086747cbd339b21b950774186091653a7b8f5751b00a906ff6f5561b3a6fcee6010000006b4830450221009ae1ba9a216d313cc592fc2c1ef08f1e0e555a32b6c1b305f685ac882d38356b0220243106bbb5bb76dde142e574cba8f30c1e2f7059e8e9161770396fbd2b50420f0121030dd394118fb66ca288bff71d8ea762678783b005770f7f9ba4128233191e0847ffffffffe2f15804b1e41c36c925c6f64f219b2bdb3c9fbff4c97a4f0e8c7f31d7e6f2af000000006b48304502200be8894fdd7f5c19be248a979c08bbf2395f606e038c3e02c0266474c03699ab022100ff5de87086e487410f5d7b68012655ca6d814f0caeb9ca42d9c425a90f68b3030121030dd394118fb66ca288bff71d8ea762678783b005770f7f9ba4128233191e0847ffffffff02a0f01900000000001976a9141c50209a1dfdf53313d237b75e9aeb553ca1dfda88ac00e1f505000000001976a914cbb9a3e7a7c1651b1006f876f08b40be85b274f588ac00000000\",\"hash\":\"dc3a80ec6c45aa489453b2c4abf6761eb6656d949e26d01793458c166640e5f3\",\"depends\":[],\"fee\":0,\"sigops\":2}],\"coinbaseaux\":{\"flags\":\"062f503253482f\"},\"coinbasevalue\":5000000000,\"target\":\"00000048d4f70000000000000000000000000000000000000000000000000000\",\"mintime\":1403691059,\"mutable\":[\"time\",\"transactions\",\"prevblock\"],\"noncerange\":\"00000000ffffffff\",\"sigoplimit\":20000,\"sizelimit\":1000000,\"curtime\":1403691825,\"bits\":\"1d48d4f7\",\"height\":315152},\"error\":null,\"id\":1}";
            var blockTemplateObject = JsonConvert.DeserializeObject<DaemonResponse<BlockTemplate>>(json);
            _blockTemplate = blockTemplateObject.Result;

            // extra nonce
            _extraNonce = Substitute.For<ExtraNonce>((UInt32)0);

            // signature script
            _signatureScript = Substitute.For<SignatureScript>(
                _blockTemplate.Height,
                _blockTemplate.CoinBaseAux.Flags,
                1403691824760,
                (byte)_extraNonce.ExtraNoncePlaceholder.Length,
                "/nodeStratum/");

            // pool config
            var poolConfig = Substitute.For<IPoolConfig>();

            // create coin config.
            var coinConfig = Substitute.For<ICoinConfig>();
            coinConfig.Options.TxMessageSupported.Returns(false);
            coinConfig.Options.IsProofOfStakeHybrid.Returns(false);
            poolConfig.Coin.Returns(coinConfig);

            // outputs
            _outputs = Substitute.For<Outputs>(_daemonClient, coinConfig);
            double blockReward = 5000000000; // the amount rewarded by the block.

            // create rewards config.
            var rewardsConfig = Substitute.For<IRewardsConfig>();
            poolConfig.Rewards.Returns(rewardsConfig);

            var amount = blockReward * 0.01;
            blockReward -= amount;
            var rewards = new Dictionary<string, float> { { "mrwhWEDnU6dUtHZJ2oBswTpEdbBHgYiMji", (float)amount } };

            rewardsConfig.GetEnumerator().Returns(rewards.GetEnumerator());
            foreach (var pair in rewards)
            {
                _outputs.AddRecipient(pair.Key, pair.Value);
            }

            // create wallet config.
            var walletConfig = Substitute.For<IWalletConfig>();
            poolConfig.Wallet.Returns(walletConfig);

            // create sample pool central wallet output.
            walletConfig.Adress.Returns("mk8JqN1kNWju8o3DXEijiJyn7iqkwktAWq");
            _outputs.AddPoolWallet(walletConfig.Adress, blockReward);

            // generation transaction
            _generationTransaction = Substitute.For<GenerationTransaction>(_extraNonce, _daemonClient, _blockTemplate, poolConfig);
            _generationTransaction.Inputs.First().SignatureScript = _signatureScript;
            _generationTransaction.Outputs = _outputs;
            _generationTransaction.Create();

            // hash algorithm
            _hashAlgorithm = new Scrypt();

            // the job.
            _job = new Job(2,_hashAlgorithm, _blockTemplate, _generationTransaction)
            {
                CleanJobs = true
            };

            // the job tracker.
            _jobTracker = Substitute.For<IJobTracker>();
            _jobTracker.Get(2).Returns(_job);

            // the job manager.
            _jobManager = Substitute.For<IJobManager>();
            _jobManager.ExtraNonce.Next().Returns((UInt32)0x58000000);

            // coin config
            _miner = Substitute.For<IStratumMiner>();
            _miner.ExtraNonce.Returns((UInt32)0x58000000);
        }
コード例 #20
0
ファイル: Share.cs プロジェクト: zz0412/ZCoiniumServ
        public Share(IStratumMiner miner, UInt64 jobId, IJob job, string extraNonce2, string nTimeString, string nSolution)
        {
            Miner = miner;
            JobId = jobId;
            Job   = job;
            Error = ShareError.None;

            var submitTime = TimeHelpers.NowInUnixTimestamp(); // 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 = extraNonce2; // set extraNonce2 for the share.

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

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

            // 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);
            CoinbaseHash   = Coin.Coinbase.Utils.HashCoinbase(CoinbaseBuffer);

            string nonceString = extraNonce2.HexToByteArray().ReverseBuffer().ToHexString() + ExtraNonce1.BigEndian().ToString("x8");

            byte[] nonce = nonceString.HexToByteArray();


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

            // create the block headers
            {
                HeaderBuffer = Serializers.SerializeHeader(Job, MerkleRoot, nonce, NTime,
                                                           nSolution.HexToByteArray().ReverseBuffer());
                HeaderHash = Job.HashAlgorithm.Hash(HeaderBuffer);
            }

            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;

            // check if block candicate
            if (Job.Target >= HeaderValue)
            {
                IsBlockCandidate = true;
                BlockHex         = Serializers.SerializeBlock(Job, HeaderBuffer, CoinbaseBuffer, miner.Pool.Config.Coin.Options.IsProofOfStakeHybrid);
                BlockHash        = HeaderBuffer.DoubleDigest().ReverseBuffer();
            }
            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.
            }
        }
コード例 #21
0
        public Share(IStratumMiner miner, UInt64 jobId, IJob job, string extraNonce2, string nTimeString, string nonceString, UInt32[] cycle)
        {
            Miner = miner;
            JobId = jobId;
            Job   = job;
            Error = ShareError.None;
            Cycle = cycle;

            var submitTime = TimeHelpers.NowInUnixTimestamp(); // 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 != 8)
            {
                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)
            {
                Error = ShareError.NTimeOutOfRange;
                return;
            }

            // check size of miner supplied nonce.
            if (nonceString.Length != 8)
            {
                Error = ShareError.IncorrectNonceSize;
                return;
            }
            Nonce = Convert.ToUInt32(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);

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

            // create the block headers
            HeaderBuffer = Serializers.SerializeHeader(Job, MerkleRoot, NTime, Nonce);
            HeaderHash   = Job.HashAlgorithm.Hash(HeaderBuffer);
            HeaderValue  = new BigInteger(HeaderHash);
            BlockHash    = HeaderBuffer.DoubleDigest().ReverseBuffer();

            if (!checkCycle())
            {
                Error = ShareError.IncorrectCycle;
                return;
            }

            var _logger = Log.ForContext <Share>();

            using (var stream = new MemoryStream())
            {
                stream.WriteByte((byte)Cycle.Length);
                foreach (var edge in Cycle)
                {
                    stream.WriteValueU32(edge);
                }

                CycleBuffer = stream.ToArray();
            }

            CycleHash  = Job.HashAlgorithm.Hash(CycleBuffer);
            CycleValue = new BigInteger(CycleHash);

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

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

            // check if block candicate
            if (Job.Target >= CycleValue)
            {
                if (Difficulty < 0)
                {
                    IsBlockCandidate = false;
                    if (miner.Software == MinerSoftware.MeritMiner && miner.SoftwareVersion == new Version("0.1.0"))
                    {
                        // if we use merit-miner 0.1.0 diff can be negative
                        Error = ShareError.NegativeDifficultyShareOutdatedMiner;
                    }
                    else
                    {
                        Error = ShareError.NegativeDifficultyShare;
                    }
                    return;
                }
                IsBlockCandidate = true;

                BlockHex = Serializers.SerializeBlock(Job, HeaderBuffer, CoinbaseBuffer, CycleBuffer, miner.Pool.Config.Coin.Options.IsProofOfStakeHybrid);
            }
            else
            {
                IsBlockCandidate = false;

                // 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 (miner.PreviousDifficulty > 0 && Difficulty >= miner.PreviousDifficulty)  // if the difficulty matches miner's previous difficulty before the last vardiff triggered difficulty change
                {
                    _logger.Debug("\tprevdiff lower; diff >= prevdiff: {0}::{1}", Difficulty, miner.PreviousDifficulty);
                    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.
            }
        }
コード例 #22
0
 public void UpdateDifficulty(IStratumMiner miner)
 {
     // with-in our current hybrid-storage-layer, we don't need to write difficulty to persistance layer.
     return;
 }
コード例 #23
0
 public void UpdateDifficulty(IStratumMiner miner)
 {
     // with-in our current hybrid-storage-layer, we don't need to write difficulty to persistance layer.
     return;
 }