コード例 #1
0
        public void Can_accept_blocks_that_are_fine()
        {
            Context   ctx             = new();
            BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject;
            BlockTree localBlockTree  = Build.A.BlockTree().OfChainLength(9).TestObject;

            ctx.SyncServer = new SyncServer(
                new MemDb(),
                new MemDb(),
                localBlockTree,
                NullReceiptStorage.Instance,
                Always.Valid,
                Always.Valid,
                ctx.PeerPool,
                StaticSelector.Full,
                new SyncConfig(),
                NullWitnessCollector.Instance,
                Policy.FullGossip,
                MainnetSpecProvider.Instance,
                LimboLogs.Instance);

            Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            ctx.SyncServer.AddNewBlock(block, ctx.NodeWhoSentTheBlock);

            Assert.AreEqual(localBlockTree.BestSuggestedHeader, block.Header);
        }
コード例 #2
0
        public void Can_accept_new_valid_blocks(bool sealOk, bool validationOk, bool accepted)
        {
            BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject;
            BlockTree localBlockTree  = Build.A.BlockTree().OfChainLength(9).TestObject;

            ISealValidator  sealValidator  = sealOk ? Always.Valid : Always.Invalid;
            IBlockValidator blockValidator = validationOk ? Always.Valid : Always.Invalid;

            _syncServer = new SyncServer(new StateDb(), new StateDb(), localBlockTree, NullReceiptStorage.Instance, blockValidator, sealValidator, _peerPool, StaticSelector.Full, new SyncConfig(), LimboLogs.Instance);

            Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            if (!accepted)
            {
                Assert.Throws <EthSyncException>(() => _syncServer.AddNewBlock(block, _nodeWhoSentTheBlock));
            }
            else
            {
                _syncServer.AddNewBlock(block, _nodeWhoSentTheBlock);
            }

            if (accepted)
            {
                Assert.AreEqual(localBlockTree.BestSuggestedHeader, block.Header);
            }
            else
            {
                Assert.AreNotEqual(localBlockTree.BestSuggestedHeader, block.Header);
            }
        }
コード例 #3
0
        public void Rejects_new_old_blocks()
        {
            Context   ctx             = new();
            BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject;
            BlockTree localBlockTree  = Build.A.BlockTree().OfChainLength(600).TestObject;

            ISealValidator sealValidator = Substitute.For <ISealValidator>();

            ctx.SyncServer = new SyncServer(
                new MemDb(),
                new MemDb(),
                localBlockTree,
                NullReceiptStorage.Instance,
                Always.Valid,
                sealValidator,
                ctx.PeerPool,
                StaticSelector.Full,
                new SyncConfig(),
                NullWitnessCollector.Instance,
                Policy.FullGossip,
                MainnetSpecProvider.Instance,
                LimboLogs.Instance);

            Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            ctx.SyncServer.AddNewBlock(block, ctx.NodeWhoSentTheBlock);

            sealValidator.DidNotReceive().ValidateSeal(Arg.Any <BlockHeader>(), Arg.Any <bool>());
        }
コード例 #4
0
        public void Fake_total_difficulty_from_peer_does_not_trick_the_node(long ttd)
        {
            BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject;
            BlockTree localBlockTree  = Build.A.BlockTree().OfChainLength(9).TestObject;
            Context   ctx             = CreateMergeContext(localBlockTree, (UInt256)ttd);

            Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            block.Header.TotalDifficulty *= 2;

            ctx.SyncServer.AddNewBlock(block, ctx.NodeWhoSentTheBlock);
            Assert.AreEqual(localBlockTree.BestSuggestedHeader !.Hash, block.Header.Hash);

            Block parentBlock = remoteBlockTree.FindBlock(8, BlockTreeLookupOptions.None);

            Assert.AreEqual(parentBlock.TotalDifficulty + block.Difficulty, localBlockTree.BestSuggestedHeader.TotalDifficulty);
        }
コード例 #5
0
        public void Will_not_reject_block_with_bad_total_diff_but_will_reset_diff_to_null()
        {
            Context   ctx             = new();
            BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject;
            BlockTree localBlockTree  = Build.A.BlockTree().OfChainLength(9).TestObject;

            HeaderValidator headerValidator = new(
                localBlockTree,
                Always.Valid,
                MainnetSpecProvider.Instance,
                LimboLogs.Instance);

            BlockValidator blockValidator = new(
                Always.Valid,
                headerValidator,
                Always.Valid,
                MainnetSpecProvider.Instance,
                LimboLogs.Instance);

            ctx.SyncServer = new SyncServer(
                new MemDb(),
                new MemDb(),
                localBlockTree,
                NullReceiptStorage.Instance,
                blockValidator,
                Always.Valid,
                ctx.PeerPool,
                StaticSelector.Full,
                new SyncConfig(),
                NullWitnessCollector.Instance,
                Policy.FullGossip,
                MainnetSpecProvider.Instance,
                LimboLogs.Instance);

            Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            block.Header.TotalDifficulty *= 2;

            ctx.SyncServer.AddNewBlock(block, ctx.NodeWhoSentTheBlock);
            Assert.AreEqual(localBlockTree.BestSuggestedHeader !.Hash, block.Header.Hash);

            Block parentBlock = remoteBlockTree.FindBlock(8, BlockTreeLookupOptions.None);

            Assert.AreEqual(parentBlock.TotalDifficulty + block.Difficulty, localBlockTree.BestSuggestedHeader.TotalDifficulty);
        }
