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(); }
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)); }
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); }
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); }