Пример #1
0
 public PendingBlockImpl()
 {
     block_         = null;
     totalUnzipped_ = 0;
     FZStreamError  = 0;
     FRecovered     = 0;
     FQueued        = 0;
 }
Пример #2
0
        private long UpdateToBlock(RequestedBlock block)
        {
            var result = PushNewBlock(block);

            if (result.BlockRequired != null)
            {
                UpdateToBlock(result.BlockRequired);
                result = PushNewBlock(block);
            }
            if (result.BlocksReverted != 0)
            {
                Log.Info($"Blocks reverted: {result.BlocksReverted}");
            }
            return(result.NewHeight);
        }
Пример #3
0
        private long UpdateToBlock(long blockNo, Stopwatch sw)
        {
            var block = new RequestedBlock(_web3, blockNo);

            sw.Restart();
            long ret;

            lock (this)
                ret = UpdateToBlock(block);
            sw.Stop();
            var ms    = sw.ElapsedMilliseconds;
            var speed = (double)block.Block.Transactions.LongLength / (double)ms * 1000;

            Log.Info($"Update completed in {ms} ms, speed: {speed}");
            return(ret);
        }
Пример #4
0
        private PushNewBlockResult PushNewBlock(RequestedBlock block)
        {
            var cr = _db.TryAddNewBlock(block.Block.ParentHash);

            if (cr.BlockRequired != null)
            {
                return(new PushNewBlockResult
                {
                    BlockRequired = cr.BlockRequired,
                    BlocksReverted = 0,
                    DbId = -1,
                    NewHeight = -1,
                });
            }
            var tokenTxCounts = new Dictionary <string, long>();

            for (int retries = 0; ; retries++)
            {
                try
                {
                    using (var dbTx = _db.BeginTransaction())
                    {
                        if (cr.BlocksToRevert.Count > 0)
                        {
                            Log.Info($"Reverting {cr.BlocksToRevert.Count} blocks.");
                            _db.DeleteBlocks(cr.BlocksToRevert);
                        }
                        var blockId = _db.InsertBlock(block, (x, y) => PostprocessTransaction(x, y, tokenTxCounts));
                        var height  = _db.AddNewBlock(block.Block.BlockHash, block.Block.ParentHash, blockId);
                        dbTx.Commit();

                        if (!Configuration.Get().Network.NetworkIsEthereum())
                        {
                            height++;
                        }

                        foreach (var kv in tokenTxCounts.Where(x => x.Value > 0))
                        {
                            Log.Info($"For token {kv.Key} processed {kv.Value} transactions.");
                        }

                        return(new PushNewBlockResult
                        {
                            BlocksReverted = cr.BlocksToRevert.Count,
                            DbId = blockId,
                            NewHeight = height,
                        });
                    }
                }
                catch (NullReceiptException)
                {
                    if (retries >= 5)
                    {
                        throw;
                    }
                    int seconds = 1 << retries;
                    Log.Warn($"Null receipt. Waiting for {seconds} seconds and retrying.");
                    Thread.Sleep(1000 * seconds);
                }
            }
        }
Пример #5
0
        private void DoInitialUpdate()
        {
            Log.Info("Doing initial update.");

            try
            {
                var  sw         = new Stopwatch();
                var  queuedData = new List <RequestedBlock>(5000);
                Task commitTask = null;

                long queuedTxs = 0;
                while (InternalContinueRunning())
                {
                    var latestIndexedBlock = _db.GetIndexedBlockchainHeight();
                    var lastestPublicBlock = GetLatestPublicBlock() - 100;
                    if (lastestPublicBlock <= latestIndexedBlock)
                    {
                        break;
                    }
                    for (long blockNo = latestIndexedBlock + 1;
                         InternalContinueRunning() && blockNo <= lastestPublicBlock;
                         blockNo++)
                    {
                        RequestedBlock block = null;
                        for (int i = 0; ; i++)
                        {
                            try
                            {
                                block = new RequestedBlock(_web3, blockNo);
                            }
                            catch
                            {
                                if (i == 5)
                                {
                                    throw;
                                }
                                Thread.Sleep(1000 * (1 << i));
                            }
                            break;
                        }

                        Debug.Assert(block != null);

                        if (_db.BlockExistsInBlockchain(block.Block))
                        {
                            Debugger.Break();
                        }

                        queuedData.Add(block);
                        queuedTxs += block.TransactionCount;
                        var blockTs = block.Timestamp;
                        if (!sw.IsRunning || sw.ElapsedMilliseconds >= 1000)
                        {
                            Log.Info(
                                $"{blockNo}, {blockTs.ToString("yyyy-MM-dd HH:mm:ss zzzz")} ({(double) blockNo/lastestPublicBlock:P})");
                            //Log.Info($"{blockNo}, {(double)blockNo / lastestPublicBlock:P}, with {block.TransactionCount} txs and {queuedTxs} txs in queue...");
                            sw.Restart();
                        }

                        if (queuedTxs >= 50000)
                        {
                            commitTask = CommitData(commitTask, ref queuedData, ref queuedTxs, false);
                        }
                    }
                    commitTask = CommitData(commitTask, ref queuedData, ref queuedTxs, true);
                }
                commitTask = CommitData(commitTask, ref queuedData, ref queuedTxs, true);
            }
            catch (Database.RestartException)
            {
                Log.Info("Non-fatal exception caught.");
            }
        }