private void QueryBlock(ref IPersistedBlock block)
        {
            var blockInfo = _blockProcessor.GetBlock(block.BlockHash); // query the block.

            if (blockInfo == null || blockInfo.Confirmations == -1)    // make sure the block exists and is accepted.
            {
                block.Status = BlockStatus.Orphaned;
                return;
            }

            // calculate our expected generation transactions's hash
            var expectedTxHash = block.TransactionHash; // expected transaction hash
            var genTxHash      = blockInfo.Tx.First();  // read the hash of very first (generation transaction) of the block

            // make sure our calculated and reported generation tx hashes match.
            if (expectedTxHash != genTxHash)
            {
                block.Status = BlockStatus.Orphaned;
                return;
            }

            var genTx = _blockProcessor.GetGenerationTransaction(blockInfo); // get the generation transaction.

            // get the output transaction that targets pools central wallet.
            var poolOutput = _blockProcessor.GetPoolOutput(genTx);

            // make sure we have a valid reference to poolOutput
            if (poolOutput == null)
            {
                block.Status = BlockStatus.Orphaned;
                return;
            }

            block.SetReward((decimal)poolOutput.Amount); // set the reward of the block to miners.

            switch (poolOutput.Category)
            {
            case "immature":
                block.Status = BlockStatus.Pending;
                break;

            case "orphan":
                block.Status = BlockStatus.Orphaned;
                break;

            case "generate":
                block.Status = BlockStatus.Confirmed;
                break;
            }


            // TODO: add back these.
            // total amount of coins contained in the block.
            // candidate.Amount = transaction.Details.Sum(output => (decimal)output.Amount);
            // candidate.Reward = (decimal) poolOutput.Amount;
        }
Exemple #2
0
        private bool SubmitBlock(IShare share)
        {
            // TODO: we should try different submission techniques and probably more then once: https://github.com/ahmedbodi/stratum-mining/blob/master/lib/bitcoin_rpc.py#L65-123

            try
            {
                _daemonClient.SubmitBlock(share.BlockHex.ToHexString());

                var block = _blockProcessor.GetBlock(share.BlockHash.ToHexString()); // query the block.

                if (block == null)                                                   // make sure the block exists
                {
                    return(false);
                }

                if (block.Confirmations == -1) // make sure the block is accepted.
                {
                    _logger.Debug("Submitted block {0:l} is orphaned", block.Hash);
                    return(false);
                }

                var expectedTxHash = share.CoinbaseHash.Bytes.ReverseBuffer().ToHexString(); // calculate our expected generation transactions's hash
                var genTxHash      = block.Tx.First();                                       // read the hash of very first (generation transaction) of the block

                if (expectedTxHash != genTxHash)                                             // make sure our calculated generated transaction and one reported by coin daemon matches.
                {
                    _logger.Debug("Submitted block {0:l} doesn't seem to belong us as reported generation transaction hash [{1:l}] doesn't match our expected one [{2:l}]", block.Hash, genTxHash, expectedTxHash);
                    return(false);
                }

                var genTx = _blockProcessor.GetGenerationTransaction(block); // get the generation transaction.

                var poolOutput = _blockProcessor.GetPoolOutput(genTx);       // get the output that targets pool's central address.

                // make sure the blocks generation transaction contains our central pool wallet address
                if (poolOutput == null)
                {
                    _logger.Debug("Submitted block doesn't seem to belong us as generation transaction doesn't contain an output for pool's central wallet address: {0:}", _poolConfig.Wallet.Adress);
                    return(false);
                }

                // if the code flows here, then it means the block was succesfully submitted and belongs to us.
                share.SetFoundBlock(block, genTx); // assign the block to share.

                return(true);
            }
            catch (Exception e)
            {
                _logger.Error("Submit block failed - height: {0}, hash: {1:l} - {2:l}", share.Height, share.BlockHash.ToHexString(), e.Message);
                return(false);
            }
        }