private void OnBlockProcessed(object?sender, BlockProcessedEventArgs e) { if (_logger.IsWarn) { _logger.Warn($"Tree tracker for {_baselineTree} processing block {e.Block.ToString(Block.Format.Short)}"); } if (_currentBlockHeader != null && _currentBlockHeader.Hash != e.Block.ParentHash && _currentBlockHeader.Number < e.Block.Number) { // what is this - not covered by any test? // why do we build tree here? _baselineTreeHelper.BuildTree(_baselineTree, _address, new BlockParameter(_currentBlockHeader.Hash), new BlockParameter(e.Block.Hash)); _currentBlockHeader = e.Block.Header; // TODO: why this is here _baselineTree.MemorizeCurrentCount(_baselineTree.LastBlockDbHash, _baselineTree.LastBlockWithLeaves, _baselineTree.Count); return; } uint removedItemsCount = 0; bool reorganized = _currentBlockHeader != null && _currentBlockHeader.Hash != e.Block.ParentHash; if (reorganized) { if (_logger.IsWarn) { _logger.Warn( $"Tree tracker for {_baselineTree} reorganizes from branching point at {e.Block.ToString(Block.Format.Short)}"); } removedItemsCount = Revert(e.Block.Number); } _currentBlockHeader = e.Block.Header; uint treeStartingCount = _baselineTree.Count; uint newLeavesCount = AddFromCurrentBlock(e.TxReceipts); _baselineTree.CalculateHashes(treeStartingCount - removedItemsCount); if (newLeavesCount != 0 || removedItemsCount != 0 || reorganized) { uint currentTreeCount = treeStartingCount + newLeavesCount - removedItemsCount; _baselineTree.MemorizeCurrentCount(e.Block.Hash, e.Block.Number, currentTreeCount); } }
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); }