Beispiel #1
0
        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");
        }
Beispiel #2
0
 private static void Reorg()
 {
     Console.WriteLine($"Reorg detected at {LocalSpvChain.Height}. Handling reog.");
     LocalSpvChain.SetTip(LocalSpvChain.Tip.Previous);
     LocalPartialChain.ReorgOne();
 }
Beispiel #3
0
        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}");
            }
        }