public List <uint256> GenerateBlocks(ReserveScript reserveScript, int generate, int maxTries, bool keepScript) { // temporary code to mine blocks while doing some simulations // this will be refactored to have the same logic as core with regards to // selecting and sorting transactions from the mempool. if (fullNode.Chain.Tip != fullNode.ConsensusLoop.Tip) { return(Enumerable.Empty <uint256>().ToList()); } List <Block> blocks = new List <Block>(); for (int i = 0; i < generate; i++) { uint nonce = 0; Block block = new Block(); block.Header.HashPrevBlock = fullNode.Chain.Tip.HashBlock; //block.Header.Bits = GetWorkRequired(fullNode.Network.Consensus,new ChainedBlock(block.Header, (uint256) null, fullNode.Chain.Tip)); block.Header.Bits = block.Header.GetWorkRequired(fullNode.Network, fullNode.Chain.Tip); block.Header.UpdateTime(dateTimeProvider.GetTimeOffset(), fullNode.Network, fullNode.Chain.Tip); var coinbase = new Transaction(); coinbase.AddInput(TxIn.CreateCoinbase(fullNode.Chain.Height + 1)); coinbase.AddOutput(new TxOut(fullNode.Network.GetReward(fullNode.Chain.Height + 1), reserveScript.reserveSfullNodecript)); block.AddTransaction(coinbase); //if (passedTransactions?.Any() ?? false) //{ // passedTransactions = Reorder(passedTransactions); // block.Transactions.AddRange(passedTransactions); //} block.UpdateMerkleRoot(); var retry = 0; while (!block.CheckProofOfWork() && !fullNode.IsDisposed && ++retry < maxTries) { block.Header.Nonce = ++nonce; } if (fullNode.IsDisposed || retry >= maxTries) { return(blocks.Select(b => b.GetHash()).ToList()); } if (block.Header.HashPrevBlock != fullNode.Chain.Tip.HashBlock) { i--; continue; // a new block was found continue to look } blocks.Add(block); var newChain = new ChainedBlock(block.Header, block.GetHash(), fullNode.Chain.Tip); fullNode.Chain.SetTip(newChain); var blockResult = new BlockResult { Block = block }; fullNode.ConsensusLoop.AcceptBlock(blockResult); if (blockResult.ChainedBlock == null) { break; //reorg } // similar logic to what's in the full node code if (blockResult.Error == null) { fullNode.ChainBehaviorState.HighestValidatedPoW = fullNode.ConsensusLoop.Tip; //if (fullNode.Chain.Tip.HashBlock == blockResult.ChainedBlock.HashBlock) //{ // var unused = cache.FlushAsync(); //} fullNode.Signals.Blocks.Broadcast(block); } // ensure the block is written to disk retry = 0; while (++retry < maxTries && this.fullNode.BlockStoreManager.BlockRepository.GetAsync(blockResult.ChainedBlock.HashBlock).GetAwaiter().GetResult() == null) { Thread.Sleep(100); } if (retry >= maxTries) { return(blocks.Select(b => b.GetHash()).ToList()); } } return(blocks.Select(b => b.GetHash()).ToList()); }
public List <uint256> GenerateBlocks(ReserveScript reserveScript, int generate, int maxTries, bool keepScript) { int nHeightStart = 0; int nHeightEnd = 0; int nHeight = 0; nHeightStart = this.chain.Height; nHeight = nHeightStart; nHeightEnd = nHeightStart + generate; int nExtraNonce = 0; var blocks = new List <uint256>(); if (this.chain.Tip != this.consensusLoop.Tip) { return(blocks); } while (nHeight < nHeightEnd) { var pblocktemplate = this.blockAssemblerFactory.Create().CreateNewBlock(reserveScript.reserveSfullNodecript); BlockAssembler.IncrementExtraNonce(pblocktemplate.Block, this.chain.Tip, nExtraNonce); var pblock = pblocktemplate.Block; while (maxTries > 0 && pblock.Header.Nonce < nInnerLoopCount && !pblock.CheckProofOfWork()) { ++pblock.Header.Nonce; --maxTries; } if (maxTries == 0) { break; } if (pblock.Header.Nonce == nInnerLoopCount) { continue; } var newChain = new ChainedBlock(pblock.Header, pblock.GetHash(), fullNode.Chain.Tip); this.chain.SetTip(newChain); var blockResult = new BlockResult { Block = pblock }; fullNode.ConsensusLoop.AcceptBlock(new ContextInformation(blockResult, fullNode.Network.Consensus)); if (blockResult.ChainedBlock == null) { break; //reorg } if (blockResult.Error != null) { return(blocks); } // similar logic to what's in the full node code fullNode.ChainBehaviorState.HighestValidatedPoW = fullNode.ConsensusLoop.Tip; fullNode.Signals.Blocks.Broadcast(pblock); ++nHeight; blocks.Add(pblock.GetHash()); // ensure the block is written to disk var retry = 0; while (++retry < maxTries && !this.fullNode.BlockStoreManager.BlockRepository.ExistAsync(blockResult.ChainedBlock.HashBlock).GetAwaiter().GetResult()) { Thread.Sleep(100); } } return(blocks); }
public List <uint256> GenerateBlocks(ReserveScript reserveScript, ulong generate, ulong maxTries) { ulong nHeightStart = 0; ulong nHeightEnd = 0; ulong nHeight = 0; nHeightStart = (ulong)this.chain.Height; nHeight = nHeightStart; nHeightEnd = nHeightStart + generate; int nExtraNonce = 0; var blocks = new List <uint256>(); // BlockTemplate pblocktemplate = null; while (nHeight < nHeightEnd) { try { if (this.chain.Tip != this.consensusLoop.Tip) { Task.Delay(TimeSpan.FromMinutes(1), this.nodeLifetime.ApplicationStopping).GetAwaiter().GetResult(); continue; } var pblocktemplate = this.blockAssemblerFactory.Create().CreateNewBlock(reserveScript.reserveSfullNodecript); this.IncrementExtraNonce(pblocktemplate.Block, this.chain.Tip, nExtraNonce); var pblock = pblocktemplate.Block; while (maxTries > 0 && pblock.Header.Nonce < InnerLoopCount && !pblock.CheckProofOfWork()) { ++pblock.Header.Nonce; --maxTries; } if (maxTries == 0) { break; } if (pblock.Header.Nonce == InnerLoopCount) { continue; } var newChain = new ChainedBlock(pblock.Header, pblock.GetHash(), this.chain.Tip); if (newChain.ChainWork <= this.chain.Tip.ChainWork) { continue; } this.chain.SetTip(newChain); var blockResult = new BlockResult { Block = pblock }; this.consensusLoop.AcceptBlock(new ContextInformation(blockResult, this.network.Consensus)); if (blockResult.ChainedBlock == null) { break; //reorg } if (blockResult.Error != null) { return(blocks); } // similar logic to what's in the full node code this.chainState.HighestValidatedPoW = this.consensusLoop.Tip; this.signals.Blocks.Broadcast(pblock); Logs.Mining.LogInformation($"Mined new {(BlockStake.IsProofOfStake(blockResult.Block) ? "POS" : "POW")} block: {blockResult.ChainedBlock.HashBlock}"); ++nHeight; blocks.Add(pblock.GetHash()); // ensure the block is written to disk ulong retry = 0; while (++retry < maxTries && !this.blockRepository.ExistAsync(blockResult.ChainedBlock.HashBlock).GetAwaiter().GetResult()) { Thread.Sleep(100); } pblocktemplate = null; } catch (ConsensusErrorException cer) { if (cer.ConsensusError == ConsensusErrors.InvalidPrevTip) { continue; } throw; } } return(blocks); }