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(); }
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(); }
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); }