public void Receipts_finish_properly_when_the_last_batch_has_no_receipts() { _syncConfig = new SyncConfig(); _syncConfig.PivotHash = _validTree2048NoTransactions.Head.Hash.ToString(); _syncConfig.PivotNumber = _validTree2048NoTransactions.Head.Number.ToString(); _syncConfig.PivotTotalDifficulty = _validTree2048NoTransactions.Head.TotalDifficulty.ToString(); _syncConfig.UseGethLimitsInFastBlocks = false; _syncConfig.DownloadBodiesInFastSync = true; _syncConfig.DownloadReceiptsInFastSync = true; _syncConfig.FastBlocks = true; _feed = new FastBlocksFeed(_specProvider, _localBlockTree, _localReceiptStorage, _syncPeerPool, _syncConfig, NullSyncReport.Instance, LimboLogs.Instance); LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048NoTransactions); SetupSyncPeers(syncPeer1); RunFeed(10000); SyncProgressResolver resolver = new SyncProgressResolver( _localBlockTree, _localReceiptStorage, Substitute.For <INodeDataDownloader>(), _syncConfig, LimboLogs.Instance); Assert.True(resolver.IsFastBlocksFinished(), "is fast blocks finished"); AssertTreeSynced(_validTree2048NoTransactions, true, true); }
public void One_peer_with_valid_chain() { LatencySyncPeerMock syncPeer = new LatencySyncPeerMock(_validTree2048); SetupSyncPeers(syncPeer); RunFeed(); Assert.AreEqual(24, _time); AssertTreeSynced(_validTree2048); }
public void Throws_when_launched_and_disabled_in_config() { _syncConfig.FastBlocks = false; SetupFeed(); LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048); SetupSyncPeers(syncPeer1); Assert.Throws <InvalidOperationException>(() => RunFeed(1000)); }
public void One_peer_with_valid_one_with_invalid_B() { LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048, 300); LatencySyncPeerMock syncPeer2 = new LatencySyncPeerMock(_badTreeAfter1024); SetupSyncPeers(syncPeer1, syncPeer2); RunFeed(); Assert.AreEqual(602, _time); AssertTreeSynced(_validTree2048); }
public void One_peer_with_valid_chain_bodies_restarting() { LatencySyncPeerMock syncPeer = new LatencySyncPeerMock(_validTree2048); SetupFeed(true); SetupSyncPeers(syncPeer); RunFeed(5000, 9); Assert.AreEqual(78, _time); AssertTreeSynced(_validTree2048, true); }
public void Two_peers_with_valid_chain_one_shorter() { LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048); LatencySyncPeerMock syncPeer2 = new LatencySyncPeerMock(_validTree1024); SetupSyncPeers(syncPeer1, syncPeer2); RunFeed(); Assert.AreEqual(18, _time); AssertTreeSynced(_validTree2048); }
public void Two_peers_with_valid_chain_bodies() { LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048); LatencySyncPeerMock syncPeer2 = new LatencySyncPeerMock(_validTree2048); SetupFeed(true); SetupSyncPeers(syncPeer1, syncPeer2); RunFeed(); Assert.AreEqual(26, _time); AssertTreeSynced(_validTree2048, true); }
private void PrepareHeadersResponse(HeadersSyncBatch headersSyncBatch, LatencySyncPeerMock syncPeer, IBlockTree tree) { if (headersSyncBatch != null) { long startNumber = headersSyncBatch.StartNumber; if (_maliciousByShiftedOneBack.Contains(syncPeer)) { startNumber++; TestContext.WriteLine($"{_time,6} | SYNC PEER {syncPeer.Node:s} WILL SEND SHIFTED MESSAGES ({startNumber} INSTEAD OF {headersSyncBatch.StartNumber})"); } else if (_maliciousByShiftedOneForward.Contains(syncPeer)) { startNumber = Math.Max(0, startNumber - 1); TestContext.WriteLine($"{_time,6} | SYNC PEER {syncPeer.Node:s} WILL SEND SHIFTED MESSAGES ({startNumber} INSTEAD OF {headersSyncBatch.StartNumber})"); } Keccak hash = tree.FindHash(startNumber); if (hash == null) { TestContext.WriteLine($"{_time,6} | SYNC PEER {syncPeer.Node:s} CANNOT FIND {headersSyncBatch.StartNumber}"); return; } int requestSize = headersSyncBatch.RequestSize; if (_incorrectByTooLongMessages.Contains(syncPeer)) { requestSize *= 2; TestContext.WriteLine($"{_time,6} | SYNC PEER {syncPeer.Node:s} WILL SEND TOO LONG MESSAGE ({requestSize} INSTEAD OF {headersSyncBatch.RequestSize})"); } else if (_incorrectByTooShortMessages.Contains(syncPeer)) { requestSize = Math.Max(1, requestSize / 2); TestContext.WriteLine($"{_time,6} | SYNC PEER {syncPeer.Node:s} WILL SEND TOO SHORT MESSAGE ({requestSize} INSTEAD OF {headersSyncBatch.RequestSize})"); } BlockHeader[] headers = tree.FindHeaders(hash, requestSize, 0, false); if (_invalidBlocks.ContainsKey(syncPeer)) { for (int i = 0; i < headers.Length; i++) { if (_invalidBlocks[syncPeer].Contains(headers[i].Number)) { TestContext.WriteLine($"{_time,6} | SYNC PEER {syncPeer.Node:s} WILL SEND AN INVALID BLOCK AT {headers[i].Number}"); headers[i] = Build.A.Block.WithDifficulty(1).TestObject.Header; } } } if (headers.Length > 3 && _maliciousByRepetition.Contains(syncPeer)) { headers[^ 1] = headers[^ 3];
public void Two_peers_one_malicious_by_repetition() { LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048); LatencySyncPeerMock syncPeer2 = new LatencySyncPeerMock(_validTree2048); _maliciousByRepetition.Add(syncPeer1); SetupSyncPeers(syncPeer1, syncPeer2); RunFeed(); Assert.AreEqual(25, _time); AssertTreeSynced(_validTree2048); }
private void PrepareReceiptsResponse(ReceiptsSyncBatch receiptSyncBatch, LatencySyncPeerMock syncPeer, IBlockTree tree) { receiptSyncBatch.Response = new TxReceipt[receiptSyncBatch.Request.Length][]; for (int i = 0; i < receiptSyncBatch.Request.Length; i++) { Block block = tree.FindBlock(receiptSyncBatch.Request[i], false); receiptSyncBatch.Response[i] = new TxReceipt[block.Transactions.Length]; for (int j = 0; j < block.Transactions.Length; j++) { receiptSyncBatch.Response[i][j] = _remoteReceiptStorage.Find(block.Transactions[j].Hash); } } }
public void Two_peers_one_malicious_by_short_at_start() { LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048); LatencySyncPeerMock syncPeer2 = new LatencySyncPeerMock(_validTree2048); _maliciousByShortAtStart.Add(syncPeer1); SetupSyncPeers(syncPeer1, syncPeer2); RunFeed(); Assert.AreEqual(25, _time); AssertTreeSynced(_validTree2048); }
public void Two_peers_one_malicious_by_shift_back() { LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048); LatencySyncPeerMock syncPeer2 = new LatencySyncPeerMock(_validTree2048); _maliciousByShiftedOneBack.Add(syncPeer1); SetupSyncPeers(syncPeer1, syncPeer2); RunFeed(); Assert.AreEqual(25, _time); AssertTreeSynced(_validTree2048); }
public void Two_peers_one_timing_out() { LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048); LatencySyncPeerMock syncPeer2 = new LatencySyncPeerMock(_validTree2048); _timingOut.Add(syncPeer1); SetupSyncPeers(syncPeer1, syncPeer2); RunFeed(20000); Assert.AreEqual(5007, _time); AssertTreeSynced(_validTree2048); }
public void Two_peers_one_sending_too_long_messages() { LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048); LatencySyncPeerMock syncPeer2 = new LatencySyncPeerMock(_validTree2048); _incorrectByTooLongMessages.Add(syncPeer1); SetupSyncPeers(syncPeer1, syncPeer2); RunFeed(); Assert.AreEqual(25, _time); AssertTreeSynced(_validTree2048); }
private FastBlocksBatch CreateResponse(LatencySyncPeerMock syncPeer) { if (!_pendingResponses.ContainsKey(syncPeer)) { TestContext.WriteLine($"{_time,6} |SYNC PEER {syncPeer.Node:s} WAKES UP"); syncPeer.IsReported = false; return(null); } FastBlocksBatch responseBatch = _pendingResponses[syncPeer]; IBlockTree tree = _peerTrees[syncPeer]; _pendingResponses.Remove(syncPeer); if (_timingOut.Contains(syncPeer)) { TestContext.WriteLine($"{_time,6} |SYNC PEER {syncPeer.Node:s} TIMED OUT"); // timeout punishment syncPeer.BusyUntil = _time + 5000; syncPeer.IsReported = true; return(responseBatch); } TestContext.WriteLine($"{_time,6} |SYNC PEER {syncPeer.Node:s} RESPONDING TO {responseBatch}"); switch (responseBatch.BatchType) { case FastBlocksBatchType.None: break; case FastBlocksBatchType.Headers: var headersSyncBatch = responseBatch.Headers; PrepareHeadersResponse(headersSyncBatch, syncPeer, tree); break; case FastBlocksBatchType.Bodies: var bodiesSyncBatch = responseBatch.Bodies; PrepareBodiesResponse(bodiesSyncBatch, syncPeer, tree); break; case FastBlocksBatchType.Receipts: var receiptSyncBatch = responseBatch.Receipts; PrepareReceiptsResponse(receiptSyncBatch, syncPeer, tree); break; default: throw new ArgumentOutOfRangeException(); } return(responseBatch); }
public void Shorter_responses() { LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048); SetupSyncPeers(syncPeer1); _incorrectByTooShortMessages.Add(syncPeer1); RunFeed(); Assert.AreEqual(240, _time); AssertTreeSynced(_validTree2048); }
public void Two_peers_one_sending_too_short_messages_bodies() { LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048); LatencySyncPeerMock syncPeer2 = new LatencySyncPeerMock(_validTree2048); _incorrectByTooShortMessages.Add(syncPeer1); SetupFeed(true); SetupSyncPeers(syncPeer1, syncPeer2); RunFeed(); Assert.AreEqual(120, _time); AssertTreeSynced(_validTree2048, true); }
public void Two_peers_one_malicious_by_invalid_ommers() { LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048); LatencySyncPeerMock syncPeer2 = new LatencySyncPeerMock(_validTree2048); _maliciousByInvalidOmmers.Add(syncPeer1); SetupFeed(true); SetupSyncPeers(syncPeer1, syncPeer2); RunFeed(); Assert.AreEqual(38, _time); AssertTreeSynced(_validTree2048, true); }
public void Two_peers_one_malicious_by_shift_forward_bodies() { LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048); LatencySyncPeerMock syncPeer2 = new LatencySyncPeerMock(_validTree2048); _maliciousByShiftedOneForward.Add(syncPeer1); SetupFeed(true); SetupSyncPeers(syncPeer1, syncPeer2); RunFeed(); Assert.AreEqual(49, _time); AssertTreeSynced(_validTree2048, true); }
private void PrepareBodiesResponse(BodiesSyncBatch bodiesSyncBatch, LatencySyncPeerMock syncPeer, IBlockTree tree) { int requestSize = bodiesSyncBatch.Request.Length; int responseSize = bodiesSyncBatch.Request.Length; if (_incorrectByTooLongMessages.Contains(syncPeer)) { responseSize *= 2; TestContext.WriteLine($"{_time,6} | SYNC PEER {syncPeer.Node:s} WILL SEND TOO LONG MESSAGE ({responseSize} INSTEAD OF {requestSize})"); } else if (_incorrectByTooShortMessages.Contains(syncPeer)) { responseSize = Math.Max(1, responseSize / 2); TestContext.WriteLine($"{_time,6} | SYNC PEER {syncPeer.Node:s} WILL SEND TOO SHORT MESSAGE ({responseSize} INSTEAD OF {requestSize})"); } bodiesSyncBatch.Response = new BlockBody[responseSize]; int maxResponseSize = _peerMaxResponseSizes.ContainsKey(syncPeer) ? Math.Min(responseSize, _peerMaxResponseSizes[syncPeer]) : responseSize; for (int i = 0; i < Math.Min(maxResponseSize, requestSize); i++) { Block block = tree.FindBlock(bodiesSyncBatch.Request[i], BlockTreeLookupOptions.None); bodiesSyncBatch.Response[i] = new BlockBody(block.Transactions, block.Ommers); } if (_maliciousByShortAtStart.Contains(syncPeer)) { bodiesSyncBatch.Response[0] = null; TestContext.WriteLine($"{_time,6} | SYNC PEER {syncPeer.Node:s} WILL SEND A MALICIOUS (SHORT AT START) MESSAGE"); } if (_maliciousByInvalidTxs.Contains(syncPeer)) { for (int i = 0; i < bodiesSyncBatch.Response.Length; i++) { BlockBody valid = bodiesSyncBatch.Response[i]; bodiesSyncBatch.Response[i] = new BlockBody(new[] { Build.A.Transaction.WithData(Bytes.FromHexString("bad")).TestObject }, valid.Ommers); } } if (_maliciousByInvalidOmmers.Contains(syncPeer)) { for (int i = 0; i < bodiesSyncBatch.Response.Length; i++) { BlockBody valid = bodiesSyncBatch.Response[i]; bodiesSyncBatch.Response[i] = new BlockBody(valid.Transactions, new[] { Build.A.BlockHeader.WithAuthor(new Address(Keccak.Compute("bad_ommer").Bytes.Take(20).ToArray())).TestObject }); } } }
public void One_valid_one_malicious_with_receipts_and_one_restart() { LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048, 300); LatencySyncPeerMock syncPeer2 = new LatencySyncPeerMock(_validTree2048); SetupFeed(true, true); _maliciousByInvalidReceipts.Add(syncPeer2); SetupSyncPeers(syncPeer1, syncPeer2); RunFeed(5000); // Assert.AreEqual(2116, _time); AssertTreeSynced(_validTree2048, true, true); }
public void Two_valid_one_slower_with_receipts_and_one_restart() { LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048, 300); LatencySyncPeerMock syncPeer2 = new LatencySyncPeerMock(_validTree2048); SetupFeed(true, true); SetupSyncPeers(syncPeer1, syncPeer2); _scheduledActions[906] = ResetAndStartNewRound; RunFeed(5000); // Assert.AreEqual(2116, _time); AssertTreeSynced(_validTree2048, true, true); }
public void Two_peers_with_valid_chain_and_various_max_response_sizes() { LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048); LatencySyncPeerMock syncPeer2 = new LatencySyncPeerMock(_validTree2048); _peerMaxResponseSizes[syncPeer1] = 100; _peerMaxResponseSizes[syncPeer2] = 75; SetupSyncPeers(syncPeer1, syncPeer2); RunFeed(); Assert.AreEqual(85, _time); AssertTreeSynced(_validTree2048); }
public void Short_chain_bodies() { LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048); LatencySyncPeerMock syncPeer2 = new LatencySyncPeerMock(_validTree1024); SetupSyncPeers(syncPeer1, syncPeer2); SetupFeed(true); _syncConfig.PivotHash = _validTree8.Head.Hash.Bytes.ToHexString(); _syncConfig.PivotNumber = _validTree8.Head.Number.ToString(); _syncConfig.PivotTotalDifficulty = _validTree8.Head.Difficulty.ToString(); RunFeed(); Assert.AreEqual(12, _time); AssertTreeSynced(_validTree8, true); }
private void PrepareReceiptsResponse(ReceiptsSyncBatch receiptSyncBatch, LatencySyncPeerMock syncPeer, IBlockTree tree) { receiptSyncBatch.Response = new TxReceipt[receiptSyncBatch.Request.Length][]; for (int i = 0; i < receiptSyncBatch.Request.Length; i++) { Block block = tree.FindBlock(receiptSyncBatch.Request[i], BlockTreeLookupOptions.None); receiptSyncBatch.Response[i] = new TxReceipt[block.Transactions.Length]; for (int j = 0; j < block.Transactions.Length; j++) { receiptSyncBatch.Response[i][j] = _remoteReceiptStorage.Find(block.Transactions[j].Hash); if (i < 10 && j == 0 && _maliciousByInvalidReceipts.Contains(syncPeer)) { receiptSyncBatch.Response[i][j] = new TxReceipt(); receiptSyncBatch.Response[i][j].StatusCode = (byte)(1 - receiptSyncBatch.Response[i][j].StatusCode); receiptSyncBatch.Response[i][j].PostTransactionState = Keccak.Compute(receiptSyncBatch.Response[i][j].PostTransactionState?.Bytes ?? new byte[] { 1 }); } } } }
public void Setup() { _localReceiptStorage = new InMemoryReceiptStorage(); _syncPeers = new List <LatencySyncPeerMock>(); _peerTrees = new Dictionary <LatencySyncPeerMock, IBlockTree>(); _peerMaxResponseSizes = new Dictionary <LatencySyncPeerMock, int>(); _pendingResponses = new Dictionary <LatencySyncPeerMock, FastBlocksBatch>(); _invalidBlocks = new Dictionary <LatencySyncPeerMock, HashSet <long> >(); _maliciousByRepetition = new HashSet <LatencySyncPeerMock>(); _maliciousByInvalidTxs = new HashSet <LatencySyncPeerMock>(); _maliciousByInvalidOmmers = new HashSet <LatencySyncPeerMock>(); _maliciousByShiftedOneForward = new HashSet <LatencySyncPeerMock>(); _maliciousByShiftedOneBack = new HashSet <LatencySyncPeerMock>(); _maliciousByShortAtStart = new HashSet <LatencySyncPeerMock>(); _maliciousByInvalidReceipts = new HashSet <LatencySyncPeerMock>(); _incorrectByTooShortMessages = new HashSet <LatencySyncPeerMock>(); _incorrectByTooLongMessages = new HashSet <LatencySyncPeerMock>(); _timingOut = new HashSet <LatencySyncPeerMock>(); _scheduledActions = new Dictionary <long, Action>(); LatencySyncPeerMock.RemoteIndex = 1; _time = 0; _syncPeerPool = Substitute.For <IEthSyncPeerPool>(); _syncPeerPool.WhenForAnyArgs(p => p.ReportNoSyncProgress(Arg.Any <SyncPeerAllocation>())) .Do(ci => { LatencySyncPeerMock mock = ((LatencySyncPeerMock)ci.Arg <SyncPeerAllocation>().Current.SyncPeer); mock.BusyUntil = _time + 5000; mock.IsReported = true; }); _syncPeerPool.WhenForAnyArgs(p => p.ReportNoSyncProgress(Arg.Any <PeerInfo>())) .Do(ci => { LatencySyncPeerMock mock = ((LatencySyncPeerMock)ci.Arg <PeerInfo>().SyncPeer); mock.BusyUntil = _time + 5000; mock.IsReported = true; }); _syncPeerPool.WhenForAnyArgs(p => p.ReportInvalid(Arg.Any <SyncPeerAllocation>())) .Do(ci => { LatencySyncPeerMock mock = ((LatencySyncPeerMock)ci.Arg <SyncPeerAllocation>().Current.SyncPeer); mock.BusyUntil = _time + 30000; mock.IsReported = true; }); _syncPeerPool.WhenForAnyArgs(p => p.ReportInvalid(Arg.Any <PeerInfo>())) .Do(ci => { LatencySyncPeerMock mock = ((LatencySyncPeerMock)ci.Arg <PeerInfo>().SyncPeer); mock.BusyUntil = _time + 30000; mock.IsReported = true; }); _syncPeerPool.AllPeers.Returns((ci) => _syncPeers.Select(sp => new PeerInfo(sp) { HeadNumber = sp.Tree.Head.Number })); _syncConfig = new SyncConfig(); _syncConfig.PivotHash = _validTree2048.Head.Hash.ToString(); _syncConfig.PivotNumber = _validTree2048.Head.Number.ToString(); _syncConfig.PivotTotalDifficulty = _validTree2048.Head.TotalDifficulty.ToString(); SetupLocalTree(); SetupFeed(); }