public TestContext()
        {
            var chain = new ConcurrentChain(this.Network);
            var extendedLoggerFactory   = new ExtendedLoggerFactory();
            var dateTimeProvider        = new DateTimeProvider();
            var hashStore               = new InvalidBlockHashStore(dateTimeProvider);
            var powConsensusRulesEngine = new PowConsensusRuleEngine(this.Network, extendedLoggerFactory, dateTimeProvider, chain,
                                                                     new NodeDeployments(this.Network, chain), this.ConsensusSettings, this.Checkpoints.Object, new Mock <ICoinView>().Object,
                                                                     this.ChainState.Object, hashStore, new NodeStats(dateTimeProvider));

            this.PartialValidation = new PartialValidator(powConsensusRulesEngine, extendedLoggerFactory);
            this.FullValidation    = new FullValidator(powConsensusRulesEngine, extendedLoggerFactory);
            this.HeaderValidator   = new Mock <IHeaderValidator>();
            this.HeaderValidator.Setup(hv => hv.ValidateHeader(It.IsAny <ChainedHeader>())).Returns(new ValidationContext());

            this.ChainedHeaderTree = new ChainedHeaderTree(
                this.Network,
                extendedLoggerFactory,
                this.HeaderValidator.Object,
                this.Checkpoints.Object,
                this.ChainState.Object,
                this.FinalizedBlockMock.Object,
                this.ConsensusSettings,
                hashStore);

            this.ConsensusManager = CreateConsensusManager();
        }
Exemple #2
0
        public void AllEntriesExpired()
        {
            var invalidBlockHashStore = new InvalidBlockHashStore(DateTimeProvider.Default, 6);

            // Create some hashes that will be banned temporarily, but not after 5 seconds.
            var hashesBannedTemporarily = new uint256[]
            {
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000011"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000012"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000013"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000014"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000015"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000016"),
            };

            foreach (uint256 hash in hashesBannedTemporarily)
            {
                invalidBlockHashStore.MarkInvalid(hash, DateTime.UtcNow.AddMilliseconds(rng.Next(2000, 5000)));
            }

            // Check all hashes are banned now.
            foreach (uint256 hash in hashesBannedTemporarily)
            {
                Assert.True(invalidBlockHashStore.IsInvalid(hash));
            }

            // Wait 5 seconds and touch all the entries, so they are removed from the store's dictionary.
            Thread.Sleep(5000);

            // Check all hashes are no longer banned.
            foreach (uint256 hash in hashesBannedTemporarily)
            {
                Assert.False(invalidBlockHashStore.IsInvalid(hash));
            }

            // Add a new hash, which should remove all the other entries from the store's circular array as well.
            uint256 lastHash = uint256.Parse("0000000000000000000000000000000000000000000000000000000000000031");

            invalidBlockHashStore.MarkInvalid(lastHash);

            // Check all removed hashes are no longer banned.
            foreach (uint256 hash in hashesBannedTemporarily)
            {
                Assert.False(invalidBlockHashStore.IsInvalid(hash));
            }

            // Check the number of entries is now 1.
            var orderedHashList = invalidBlockHashStore.GetMemberValue("orderedHashList") as CircularArray <uint256>;

            Assert.Equal(1, orderedHashList.Count);

            // Check the last entry is banned.
            Assert.True(invalidBlockHashStore.IsInvalid(lastHash));
        }
