public async Task HealTreeWithoutBoundaryProofs() { DbContext dbContext = new DbContext(_logger, _logManager); TestItem.Tree.FillStateTreeWithTestAccounts(dbContext.RemoteStateTree); Keccak rootHash = dbContext.RemoteStateTree.RootHash; ProcessAccountRange(dbContext.RemoteStateTree, dbContext.LocalStateTree, 1, rootHash, TestItem.Tree.AccountsWithPaths); SyncPeerMock mock = new SyncPeerMock(dbContext.RemoteStateDb, dbContext.RemoteCodeDb); SafeContext ctx = PrepareDownloader(dbContext, mock); await ActivateAndWait(ctx, dbContext, 1024); DetailedProgress data = ctx.TreeFeed.GetDetailedProgress(); dbContext.CompareTrees("END"); Assert.AreEqual(dbContext.RemoteStateTree.RootHash, dbContext.LocalStateTree.RootHash); Assert.AreEqual(0, data.RequestedNodesCount); // 4 boundary proof nodes stitched together => 0 }
public async Task HealBigSquezedRandomTree() { DbContext dbContext = new DbContext(_logger, _logManager); int pathPoolCount = 100_000; Keccak[] pathPool = new Keccak[pathPoolCount]; SortedDictionary <Keccak, Account> accounts = new(); int updatesCount = 0; int deletionsCount = 0; for (int i = 0; i < pathPoolCount; i++) { byte[] key = new byte[32]; ((UInt256)i).ToBigEndian(key); Keccak keccak = new Keccak(key); pathPool[i] = keccak; } // generate Remote Tree for (int accountIndex = 0; accountIndex < 10000; accountIndex++) { Account account = TestItem.GenerateRandomAccount(); Keccak path = pathPool[TestItem.Random.Next(pathPool.Length - 1)]; dbContext.RemoteStateTree.Set(path, account); accounts[path] = account; } dbContext.RemoteStateTree.Commit(0); int startingHashIndex = 0; int endHashIndex = 0; int blockJumps = 5; for (int blockNumber = 1; blockNumber <= blockJumps; blockNumber++) { for (int i = 0; i < 19; i++) { endHashIndex = startingHashIndex + 1000; ProcessAccountRange(dbContext.RemoteStateTree, dbContext.LocalStateTree, blockNumber, dbContext.RemoteStateTree.RootHash, accounts.Where(a => a.Key >= pathPool[startingHashIndex] && a.Key <= pathPool[endHashIndex]).Select(a => new PathWithAccount(a.Key, a.Value)).ToArray()); startingHashIndex = endHashIndex + 1; } for (int accountIndex = 0; accountIndex < 1000; accountIndex++) { Account account = TestItem.GenerateRandomAccount(); Keccak path = pathPool[TestItem.Random.Next(pathPool.Length - 1)]; if (accounts.ContainsKey(path)) { if (TestItem.Random.NextSingle() > 0.5) { dbContext.RemoteStateTree.Set(path, account); accounts[path] = account; updatesCount++; } else { dbContext.RemoteStateTree.Set(path, null); accounts.Remove(path); deletionsCount++; } } else { dbContext.RemoteStateTree.Set(path, account); accounts[path] = account; } } dbContext.RemoteStateTree.Commit(blockNumber); } endHashIndex = startingHashIndex + 1000; while (endHashIndex < pathPool.Length - 1) { endHashIndex = startingHashIndex + 1000; if (endHashIndex > pathPool.Length - 1) { endHashIndex = pathPool.Length - 1; } ProcessAccountRange(dbContext.RemoteStateTree, dbContext.LocalStateTree, blockJumps, dbContext.RemoteStateTree.RootHash, accounts.Where(a => a.Key >= pathPool[startingHashIndex] && a.Key <= pathPool[endHashIndex]).Select(a => new PathWithAccount(a.Key, a.Value)).ToArray()); startingHashIndex += 1000; } SyncPeerMock mock = new SyncPeerMock(dbContext.RemoteStateDb, dbContext.RemoteCodeDb); dbContext.LocalStateTree.RootHash = dbContext.RemoteStateTree.RootHash; SafeContext ctx = PrepareDownloader(dbContext, mock); await ActivateAndWait(ctx, dbContext, 9); DetailedProgress data = ctx.TreeFeed.GetDetailedProgress(); dbContext.LocalStateTree.UpdateRootHash(); dbContext.CompareTrees("END"); _logger.Info($"REQUESTED NODES TO HEAL: {data.RequestedNodesCount}"); Assert.IsTrue(data.RequestedNodesCount < accounts.Count / 2); }
/// <summary> /// Generate the social networking report /// </summary> public void Generate(Status StatusCallback, WriteRows WriteRowsCallback, DetailedProgress DetailedProgressCallback) { // Look up each colleague in the database DataTable ColleagueRows = DB.ExecuteQuery("SELECT Setnb, First, Middle, Last FROM " + FirstDegreeDB + ".Colleagues ORDER BY Setnb"); int RowCount = ColleagueRows.Rows.Count; for (int Row = 0; Row < RowCount; Row++) { // Get the social network for the colleague DataRow ColleagueRow = ColleagueRows.Rows[Row]; if ((ColleaguesToInclude.Count == 0 || ColleaguesToInclude.Contains(ColleagueRow["Setnb"].ToString().ToLower())) && (!ColleaguesToExclude.Contains(ColleagueRow["Setnb"].ToString().ToLower()))) { string Colleague = ColleagueRow["Setnb"].ToString(); Hashtable Network = GetSocialNetwork(Colleague); // Send back status string Name = ColleagueRow["First"].ToString(); if (ColleagueRow["Middle"].ToString().Trim() != "") { Name += " " + ColleagueRow["Middle"].ToString(); } Name += " " + ColleagueRow["Last"].ToString(); if (StatusCallback != null) { StatusCallback(Row + 1, RowCount, Colleague, Name); } // The report must be in ascending order. string[] Keys = new string[Network.Keys.Count]; Network.Keys.CopyTo(Keys, 0); Array.Sort(Keys); // Declare a DataTable to store the current subset of the report DataTable Results = new DataTable(); // Generate the rows for each colleague and roll them onto the end of the report for (int i = 0; i < Network.Keys.Count; i++) { // Get the second degere stars string Star = Keys[i].ToString(); SecondDegreeStars secondDegreeStars = new SecondDegreeStars(DB, Colleague, FirstDegreeDB, Star, SecondDegreeDB); // Make sure the second degere stars are processed in order for (int j = 0; j < secondDegreeStars.Setnbs.Count; j++) { if (DetailedProgressCallback != null) { DetailedProgressCallback(i + 1, Network.Keys.Count + 1, j + 1, secondDegreeStars.Setnbs.Count + 1); } // Roll the report rows onto the end of the report string SecondDegree = secondDegreeStars.Setnbs[j].ToString(); Results = RollUpReportRows(Results, RowsForColleagueStarSecondDegree(Colleague, Star, SecondDegree)); } if (DetailedProgressCallback != null) { DetailedProgressCallback(Network.Keys.Count + 1, Network.Keys.Count + 1, secondDegreeStars.Setnbs.Count + 1, secondDegreeStars.Setnbs.Count + 1); } } // Write the report rows if (WriteRowsCallback != null) { WriteRowsCallback(Results); } } } }