/// <summary> /// Set the new block template, generated from the response deserialization. /// </summary> public void SetBlockTemplateLocked(RPCBlockTemplate blockTemplate) { lock (lockObject) { if (blockTemplate == null || this.currentBlockTemplate == null || this.currentBlockTemplate.previousblockhash != blockTemplate.previousblockhash) { this.extraNonce = 0; } this.currentBlockTemplate = blockTemplate; } }
bool EnsureBlockTemplate() { this.BlockTemplate = this.blockTemplateCache.GetClonedBlockTemplateLocked(); return(this.BlockTemplate != null && this.BlockTemplate.height % 2 == 0); }
async Task PullWorkLoop() { while (!this.appConfiguration.Cts.IsCancellationRequested) { try { if (this.appConfiguration.Stake) { var getUnspentOutputsResponse = await this.rpcClient.GetUnspentOutputs(); var dumpWalletResponse = await this.rpcClient.DumpWallet(Path.Combine(this.appConfiguration.DataDirRoot.ToString(), "dumptemp.txt")); if (getUnspentOutputsResponse.Status == 200 && dumpWalletResponse.Status == 200) { PushToCoinsCache(getUnspentOutputsResponse.Result.result, dumpWalletResponse.Result.result, false); } } this.logger.LogInformation("Requesting block template..."); var getBlockTemplateResponse = await this.rpcClient.GetBlockTemplate(); if (getBlockTemplateResponse.Status != 200) { if (!this.appConfiguration.Cts.IsCancellationRequested) { this.logger.LogError("Block template was null, waiting 10 seconds before next request..."); await Task.Delay(10000); } continue; } if (getBlockTemplateResponse.Result.result.longpollid == prevLongPollId) { // if we would continue here, we'd just cancel the miner for nothing... this.logger.LogWarning("Block template is not new, ignoring and waiting 10 seconds before next request."); await Task.Delay(10000); continue; } else { prevLongPollId = getBlockTemplateResponse.Result.result.longpollid; } RPCBlockTemplate blockTemplate = getBlockTemplateResponse.Result.result; uint posBits = blockTemplate.ParseBits(true); uint powBits = blockTemplate.ParseBits(false); Target posTarget = new Target(posBits); Target powTarget = new Target(powBits); this.logger.LogInformation($"New block template: {blockTemplate.previousblockhash}-{blockTemplate.TemplateNumber} Block: {blockTemplate.height} Reward: {Money.Satoshis(blockTemplate.coinbasevalue)} X1{Environment.NewLine}" + $"Proof-of-Stake: Target: {blockTemplate.posbits} Difficulty: {posTarget.Difficulty.ToString("0").PadLeft(7)} Equivalent to PoW hash rate: { HashRate.EstimateGHashPerSecondFromBits(posBits).ToString("0.0").PadLeft(7)} GHash/s{Environment.NewLine}" + $"Proof-of-Work: Target: {blockTemplate.bits} Difficulty: {powTarget.Difficulty.ToString("0").PadLeft(7)} Estimated network hash rate: { HashRate.EstimateGHashPerSecondFromBits(powBits).ToString("0.0").PadLeft(7)} GHash/s"); this.blockTemplateCache.SetBlockTemplateLocked(blockTemplate); if (this.appConfiguration.Mine) { this.minerCoordinator.NotifyBlockTemplateReceived(blockTemplate.height % 2 != 0); } } catch (Exception e) { this.stakingService.BlockTemplate = null; if (!this.appConfiguration.Cts.IsCancellationRequested) { Console.WriteLine($"Error in PullWorkLoop: {e.Message}"); } } await Task.Delay(1000); } HasShutDown = true; }