コード例 #1
0
        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);
        }
コード例 #2
0
        public void One_peer_with_valid_chain()
        {
            LatencySyncPeerMock syncPeer = new LatencySyncPeerMock(_validTree2048);

            SetupSyncPeers(syncPeer);
            RunFeed();
            Assert.AreEqual(24, _time);

            AssertTreeSynced(_validTree2048);
        }
コード例 #3
0
        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));
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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];
コード例 #9
0
        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);
        }
コード例 #10
0
 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);
         }
     }
 }
コード例 #11
0
        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);
        }
コード例 #12
0
        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);
        }
コード例 #13
0
        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);
        }
コード例 #14
0
        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);
        }
コード例 #15
0
        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);
        }
コード例 #16
0
        public void Shorter_responses()
        {
            LatencySyncPeerMock syncPeer1 = new LatencySyncPeerMock(_validTree2048);

            SetupSyncPeers(syncPeer1);

            _incorrectByTooShortMessages.Add(syncPeer1);

            RunFeed();

            Assert.AreEqual(240, _time);

            AssertTreeSynced(_validTree2048);
        }
コード例 #17
0
        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);
        }
コード例 #18
0
        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);
        }
コード例 #19
0
        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);
        }
コード例 #20
0
        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 });
                }
            }
        }
コード例 #21
0
        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);
        }
コード例 #22
0
        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);
        }
コード例 #23
0
        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);
        }
コード例 #24
0
        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);
        }
コード例 #25
0
        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 });
                    }
                }
            }
        }
コード例 #26
0
        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();
        }