private static async Task SaveAllAsync() { await SemaphoreSave.WaitAsync().ConfigureAwait(false); try { AddressManager.SavePeerFile(_addressManagerFilePath, Network); SaveSpvChain(); } finally { SemaphoreSave.Release(); } LocalPartialChain.SaveAsync(_partialChainFolderPath).Wait(); Console.WriteLine($"{nameof(LocalPartialChain)} saved"); }
private static void Reorg() { Console.WriteLine($"Reorg detected at {LocalSpvChain.Height}. Handling reog."); LocalSpvChain.SetTip(LocalSpvChain.Tip.Previous); LocalPartialChain.ReorgOne(); }
private static async Task BlockPullerJobAsync(CancellationToken ctsToken) { while (true) { if (ctsToken.IsCancellationRequested) { Console.WriteLine($"{nameof(BlockPullerJobAsync)} is stopped."); return; } if (LocalSpvChain.Height < WalletCreationHeight) { await Task.Delay(1000, ctsToken).ContinueWith(tsk => { }).ConfigureAwait(false); continue; } int height; if (LocalPartialChain.BlockCount == 0) { height = WalletCreationHeight; } else if (LocalSpvChain.Height <= LocalPartialChain.BestHeight) { await Task.Delay(100, ctsToken).ContinueWith(tsk => { }).ConfigureAwait(false); continue; } else { height = LocalPartialChain.BestHeight + 1; } var chainedBlock = LocalSpvChain.GetBlock(height); BlockPuller.SetLocation(new ChainedBlock(chainedBlock.Previous.Header, chainedBlock.Previous.Height)); Block block = null; CancellationTokenSource ctsBlockDownload = CancellationTokenSource.CreateLinkedTokenSource( new CancellationTokenSource(TimeSpan.FromSeconds(timeoutDownSec)).Token, ctsToken); try { block = await Task.Run(() => BlockPuller.NextBlock(ctsBlockDownload.Token)).ConfigureAwait(false); } catch (OperationCanceledException) { if (ctsToken.IsCancellationRequested) { return; } Console.WriteLine($"Failed to download block {chainedBlock.Height} within {timeoutDownSec} seconds. Retry"); if (timeoutDownSec > 180) { timeoutDownSec = 20; _nodes.Purge("no reason"); } else { timeoutDownSec = timeoutDownSec * 2; // adjust to the network speed } continue; } //reorg test //if(new Random().Next(100) >= 60) block = null; if (block == null) // then reorg happened { Reorg(); continue; } LocalPartialChain.Add(chainedBlock.Height, block); // check if chains are in sync, to be sure var bh = LocalPartialChain.BestHeight; for (int i = bh; i > bh - 6; i--) { if (!LocalPartialChain.Chain[i].MerkleProof.Header.GetHash() .Equals(LocalSpvChain.GetBlock(i).Header.GetHash())) { // something worng, reorg Reorg(); } } Console.WriteLine($"Full blocks left to download: {LocalSpvChain.Height - LocalPartialChain.BestHeight}"); } }