コード例 #6
0
        public void Will_not_reject_block_with_bad_total_diff_but_will_reset_diff_to_null()
        {
            BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject;
            BlockTree localBlockTree  = Build.A.BlockTree().OfChainLength(9).TestObject;

            _syncServer = new SyncServer(new StateDb(), new StateDb(), localBlockTree, NullReceiptStorage.Instance, new BlockValidator(Always.Valid, new HeaderValidator(localBlockTree, Always.Valid, MainnetSpecProvider.Instance, LimboLogs.Instance), Always.Valid, MainnetSpecProvider.Instance, LimboLogs.Instance), Always.Valid, _peerPool, StaticSelector.Full, new SyncConfig(), LimboLogs.Instance);

            Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            block.Header.TotalDifficulty *= 2;

            _syncServer.AddNewBlock(block, _nodeWhoSentTheBlock);
            Assert.AreEqual(localBlockTree.BestSuggestedHeader.Hash, block.Header.Hash);

            Block parentBlock = remoteBlockTree.FindBlock(8, BlockTreeLookupOptions.None);

            Assert.AreEqual(parentBlock.TotalDifficulty + block.Difficulty, localBlockTree.BestSuggestedHeader.TotalDifficulty);
        }
コード例 #7
0
        public void Terminal_block_with_lower_td_should_not_change_best_suggested_but_should_be_added_to_block_tree()
        {
            Context          ctx              = new();
            BlockTree        remoteBlockTree  = Build.A.BlockTree().OfChainLength(10).TestObject;
            BlockTree        localBlockTree   = Build.A.BlockTree().OfChainLength(9).TestObject;
            TestSpecProvider testSpecProvider = new(London.Instance);

            testSpecProvider.TerminalTotalDifficulty = 10_000_000;

            Block newBestLocalBlock = Build.A.Block.WithNumber(localBlockTree.Head !.Number + 1).WithParent(localBlockTree.Head !).WithDifficulty(10_000_002L).TestObject;

            localBlockTree.SuggestBlock(newBestLocalBlock);

            PoSSwitcher poSSwitcher         = new(new MergeConfig()
            {
                Enabled = true
            }, new SyncConfig(), new MemDb(), localBlockTree, testSpecProvider, LimboLogs.Instance);
            HeaderValidator headerValidator = new(
                localBlockTree,
                Always.Valid,
                testSpecProvider,
                LimboLogs.Instance);

            MergeHeaderValidator mergeHeaderValidator = new(poSSwitcher, headerValidator, localBlockTree, testSpecProvider, Always.Valid, LimboLogs.Instance);
            BlockValidator       blockValidator       = new(
                Always.Valid,
                mergeHeaderValidator,
                Always.Valid,
                MainnetSpecProvider.Instance,
                LimboLogs.Instance);

            ctx.SyncServer = new SyncServer(
                new MemDb(),
                new MemDb(),
                localBlockTree,
                NullReceiptStorage.Instance,
                blockValidator,
                Always.Valid,
                ctx.PeerPool,
                StaticSelector.Full,
                new SyncConfig(),
                NullWitnessCollector.Instance,
                Policy.FullGossip,
                testSpecProvider,
                LimboLogs.Instance);

            Block remoteBestBlock = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            ctx.SyncServer.AddNewBlock(remoteBestBlock, ctx.NodeWhoSentTheBlock);
            Assert.AreEqual(newBestLocalBlock.Header.Hash, localBlockTree.BestSuggestedHeader !.Hash);
            Assert.AreEqual(remoteBestBlock.Hash, localBlockTree.FindBlock(remoteBestBlock.Hash, BlockTreeLookupOptions.None) !.Hash);
        }
コード例 #8
0
        public void Can_accept_blocks_that_are_fine()
        {
            BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject;
            BlockTree localBlockTree  = Build.A.BlockTree().OfChainLength(9).TestObject;

            _syncServer = new SyncServer(new StateDb(), new StateDb(), localBlockTree, NullReceiptStorage.Instance, Always.Valid, Always.Valid, _peerPool, StaticSelector.Full, new SyncConfig(), LimboLogs.Instance);

            Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            _syncServer.AddNewBlock(block, _nodeWhoSentTheBlock);

            Assert.AreEqual(localBlockTree.BestSuggestedHeader, block.Header);
        }