Exemple #3
0
        public TestContext()
        {
            this.Network = KnownNetworks.RegTest;

            this.chainIndexer     = new ChainIndexer(this.Network);
            this.dateTimeProvider = new DateTimeProvider();
            this.hashStore        = new InvalidBlockHashStore(this.dateTimeProvider);

            this.coinView        = new TestInMemoryCoinView(this.chainIndexer.Tip.HashBlock);
            this.HeaderValidator = new Mock <IHeaderValidator>();
            this.HeaderValidator.Setup(hv => hv.ValidateHeader(It.IsAny <ChainedHeader>())).Returns(new ValidationContext());

            this.nodeLifetime = new NodeLifetime();
            this.ibd          = new Mock <IInitialBlockDownloadState>();
            this.BlockPuller  = new Mock <IBlockPuller>();

            this.BlockPuller.Setup(b => b.Initialize(It.IsAny <BlockPuller.OnBlockDownloadedCallback>()))
            .Callback <BlockPuller.OnBlockDownloadedCallback>((d) => { this.blockPullerBlockDownloadCallback = d; });
            this.BlockStore  = new Mock <IBlockStore>();
            this.checkpoints = new Mock <ICheckpoints>();
            this.ChainState  = new Mock <IChainState>();

            string[] param = new string[] { };
            this.nodeSettings      = new NodeSettings(this.Network, args: param);
            this.ConsensusSettings = new ConsensusSettings(this.nodeSettings);

            this.loggerFactory = this.nodeSettings.LoggerFactory;

            this.nodeStats = new NodeStats(this.dateTimeProvider, this.loggerFactory);

            var connectionSettings = new ConnectionManagerSettings(this.nodeSettings);

            this.selfEndpointTracker       = new SelfEndpointTracker(this.loggerFactory, connectionSettings);
            this.Network.Consensus.Options = new ConsensusOptions();

            this.signals       = new Bitcoin.Signals.Signals(this.loggerFactory, null);
            this.asyncProvider = new AsyncProvider(this.loggerFactory, this.signals, this.nodeLifetime);

            // Dont check PoW of a header in this test.
            this.Network.Consensus.ConsensusRules.HeaderValidationRules.RemoveAll(x => x.GetType() == typeof(CheckDifficultyPowRule));

            this.ChainedHeaderTree = new ChainedHeaderTree(
                this.Network,
                this.loggerFactory,
                this.HeaderValidator.Object,
                this.checkpoints.Object,
                this.ChainState.Object,
                this.FinalizedBlockMock.Object,
                this.ConsensusSettings,
                this.hashStore);

            this.peerAddressManager = new PeerAddressManager(DateTimeProvider.Default, this.nodeSettings.DataFolder, this.loggerFactory, this.selfEndpointTracker);

            this.networkPeerFactory = new NetworkPeerFactory(this.Network,
                                                             this.dateTimeProvider,
                                                             this.loggerFactory, new PayloadProvider().DiscoverPayloads(),
                                                             this.selfEndpointTracker,
                                                             this.ibd.Object,
                                                             new ConnectionManagerSettings(this.nodeSettings),
                                                             this.asyncProvider,
                                                             this.peerAddressManager);

            var peerDiscovery = new PeerDiscovery(this.asyncProvider, this.loggerFactory, this.Network, this.networkPeerFactory, this.nodeLifetime, this.nodeSettings, this.peerAddressManager);

            this.connectionManager = new ConnectionManager(this.dateTimeProvider, this.loggerFactory, this.Network, this.networkPeerFactory, this.nodeSettings,
                                                           this.nodeLifetime, new NetworkPeerConnectionParameters(), this.peerAddressManager, new IPeerConnector[] { },
                                                           peerDiscovery, this.selfEndpointTracker, connectionSettings, new VersionProvider(), this.nodeStats, this.asyncProvider);

            this.deployments = new NodeDeployments(this.Network, this.chainIndexer);

            this.consensusRules = new PowConsensusRuleEngine(this.Network, this.loggerFactory, this.dateTimeProvider, this.chainIndexer, this.deployments, this.ConsensusSettings,
                                                             this.checkpoints.Object, this.coinView, this.ChainState.Object, this.hashStore, this.nodeStats, this.asyncProvider, new ConsensusRulesContainer());

            this.consensusRules.SetupRulesEngineParent();

            var tree = new ChainedHeaderTree(this.Network, this.loggerFactory, this.HeaderValidator.Object, this.checkpoints.Object,
                                             this.ChainState.Object, this.FinalizedBlockMock.Object, this.ConsensusSettings, this.hashStore);

            this.PartialValidator = new Mock <IPartialValidator>();
            this.FullValidator    = new Mock <IFullValidator>();

            this.peerBanning = new PeerBanning(this.connectionManager, this.loggerFactory, this.dateTimeProvider, this.peerAddressManager);

            this.IntegrityValidator.Setup(i => i.VerifyBlockIntegrity(It.IsAny <ChainedHeader>(), It.IsAny <Block>()))
            .Returns(new ValidationContext());

            ConsensusManager consensusManager = new ConsensusManager(tree, this.Network, this.loggerFactory, this.ChainState.Object, this.IntegrityValidator.Object,
                                                                     this.PartialValidator.Object, this.FullValidator.Object, this.consensusRules,
                                                                     this.FinalizedBlockMock.Object, this.signals, this.peerBanning, this.ibd.Object, this.chainIndexer,
                                                                     this.BlockPuller.Object, this.BlockStore.Object, this.connectionManager, this.nodeStats, this.nodeLifetime, this.ConsensusSettings, this.dateTimeProvider);

            this.TestConsensusManager = new TestConsensusManager(consensusManager);
        }
