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