private uint AddFromCurrentBlock(TxReceipt[] txReceipts)
        {
            uint      newLeavesCount     = 0;
            LogFilter insertLeavesFilter = new LogFilter(
                0,
                new BlockParameter(0L),
                new BlockParameter(0L),
                new AddressFilter(_address),
                new AnyTopicsFilter(new SpecificTopic(BaselineModule.LeavesTopic), new SpecificTopic(BaselineModule.LeafTopic)));
            var logs = _currentBlockHeader.FindLogs(txReceipts, insertLeavesFilter, FindOrder.Ascending, FindOrder.Ascending);

            foreach (var filterLog in logs)
            {
                if (filterLog.Data.Length == 96)
                {
                    Keccak leafHash = new Keccak(filterLog.Data.Slice(32, 32).ToArray());
                    _baselineTree.Insert(leafHash, false);
                    ++newLeavesCount;
                }
                else
                {
                    for (int i = 0; i < (filterLog.Data.Length - 128) / 32; i++)
                    {
                        Keccak leafHash = new Keccak(filterLog.Data.Slice(128 + 32 * i, 32).ToArray());
                        _baselineTree.Insert(leafHash, false);
                        ++newLeavesCount;
                    }
                }
            }

            return(newLeavesCount);
        }
Example #2
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);
        }