Exemple #4
0
        public void MarkBlockInvalid_PermanentAndTemporaryBans()
        {
            var fullNode = new Mock <IFullNode>();

            fullNode.Setup(f => f.NodeService <IDateTimeProvider>(true))
            .Returns(DateTimeProvider.Default);

            var store = new InvalidBlockHashStore(DateTimeProvider.Default);

            // Create some hashes that will be banned forever.
            var hashesBannedPermanently = new uint256[]
            {
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000001"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000002"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000003"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000004"),
            };

            foreach (uint256 hash in hashesBannedPermanently)
            {
                store.MarkInvalid(hash);
            }

            // Create some hashes that will be banned now, but not in 5 seconds.
            var hashesBannedTemporarily1 = new uint256[]
            {
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000011"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000012"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000013"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000014"),
            };

            foreach (uint256 hash in hashesBannedTemporarily1)
            {
                store.MarkInvalid(hash, DateTime.UtcNow.AddMilliseconds(rng.Next(2000, 5000)));
            }

            // Create some hashes that will be banned now and also after 5 seconds.
            var hashesBannedTemporarily2 = new uint256[]
            {
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000021"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000022"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000023"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000024"),
            };

            foreach (uint256 hash in hashesBannedTemporarily2)
            {
                store.MarkInvalid(hash, DateTime.UtcNow.AddMilliseconds(rng.Next(20000, 50000)));
            }

            // Check that all hashes we have generated are banned now.
            var allHashes = new List <uint256>(hashesBannedPermanently);

            allHashes.AddRange(hashesBannedTemporarily1);
            allHashes.AddRange(hashesBannedTemporarily2);

            foreach (uint256 hash in allHashes)
            {
                Assert.True(store.IsInvalid(hash));
            }

            // Wait 5 seconds and then check if hashes from first temporary group are no longer banned and all others still are.
            Thread.Sleep(5000);

            foreach (uint256 hash in allHashes)
            {
                uint num           = hash.GetLow32();
                bool isSecondGroup = (0x10 <= num) && (num < 0x20);
                Assert.Equal(!isSecondGroup, store.IsInvalid(hash));
            }
        }
        public void ReachingStoreCapacity_RemovesOldestEntries()
        {
            var invalidBlockHashStore = new InvalidBlockHashStore(DateTimeProvider.Default, 10);

            // Create some hashes that will be banned forever.
            var hashesBannedPermanently = new uint256[]
            {
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000001"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000002"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000003"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000004"),
            };

            foreach (uint256 hash in hashesBannedPermanently)
            {
                invalidBlockHashStore.MarkInvalid(hash);
            }

            // Create some hashes that will be banned.
            var hashesBannedTemporarily1 = new uint256[]
            {
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000011"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000012"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000013"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000014"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000015"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000016"),
            };

            foreach (uint256 hash in hashesBannedTemporarily1)
            {
                invalidBlockHashStore.MarkInvalid(hash, DateTime.UtcNow.AddMilliseconds(rng.Next(2000, 5000)));
            }

            // Check that all hashes we have generated are banned now.
            var allHashes = new List <uint256>(hashesBannedPermanently);

            allHashes.AddRange(hashesBannedTemporarily1);

            foreach (uint256 hash in allHashes)
            {
                Assert.True(invalidBlockHashStore.IsInvalid(hash));
            }

            // Add two more hashes that will be banned.
            var hashesBannedTemporarily2 = new uint256[]
            {
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000031"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000032"),
            };

            foreach (uint256 hash in hashesBannedTemporarily2)
            {
                invalidBlockHashStore.MarkInvalid(hash, DateTime.UtcNow.AddMilliseconds(rng.Next(20000, 50000)));
            }

            // As the capacity is just 10, the first two hashes should no longer be banned at this point.
            Assert.False(invalidBlockHashStore.IsInvalid(hashesBannedPermanently[0]));
            Assert.False(invalidBlockHashStore.IsInvalid(hashesBannedPermanently[1]));

            // And all other hashes are still banned.
            var allBannedHashes = new List <uint256>();

            allBannedHashes.Add(hashesBannedPermanently[2]);
            allBannedHashes.Add(hashesBannedPermanently[3]);
            allBannedHashes.AddRange(hashesBannedTemporarily1);
            allBannedHashes.AddRange(hashesBannedTemporarily2);

            foreach (uint256 hash in allBannedHashes)
            {
                Assert.True(invalidBlockHashStore.IsInvalid(hash));
            }
        }
        public void ReachingStoreCapacity_CircularArraySkipsExpiredEntries()
        {
            var invalidBlockHashStore = new InvalidBlockHashStore(DateTimeProvider.Default, 10);

            // Create some hashes that will be banned forever.
            var hashesBannedPermanently1 = new uint256[]
            {
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000001"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000002"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000003"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000004"),
            };

            foreach (uint256 hash in hashesBannedPermanently1)
            {
                invalidBlockHashStore.MarkInvalid(hash);
            }

            // Create some hashes that will be banned temporarily, but not after 5 seconds.
            var hashesBannedTemporarily = new uint256[]
            {
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000011"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000012"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000013"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000014"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000015"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000016"),
            };

            foreach (uint256 hash in hashesBannedTemporarily)
            {
                invalidBlockHashStore.MarkInvalid(hash, DateTime.UtcNow.AddMilliseconds(rng.Next(2000, 5000)));
            }

            // Add more forever bans.
            var hashesBannedPermanently2 = new uint256[]
            {
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000021"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000022"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000023"),
                uint256.Parse("0000000000000000000000000000000000000000000000000000000000000024"),
            };

            foreach (uint256 hash in hashesBannedPermanently2)
            {
                invalidBlockHashStore.MarkInvalid(hash);
            }

            // Now check that all hashes from the first group are no longer banned and all others still are.
            var allBannedHashes = new List <uint256>(hashesBannedTemporarily);

            allBannedHashes.AddRange(hashesBannedPermanently2);

            foreach (uint256 hash in hashesBannedPermanently1)
            {
                Assert.False(invalidBlockHashStore.IsInvalid(hash));
            }

            foreach (uint256 hash in allBannedHashes)
            {
                Assert.True(invalidBlockHashStore.IsInvalid(hash));
            }

            // Now we wait 5 seconds and touch the first four temporarily banned hashes,
            // which should remove them from the dictionary.
            Thread.Sleep(5000);

            Assert.False(invalidBlockHashStore.IsInvalid(hashesBannedTemporarily[0]));
            Assert.False(invalidBlockHashStore.IsInvalid(hashesBannedTemporarily[1]));
            Assert.False(invalidBlockHashStore.IsInvalid(hashesBannedTemporarily[2]));
            Assert.False(invalidBlockHashStore.IsInvalid(hashesBannedTemporarily[3]));

            // Then we add a new hash, which should remove the four hashes from the circular array as well.
            invalidBlockHashStore.MarkInvalid(uint256.Parse("0000000000000000000000000000000000000000000000000000000000000031"));

            Assert.Equal(6, invalidBlockHashStore.orderedHashList.Count);
        }