Exemplo n.º 1
0
        public BaselineTreeNode[] GetHistoricalLeaves(BaselineTree tree, uint[] leafIndexes, long blockNumber)
        {
            if (_logger.IsWarn)
            {
                _logger.Warn(
                    $"Retrieving historical leaves of {tree} with index {string.Join(", ", leafIndexes)} for block {blockNumber}");
            }

            var historicalCount = tree.GetBlockCount(blockNumber);

            BaselineTreeNode[] leaves = new BaselineTreeNode[leafIndexes.Length];

            for (int i = 0; i < leafIndexes.Length; i++)
            {
                var leafIndex = leafIndexes[i];
                if (historicalCount <= leafIndex)
                {
                    leaves[i] = new BaselineTreeNode(Keccak.Zero, leafIndex);
                }
                else
                {
                    leaves[i] = tree.GetLeaf(leafIndex);
                }
            }

            return(leaves);
        }
        /// <summary>
        /// This class should smoothly react to new blocks and logs
        /// For now it will be very non-optimized just to deliver the basic functionality
        /// </summary>
        /// <param name="address"></param>
        /// <param name="baselineTree"></param>
        /// <param name="logFinder"></param>
        /// <param name="blockFinder"></param>
        public BaselineTreeTracker(Address address, BaselineTree baselineTree, ILogFinder logFinder, IBlockFinder blockFinder)
        {
            _address      = address ?? throw new ArgumentNullException(nameof(address));
            _baselineTree = baselineTree ?? throw new ArgumentNullException(nameof(baselineTree));
            _logFinder    = logFinder ?? throw new ArgumentNullException(nameof(logFinder));
            _blockFinder  = blockFinder ?? throw new ArgumentNullException(nameof(blockFinder));

            _timer = InitTimer();
        }
Exemplo n.º 3
0
        public BaselineTreeNode GetHistoricalLeaf(BaselineTree tree, uint leafIndex, long blockNumber)
        {
            if (_logger.IsWarn)
            {
                _logger.Warn($"Retrieving historical leaf of {tree} with index {leafIndex} for block {blockNumber}");
            }

            var historicalCount = tree.GetBlockCount(blockNumber);

            if (historicalCount <= leafIndex)
            {
                return(new BaselineTreeNode(Keccak.Zero, leafIndex));
            }

            return(tree.GetLeaf(leafIndex));
        }
        public BaselineTreeTracker(
            Address address,
            BaselineTree baselineTree,
            IBlockProcessor blockProcessor,
            IBaselineTreeHelper baselineTreeHelper,
            IBlockFinder blockFinder,
            ILogger logger)
        {
            _address            = address ?? throw new ArgumentNullException(nameof(address));
            _baselineTree       = baselineTree ?? throw new ArgumentNullException(nameof(baselineTree));
            _blockProcessor     = blockProcessor ?? throw new ArgumentNullException(nameof(blockProcessor));
            _baselineTreeHelper = baselineTreeHelper ?? throw new ArgumentNullException(nameof(baselineTreeHelper));
            _blockFinder        = blockFinder ?? throw new ArgumentNullException(nameof(blockFinder));
            _logger             = logger ?? throw new ArgumentNullException(nameof(logger));

            StartTracking();
        }
Exemplo n.º 5
0
        public BaselineTree BuildTree(BaselineTree baselineTree, Address treeAddress, BlockParameter blockFrom, BlockParameter blockTo)
        {
            if (_logger.IsWarn)
            {
                _logger.Warn($"Build {baselineTree} from {blockFrom} to {blockTo}");
            }

            var       initCount          = baselineTree.Count;
            LogFilter insertLeavesFilter = new LogFilter(
                0,
                blockFrom,
                blockTo,
                new AddressFilter(treeAddress),
                new SequenceTopicsFilter(new SpecificTopic(BaselineModule.LeavesTopic)));

            LogFilter insertLeafFilter = new LogFilter(
                0,
                blockFrom,
                blockTo,
                new AddressFilter(treeAddress),
                new SequenceTopicsFilter(new SpecificTopic(BaselineModule.LeafTopic)));

            var insertLeavesLogs = _logFinder.FindLogs(insertLeavesFilter);
            var insertLeafLogs   = _logFinder.FindLogs(insertLeafFilter);

            long?currentBlockNumber = null;
            uint count = 0;

            using var batch = baselineTree.StartBatch();
            foreach (FilterLog filterLog in insertLeavesLogs
                     .Union(insertLeafLogs)
                     .OrderBy(fl => fl.BlockNumber).ThenBy(fl => fl.LogIndex))
            {
                if (filterLog.BlockHash == baselineTree.LastBlockDbHash)
                {
                    continue;
                }
                if (currentBlockNumber == null)
                {
                    currentBlockNumber = filterLog.BlockNumber;
                }

                if (currentBlockNumber != filterLog.BlockNumber)
                {
                    baselineTree.MemorizePastCount(currentBlockNumber.Value, count);
                    currentBlockNumber = filterLog.BlockNumber;
                }

                if (filterLog.Data.Length == 96)
                {
                    Keccak leafHash = new Keccak(filterLog.Data.Slice(32, 32).ToArray());

                    if (_logger.IsWarn)
                    {
                        _logger.Warn($"Inserting leaf into {baselineTree} in block {currentBlockNumber}");
                    }
                    baselineTree.Insert(leafHash, false);
                    ++count;
                }
                else
                {
                    for (int i = 0; i < (filterLog.Data.Length - 128) / 32; i++)
                    {
                        Keccak leafHash = new Keccak(filterLog.Data.Slice(128 + 32 * i, 32).ToArray());
                        if (_logger.IsWarn)
                        {
                            _logger.Warn($"Inserting leaf {i} into {baselineTree} in block {currentBlockNumber}");
                        }
                        baselineTree.Insert(leafHash, false);
                        ++count;
                    }
                }
            }

            if (currentBlockNumber != null && count != 0)
            {
                baselineTree.MemorizePastCount(currentBlockNumber.Value, baselineTree.Count);
            }

            baselineTree.CalculateHashes(initCount);
            return(baselineTree);
        }