コード例 #9
0
        public void Rejects_new_old_blocks()
        {
            BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject;
            BlockTree localBlockTree  = Build.A.BlockTree().OfChainLength(600).TestObject;

            ISealValidator sealValidator = Substitute.For <ISealValidator>();

            _syncServer = new SyncServer(new StateDb(), new StateDb(), localBlockTree, NullReceiptStorage.Instance, Always.Valid, sealValidator, _peerPool, StaticSelector.Full, new SyncConfig(), LimboLogs.Instance);

            Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            _syncServer.AddNewBlock(block, _nodeWhoSentTheBlock);

            sealValidator.DidNotReceive().ValidateSeal(Arg.Any <BlockHeader>(), Arg.Any <bool>());
        }
コード例 #10
0
        public void Can_reject_block_POW_block_after_TTD(long ttd, bool sendFakeTd)
        {
            BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject;
            BlockTree localBlockTree  = Build.A.BlockTree().OfChainLength(9).TestObject;
            Context   ctx             = CreateMergeContext(localBlockTree, (UInt256)ttd);

            Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            if (sendFakeTd)
            {
                block.Header.TotalDifficulty *= 2;
            }

            Assert.Throws <EthSyncException>(() => ctx.SyncServer.AddNewBlock(block, ctx.NodeWhoSentTheBlock));
            Assert.AreEqual(localBlockTree.BestSuggestedHeader !.Number, 8);
        }
コード例 #11
0
        public void Can_accept_new_valid_blocks(bool sealOk, bool validationOk, bool accepted)
        {
            Context   ctx             = new();
            BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject;
            BlockTree localBlockTree  = Build.A.BlockTree().OfChainLength(9).TestObject;

            ISealValidator  sealValidator  = sealOk ? Always.Valid : Always.Invalid;
            IBlockValidator blockValidator = validationOk ? Always.Valid : Always.Invalid;

            ctx.SyncServer = new SyncServer(
                new MemDb(),
                new MemDb(),
                localBlockTree,
                NullReceiptStorage.Instance,
                blockValidator,
                sealValidator,
                ctx.PeerPool,
                StaticSelector.Full,
                new SyncConfig(),
                NullWitnessCollector.Instance,
                Policy.FullGossip,
                MainnetSpecProvider.Instance,
                LimboLogs.Instance);

            Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            if (!accepted)
            {
                Assert.Throws <EthSyncException>(() => ctx.SyncServer.AddNewBlock(block, ctx.NodeWhoSentTheBlock));
            }
            else
            {
                ctx.SyncServer.AddNewBlock(block, ctx.NodeWhoSentTheBlock);
            }

            if (accepted)
            {
                Assert.AreEqual(localBlockTree.BestSuggestedHeader, block.Header);
            }
            else
            {
                Assert.AreNotEqual(localBlockTree.BestSuggestedHeader, block.Header);
            }
        }
コード例 #12
0
        public void Post_merge_blocks_wont_be_accepted_by_gossip(long ttd, bool sendFakeTd)
        {
            BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(9).TestObject;
            Block     postMergeBlock  = Build.A.Block.WithDifficulty(0).WithParent(remoteBlockTree.Head).WithTotalDifficulty(remoteBlockTree.Head.TotalDifficulty).WithNonce(0u).TestObject;

            remoteBlockTree.SuggestBlock(postMergeBlock);
            BlockTree localBlockTree = Build.A.BlockTree().OfChainLength(9).TestObject;
            Context   ctx            = CreateMergeContext(localBlockTree, (UInt256)ttd);

            Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            if (sendFakeTd)
            {
                block.Header.TotalDifficulty *= 2;
            }

            ctx.SyncServer.AddNewBlock(block, ctx.NodeWhoSentTheBlock);
            Assert.AreEqual(localBlockTree.BestSuggestedHeader !.Number, 8);
            localBlockTree.FindBlock(postMergeBlock.Hash !, BlockTreeLookupOptions.None).Should().BeNull();
        }
コード例 #13
0
        public void Can_inject_terminal_block_with_higher_td_than_head(long ttd, bool sendFakeTd)
        {
            BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(9).TestObject;
            Block     terminalBlockWithHigherTotalDifficulty = Build.A.Block.WithDifficulty(1000010).WithParent(remoteBlockTree.Head).WithTotalDifficulty(remoteBlockTree.Head.TotalDifficulty + 1000010).TestObject;

            remoteBlockTree.SuggestBlock(terminalBlockWithHigherTotalDifficulty);
            BlockTree localBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject;
            Context   ctx            = CreateMergeContext(localBlockTree, (UInt256)ttd);

            Assert.True(terminalBlockWithHigherTotalDifficulty.IsTerminalBlock(ctx.SpecProvider));

            Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            if (sendFakeTd)
            {
                block.Header.TotalDifficulty *= 2;
            }

            ctx.SyncServer.AddNewBlock(block, ctx.NodeWhoSentTheBlock);
            Assert.AreEqual(localBlockTree.BestSuggestedHeader !.Number, 9);
            localBlockTree.FindBlock(terminalBlockWithHigherTotalDifficulty.Hash !, BlockTreeLookupOptions.None).Should().NotBeNull();
            localBlockTree.BestSuggestedHeader !.Hash.Should().Be(terminalBlockWithHigherTotalDifficulty.Hash !);
        }