public void RetrieveDeposits_ReturnsSmallAndNormalDeposits_Scenario5() { // Create a "chain" of 20 blocks. List <ChainedHeaderBlock> blocks = ChainedHeadersHelper.CreateConsecutiveHeadersAndBlocks(20, null, true); // Add 4 small deposits to blocks 5 through to 8 (the amounts are less than 10). for (int i = 5; i <= 8; i++) { blocks[i].Block.AddTransaction(new Transaction()); CreateDepositTransaction(this.targetAddress, blocks[i].Block, Money.Coins(i), this.opReturnBytes); } // Add 6 normal deposits to block 11 through to 16. for (int i = 11; i <= 16; i++) { blocks[i].Block.AddTransaction(new Transaction()); CreateDepositTransaction(this.targetAddress, blocks[i].Block, Money.Coins(i), this.opReturnBytes); } this.consensusManager.GetBlockData(Arg.Any <List <uint256> >()).Returns(delegate(CallInfo info) { var hashes = (List <uint256>)info[0]; return(hashes.Select((hash) => blocks.Single(x => x.ChainedHeader.HashBlock == hash)).ToArray()); }); this.consensusManager.Tip.Returns(blocks.Last().ChainedHeader); var depositExtractor = new DepositExtractor(this.loggerFactory, this.federatedPegSettings, this.opReturnDataReader); var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.federatedPegSettings, this.loggerFactory); SerializableResult <List <MaturedBlockDepositsModel> > depositsResult = maturedBlocksProvider.RetrieveDeposits(10); // Total deposits Assert.Empty(depositsResult.Value.SelectMany(b => b.Deposits)); }
public void GetMaturedBlocksReturnsDeposits() { List <ChainedHeaderBlock> blocks = ChainedHeadersHelper.CreateConsecutiveHeadersAndBlocks(10, null, true); ChainedHeader tip = blocks.Last().ChainedHeader; this.consensusManager.GetBlockData(Arg.Any <List <uint256> >()).Returns(delegate(CallInfo info) { var hashes = (List <uint256>)info[0]; return(hashes.Select((hash) => blocks.Single(x => x.ChainedHeader.HashBlock == hash)).ToArray()); }); IFederatedPegSettings federatedPegSettings = Substitute.For <IFederatedPegSettings>(); federatedPegSettings.MinimumConfirmationsNormalDeposits.Returns(0); var deposits = new List <IDeposit>() { new Deposit(new uint256(0), DepositRetrievalType.Normal, 100, "test", 0, new uint256(1)) }; IDepositExtractor depositExtractor = Substitute.For <IDepositExtractor>(); depositExtractor.ExtractBlockDeposits(blocks.First(), DepositRetrievalType.Normal).ReturnsForAnyArgs(new MaturedBlockDepositsModel(new MaturedBlockInfoModel(), deposits)); this.consensusManager.Tip.Returns(tip); // Makes every block a matured block. var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, federatedPegSettings, this.loggerFactory); SerializableResult <List <MaturedBlockDepositsModel> > depositsResult = maturedBlocksProvider.RetrieveDeposits(0); // This will be double the amount of blocks because the mocked depositExtractor will always return a set of blocks // as that is how it has been configured. Assert.Equal(33, depositsResult.Value.Count); }
public async Task AssignDownloadJobs_PeerThrowsAndHisAssignmentAreReassignedAsync() { INetworkPeer peer1 = this.helper.CreatePeer(out ExtendedBlockPullerBehavior behavior1); INetworkPeer peer2 = this.helper.CreatePeer(out ExtendedBlockPullerBehavior behavior2); behavior2.ShouldThrowAtRequestBlocksAsync = true; this.puller.SetMaxBlocksBeingDownloaded(int.MaxValue); List <ChainedHeader> headers = ChainedHeadersHelper.CreateConsecutiveHeaders(10000); this.puller.NewPeerTipClaimed(peer1, headers.Last()); this.puller.NewPeerTipClaimed(peer2, headers.Last()); this.puller.RequestBlocksDownload(headers); await this.puller.AssignDownloadJobsAsync(); int headersReassignedFromPeer2Count = headers.Count - this.puller.AssignedDownloadsByHash.Values.Count(x => x.PeerId == peer1.Connection.Id); Assert.Single(this.puller.ReassignedJobsQueue); Assert.Empty(this.puller.DownloadJobsQueue); Assert.Equal(headersReassignedFromPeer2Count, this.puller.ReassignedJobsQueue.Peek().Headers.Count); Assert.Single(this.puller.PullerBehaviorsByPeerId); await this.puller.AssignDownloadJobsAsync(); Assert.Empty(this.puller.ReassignedJobsQueue); Assert.Empty(this.puller.DownloadJobsQueue); Assert.Equal(headers.Count, this.puller.AssignedDownloadsByHash.Count); Assert.True(this.puller.AssignedDownloadsByHash.All(x => x.Value.PeerId == peer1.Connection.Id)); this.VerifyAssignedDownloadsSortedOrder(); }
public async Task TotalSpeedOfAllPeersBytesPerSec_CalculatedCorrectlyAsync() { this.puller.SetCallback((hash, block, peerId) => { this.helper.CallbacksCalled.Add(hash, block); }); Assert.Equal(0, this.puller.GetAverageBlockSizeBytes()); Assert.Equal(0, this.puller.GetTotalSpeedOfAllPeersBytesPerSec()); INetworkPeer peer = this.helper.CreatePeer(out ExtendedBlockPullerBehavior behavior); List <ChainedHeader> headers = ChainedHeadersHelper.CreateConsecutiveHeaders(2); this.puller.NewPeerTipClaimed(peer, headers.Last()); this.puller.RequestBlocksDownload(headers); await this.puller.AssignDownloadJobsAsync(); // Make sure job was assigned. foreach (ChainedHeader chainedHeader in headers) { Assert.True(this.puller.AssignedDownloadsByHash.ContainsKey(chainedHeader.HashBlock)); } this.puller.PushBlock(headers[0].HashBlock, this.helper.GenerateBlock(200), behavior.AttachedPeer.Connection.Id); this.puller.PushBlock(headers[1].HashBlock, this.helper.GenerateBlock(400), behavior.AttachedPeer.Connection.Id); double averageSize = this.puller.GetAverageBlockSizeBytes(); Assert.True(this.helper.DoubleEqual(300, averageSize)); }
public void DistributeHeaders_EvenlyDistributed() { INetworkPeer peer1 = this.helper.CreatePeer(out ExtendedBlockPullerBehavior behavior1); INetworkPeer peer2 = this.helper.CreatePeer(out ExtendedBlockPullerBehavior behavior2); List <ChainedHeader> headers = ChainedHeadersHelper.CreateConsecutiveHeaders(10000); behavior1.OverrideQualityScore = behavior2.OverrideQualityScore = 1; this.puller.NewPeerTipClaimed(peer1, headers.Last()); this.puller.NewPeerTipClaimed(peer2, headers.Last()); var job = new DownloadJob() { Headers = new List <ChainedHeader>(headers), Id = 1 }; var failedHashes = new List <uint256>(); List <AssignedDownload> assignedDownloads = this.puller.DistributeHeadersLocked(job, failedHashes, int.MaxValue); Assert.Empty(failedHashes); Assert.Equal(headers.Count, assignedDownloads.Count); int epsilon = Math.Abs(assignedDownloads.Count(x => x.PeerId == peer1.Connection.Id) - assignedDownloads.Count(x => x.PeerId == peer2.Connection.Id)); // Amount of jobs assigned to peer 1 shouldn't be more than 10% different comparing to amount assigned to peer 2. Assert.True(epsilon < headers.Count * 0.1); }
public async Task AssignDownloadJobs_PeerDisconnectedAndJobFailedAsync() { this.puller.SetCallback((hash, block, peerId) => { this.helper.CallbacksCalled.Add(hash, block); }); INetworkPeer peer = this.helper.CreatePeer(out ExtendedBlockPullerBehavior behavior); List <ChainedHeader> headers = ChainedHeadersHelper.CreateConsecutiveHeaders(100); this.puller.NewPeerTipClaimed(peer, headers.Last()); this.puller.RequestBlocksDownload(headers); this.puller.PeerDisconnected(peer.Connection.Id); await this.puller.AssignDownloadJobsAsync(); Assert.Equal(100, this.helper.CallbacksCalled.Count); foreach (ChainedHeader chainedHeader in headers) { Assert.Null(this.helper.CallbacksCalled[chainedHeader.HashBlock]); } Assert.Empty(this.puller.AssignedDownloadsByHash); Assert.Empty(this.puller.DownloadJobsQueue); }
public CoinviewTests() { this.network = new StratisMain(); this.dataFolder = TestBase.CreateDataFolder(this); this.dateTimeProvider = new DateTimeProvider(); this.loggerFactory = new ExtendedLoggerFactory(); this.nodeStats = new NodeStats(this.dateTimeProvider); this.dbreezeCoinview = new DBreezeCoinView(this.network, this.dataFolder, this.dateTimeProvider, this.loggerFactory, this.nodeStats, new DBreezeSerializer(this.network.Consensus.ConsensusFactory)); this.dbreezeCoinview.Initialize(); this.chainIndexer = new ChainIndexer(this.network); this.stakeChainStore = new StakeChainStore(this.network, this.chainIndexer, this.dbreezeCoinview, this.loggerFactory); this.stakeChainStore.Load(); this.rewindDataIndexCache = new RewindDataIndexCache(this.dateTimeProvider, this.network); this.cachedCoinView = new CachedCoinView(this.dbreezeCoinview, this.dateTimeProvider, this.loggerFactory, this.nodeStats, this.stakeChainStore, this.rewindDataIndexCache); this.rewindDataIndexCache.Initialize(this.chainIndexer.Height, this.cachedCoinView); this.random = new Random(); ChainedHeader newTip = ChainedHeadersHelper.CreateConsecutiveHeaders(1000, this.chainIndexer.Tip, true, null, this.network).Last(); this.chainIndexer.SetTip(newTip); }
public async Task RequestBlocksDownload_AssignedPeerThrows_JobIsFailedAndPeerDisconnectedAsync() { this.puller.SetCallback((hash, block, peerId) => { this.helper.CallbacksCalled.Add(hash, block); }); INetworkPeer peer = this.helper.CreatePeer(out ExtendedBlockPullerBehavior behavior); behavior.ShouldThrowAtRequestBlocksAsync = true; List <ChainedHeader> headers = ChainedHeadersHelper.CreateConsecutiveHeaders(5); this.puller.NewPeerTipClaimed(peer, headers.Last()); this.puller.RequestBlocksDownload(headers); Assert.Empty(this.helper.CallbacksCalled); Assert.Single(this.puller.PullerBehaviorsByPeerId); await this.puller.AssignDownloadJobsAsync(); Assert.Empty(this.puller.PullerBehaviorsByPeerId); Assert.Single(this.puller.ReassignedJobsQueue); Assert.Equal(headers.Count, this.puller.ReassignedJobsQueue.Peek().Headers.Count); await this.puller.AssignDownloadJobsAsync(); Assert.Equal(headers.Count, this.helper.CallbacksCalled.Count); // Callbacks are called with null. foreach (ChainedHeader chainedHeader in headers) { Assert.Null(this.helper.CallbacksCalled[chainedHeader.HashBlock]); } }
public async Task GetMaturedBlockDeposits_Fails_When_Block_Not_In_Chain_Async() { FederationGatewayController controller = this.CreateController(); ChainedHeader tip = ChainedHeadersHelper.CreateConsecutiveHeaders(3, null, true)[2]; this.consensusManager.Tip.Returns(tip); IActionResult result = await controller.GetMaturedBlockDepositsAsync(new MaturedBlockRequestModel(1, 1000)).ConfigureAwait(false); result.Should().BeOfType <ErrorResult>(); var error = result as ErrorResult; error.Should().NotBeNull(); var errorResponse = error.Value as ErrorResponse; errorResponse.Should().NotBeNull(); errorResponse.Errors.Should().HaveCount(1); errorResponse.Errors.Should().Contain( e => e.Status == (int)HttpStatusCode.BadRequest); errorResponse.Errors.Should().Contain( e => e.Message.Contains("Unable to get deposits for block at height")); }
public async Task GetMaturedBlockDeposits_Gets_All_Matured_Block_Deposits_Async() { ChainedHeader tip = ChainedHeadersHelper.CreateConsecutiveHeaders(10, null, true).Last(); this.consensusManager.Tip.Returns(tip); FederationGatewayController controller = this.CreateController(); ChainedHeader earlierBlock = tip.GetAncestor(2); int minConfirmations = 2; this.depositExtractor.MinimumDepositConfirmations.Returns((uint)minConfirmations); int depositExtractorCallCount = 0; this.depositExtractor.ExtractBlockDeposits(Arg.Any <ChainedHeaderBlock>()).Returns(new MaturedBlockDepositsModel(null, null)); this.depositExtractor.When(x => x.ExtractBlockDeposits(Arg.Any <ChainedHeaderBlock>())).Do(info => { depositExtractorCallCount++; }); IActionResult result = await controller.GetMaturedBlockDepositsAsync(new MaturedBlockRequestModel(earlierBlock.Height, 1000)).ConfigureAwait(false); result.Should().BeOfType <JsonResult>(); // If the minConfirmations == 0 and this.chain.Height == earlierBlock.Height then expectedCallCount must be 1. int expectedCallCount = (tip.Height - minConfirmations) - earlierBlock.Height + 1; depositExtractorCallCount.Should().Be(expectedCallCount); }
public async Task ProcessGetHeadersAsync_SendsHeadersIfLocatorIsPartiallyOnAForkAsync() { this.helper.CreateAndAttachBehavior(this.headers[100]); List <ChainedHeader> chainBSuffix = ChainedHeadersHelper.CreateConsecutiveHeaders(50, this.headers[55]); var payload = new GetHeadersPayload(new BlockLocator() { Blocks = new List <uint256>() { chainBSuffix.Single(x => x.Height == 90).HashBlock, chainBSuffix.Single(x => x.Height == 60).HashBlock, this.headers[50].HashBlock, this.headers[30].HashBlock, this.headers[10].HashBlock } }); await this.helper.ReceivePayloadAsync(payload); Assert.Single(this.helper.HeadersPayloadsSent); List <BlockHeader> headersSent = this.helper.HeadersPayloadsSent.First().Headers; Assert.Equal(50, headersSent.Count); for (int i = 51; i < 100; i++) { Assert.Equal(this.headers[i].Header, headersSent[i - 51]); } }
public CoinviewTests() { this.network = new StraxMain(); this.dataFolder = TestBase.CreateDataFolder(this); this.dateTimeProvider = new DateTimeProvider(); this.loggerFactory = new ExtendedLoggerFactory(); this.nodeStats = new NodeStats(this.dateTimeProvider, NodeSettings.Default(this.network), new Mock <IVersionProvider>().Object); this.coindb = new DBreezeCoindb(this.network, this.dataFolder, this.dateTimeProvider, this.loggerFactory, this.nodeStats, new DBreezeSerializer(this.network.Consensus.ConsensusFactory)); this.coindb.Initialize(); this.chainIndexer = new ChainIndexer(this.network); this.stakeChainStore = new StakeChainStore(this.network, this.chainIndexer, (IStakedb)this.coindb, this.loggerFactory); this.stakeChainStore.Load(); this.rewindDataIndexCache = new RewindDataIndexCache(this.dateTimeProvider, this.network, new FinalizedBlockInfoRepository(new HashHeightPair()), new Checkpoints()); this.cachedCoinView = new CachedCoinView(this.network, new Checkpoints(), this.coindb, this.dateTimeProvider, this.loggerFactory, this.nodeStats, new ConsensusSettings(new NodeSettings(this.network)), this.stakeChainStore, this.rewindDataIndexCache); this.rewindDataIndexCache.Initialize(this.chainIndexer.Height, this.cachedCoinView); this.random = new Random(); ChainedHeader newTip = ChainedHeadersHelper.CreateConsecutiveHeaders(1000, this.chainIndexer.Tip, true, null, this.network).Last(); this.chainIndexer.SetTip(newTip); }
public void GetMaturedBlocksReturnsDeposits() { this.blocks = ChainedHeadersHelper.CreateConsecutiveHeadersAndBlocks(10, true, this.mainChainNetwork); ChainedHeader tip = this.blocks.Last().ChainedHeader; IFederatedPegSettings federatedPegSettings = Substitute.For <IFederatedPegSettings>(); federatedPegSettings.MinimumConfirmationsNormalDeposits.Returns(0); var deposits = new List <IDeposit>() { new Deposit(new uint256(0), DepositRetrievalType.Normal, 100, "test", 0, new uint256(1)) }; // Set the first block up to return 100 normal deposits. IDepositExtractor depositExtractor = Substitute.For <IDepositExtractor>(); depositExtractor.ExtractDepositsFromBlock(this.blocks.First().Block, this.blocks.First().ChainedHeader.Height, new[] { DepositRetrievalType.Normal }).ReturnsForAnyArgs(deposits); this.consensusManager.Tip.Returns(tip); // Makes every block a matured block. var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, federatedPegSettings, this.loggerFactory); SerializableResult <List <MaturedBlockDepositsModel> > depositsResult = maturedBlocksProvider.RetrieveDeposits(0); Assert.Equal(11, depositsResult.Value.Count); }
public async Task RetrieveDeposits_ReturnsLargeDeposits_Scenario6_Async() { // Create a "chain" of 20 blocks. this.blocks = ChainedHeadersHelper.CreateConsecutiveHeadersAndBlocks(20, true, this.mainChainNetwork); // Add 4 small deposits to blocks 5 through to 8 (the amounts are less than 10). for (int i = 5; i <= 8; i++) { this.blocks[i].Block.AddTransaction(new Transaction()); CreateDepositTransaction(this.targetAddress, this.blocks[i].Block, Money.Coins(i), this.opReturnBytes); } // Add 6 normal deposits to block 11 through to 16. for (int i = 11; i <= 16; i++) { this.blocks[i].Block.AddTransaction(new Transaction()); CreateDepositTransaction(this.targetAddress, this.blocks[i].Block, Money.Coins(i), this.opReturnBytes); } // Add 6 large deposits to block 11 through to 16. for (int i = 11; i <= 16; i++) { this.blocks[i].Block.AddTransaction(new Transaction()); CreateDepositTransaction(this.targetAddress, this.blocks[i].Block, Money.Coins((long)this.federatedPegSettings.NormalDepositThresholdAmount + 1), this.opReturnBytes); } this.consensusManager.Tip.Returns(this.blocks.Last().ChainedHeader); var depositExtractor = new DepositExtractor(this.conversionRequestRepository, this.federatedPegSettings, this.network, this.opReturnDataReader); var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.federatedPegSettings); SerializableResult <List <MaturedBlockDepositsModel> > depositsResult = await maturedBlocksProvider.RetrieveDepositsAsync(10); // Total deposits Assert.Equal(4, depositsResult.Value.SelectMany(b => b.Deposits).Count()); }
public void CommonTipCalculatedCorrectlyWhenProvidersAreOnDifferentChains() { // Chain that forks at block 12 List <ChainedHeader> altChainHeaders = ChainedHeadersHelper.CreateConsecutiveHeaders(5, this.mainChainHeaders[12]); this.tipsManager.Initialize(this.mainChainHeaders.Last()); var provider1 = new testTipProvider(); var provider2 = new testTipProvider(); var provider3 = new testTipProvider(); this.tipsManager.RegisterTipProvider(provider1); this.tipsManager.RegisterTipProvider(provider2); this.tipsManager.RegisterTipProvider(provider3); this.tipsManager.CommitTipPersisted(provider1, this.mainChainHeaders[15]); this.tipsManager.CommitTipPersisted(provider2, this.mainChainHeaders[15]); this.tipsManager.CommitTipPersisted(provider3, altChainHeaders[4]); Assert.Equal(this.mainChainHeaders[12], this.tipsManager.GetLastCommonTip()); this.tipsManager.CommitTipPersisted(provider3, this.mainChainHeaders[18]); Assert.Equal(this.mainChainHeaders[15], this.tipsManager.GetLastCommonTip()); this.tipsManager.CommitTipPersisted(provider1, altChainHeaders[2]); this.tipsManager.CommitTipPersisted(provider2, altChainHeaders[3]); this.tipsManager.CommitTipPersisted(provider3, altChainHeaders[4]); Assert.Equal(altChainHeaders[2], this.tipsManager.GetLastCommonTip()); }
public async Task RequestBlocksDownload_WhileThereAreNoPeers_JobFailedAsync() { this.puller.SetCallback((hash, block, pereId) => { this.helper.CallbacksCalled.Add(hash, block); }); List <ChainedHeader> headers = ChainedHeadersHelper.CreateConsecutiveHeaders(2); Assert.Empty(this.puller.DownloadJobsQueue); Assert.Empty(this.helper.CallbacksCalled); Assert.False(this.puller.ProcessQueuesSignal.IsSet); this.puller.RequestBlocksDownload(headers); // Headers were added to the jobs queue. Assert.Single(this.puller.DownloadJobsQueue); Assert.Equal(2, this.puller.DownloadJobsQueue.Peek().Headers.Count); Assert.True(this.puller.ProcessQueuesSignal.IsSet); await this.puller.AssignDownloadJobsAsync(); // Callbacks are called with null. foreach (ChainedHeader chainedHeader in headers) { Assert.Null(this.helper.CallbacksCalled[chainedHeader.HashBlock]); } }
public void GetMaturedBlockDeposits_Fails_When_Block_Height_Greater_Than_Minimum_Deposit_Confirmations_Async() { ChainedHeader tip = ChainedHeadersHelper.CreateConsecutiveHeaders(5, null, true).Last(); this.consensusManager.Tip.Returns(tip); // Minimum deposit confirmations : 2 IFederatedPegSettings federatedPegSettings = Substitute.For <IFederatedPegSettings>(); federatedPegSettings.MinimumConfirmationsNormalDeposits.Returns(2); FederationGatewayController controller = this.CreateController(federatedPegSettings); int maturedHeight = (int)(tip.Height - 2); // Back online at block height : 3 // 0 - 1 - 2 - 3 ChainedHeader earlierBlock = tip.GetAncestor(maturedHeight + 1); // Mature height = 2 (Chain header height (4) - Minimum deposit confirmations (2)) IActionResult result = controller.GetMaturedBlockDeposits(earlierBlock.Height); // Block height (3) > Mature height (2) - returns error message var maturedBlockDepositsResult = (result as JsonResult).Value as SerializableResult <List <MaturedBlockDepositsModel> >; maturedBlockDepositsResult.Should().NotBeNull(); maturedBlockDepositsResult.Value.Count().Should().Be(0); Assert.NotNull(maturedBlockDepositsResult.Message); }
public void DistributeHeaders_BetweenTwoPeersWhereOneIsOnADifferentChain() { INetworkPeer peer1 = this.helper.CreatePeer(out ExtendedBlockPullerBehavior behavior1); INetworkPeer peer2 = this.helper.CreatePeer(out ExtendedBlockPullerBehavior behavior2); List <ChainedHeader> peer1Headers = ChainedHeadersHelper.CreateConsecutiveHeaders(10); List <ChainedHeader> peer2Headers = ChainedHeadersHelper.CreateConsecutiveHeaders(5); this.puller.NewPeerTipClaimed(peer1, peer1Headers.Last()); this.puller.NewPeerTipClaimed(peer2, peer2Headers.Last()); var job = new DownloadJob() { Headers = new List <ChainedHeader>(peer1Headers), Id = 1 }; var failedHashes = new List <uint256>(); List <AssignedDownload> assignedDownloads = this.puller.DistributeHeadersLocked(job, failedHashes, int.MaxValue); // Make sure all jobs were assigned to peer 1. foreach (ChainedHeader chainedHeader in peer1Headers) { Assert.True(assignedDownloads.Exists(x => x.Header == chainedHeader)); } Assert.Equal(peer1Headers.Count, assignedDownloads.Count); }
public void OnNextCore_WhenTransactionsMissingInLongestChain_ReturnsThemToTheMempool() { var mempoolValidatorMock = new Mock <IMempoolValidator>(); var loggerFactoryMock = new Mock <ILoggerFactory>(); loggerFactoryMock.Setup(i => i.CreateLogger(It.IsAny <string>())).Returns(new Mock <ILogger>().Object); Signals.Signals signals = new Signals.Signals(); var subject = new BlocksDisconnectedSignaled(mempoolValidatorMock.Object, new MempoolSchedulerLock(), loggerFactoryMock.Object, signals); subject.Initialize(); var block = new Block(); var genesisChainedHeaderBlock = new ChainedHeaderBlock(block, ChainedHeadersHelper.CreateGenesisChainedHeader()); var transaction1 = new Transaction(); var transaction2 = new Transaction(); block.Transactions = new List <Transaction> { transaction1, transaction2 }; signals.OnBlockDisconnected.Notify(genesisChainedHeaderBlock); mempoolValidatorMock.Verify(x => x.AcceptToMemoryPool(It.IsAny <MempoolValidationState>(), transaction1)); mempoolValidatorMock.Verify(x => x.AcceptToMemoryPool(It.IsAny <MempoolValidationState>(), transaction2)); }
public void DistributeHeaders_DownloadsAreDistributedAccordingToQualityScore() { INetworkPeer peer1 = this.helper.CreatePeer(out ExtendedBlockPullerBehavior behavior1); INetworkPeer peer2 = this.helper.CreatePeer(out ExtendedBlockPullerBehavior behavior2); behavior1.OverrideQualityScore = 1; behavior2.OverrideQualityScore = 0.1; List <ChainedHeader> headers = ChainedHeadersHelper.CreateConsecutiveHeaders(10000); this.puller.NewPeerTipClaimed(peer1, headers.Last()); this.puller.NewPeerTipClaimed(peer2, headers.Last()); var job = new DownloadJob() { Headers = new List <ChainedHeader>(headers), Id = 1 }; var failedHashes = new List <uint256>(); List <AssignedDownload> assignedDownloads = this.puller.DistributeHeadersLocked(job, failedHashes, int.MaxValue); double margin = (double)assignedDownloads.Count(x => x.PeerId == peer1.Connection.Id) / assignedDownloads.Count(x => x.PeerId == peer2.Connection.Id); // Peer A is expected to get 10 times more than peer B. 8 is used to avoid false alarms when randomization is too lucky. Assert.True(margin > 8); }
public async Task PushBlock_ByPeerThatWereNotAssignedToIt_NothingHappensAsync() { INetworkPeer peer1 = this.helper.CreatePeer(out ExtendedBlockPullerBehavior behavior1); INetworkPeer peer2 = this.helper.CreatePeer(out ExtendedBlockPullerBehavior behavior2); List <ChainedHeader> peer1Headers = ChainedHeadersHelper.CreateConsecutiveHeaders(2); List <ChainedHeader> peer2Headers = ChainedHeadersHelper.CreateConsecutiveHeaders(2); this.puller.NewPeerTipClaimed(peer1, peer1Headers.Last()); this.puller.NewPeerTipClaimed(peer2, peer2Headers.Last()); this.puller.RequestBlocksDownload(peer1Headers); await this.puller.AssignDownloadJobsAsync(); this.puller.PushBlock(peer1Headers.First().HashBlock, this.helper.GenerateBlock(100), peer2.Connection.Id); foreach (ChainedHeader chainedHeader in this.puller.AssignedHeadersByPeerId[peer1.Connection.Id]) { Assert.Contains(chainedHeader, peer1Headers); } Assert.Empty(this.helper.CallbacksCalled); Assert.Equal(peer1Headers.Count, this.puller.AssignedDownloadsByHash.Count); }
public async Task RetrieveDeposits_ReturnsSmallAndNormalDeposits_Scenario3_Async() { // Create a "chain" of 30 blocks. this.blocks = ChainedHeadersHelper.CreateConsecutiveHeadersAndBlocks(30, true, this.mainChainNetwork); // Add 6 small deposits to blocks 8 through to 13 (the amounts are less than 10). for (int i = 8; i <= 13; i++) { this.blocks[i].Block.AddTransaction(new Transaction()); CreateDepositTransaction(this.targetAddress, this.blocks[i].Block, Money.Coins(8), this.opReturnBytes); } // Add 5 normal deposits to block 11 through to 15. for (int i = 11; i <= 15; i++) { this.blocks[i].Block.AddTransaction(new Transaction()); CreateDepositTransaction(this.targetAddress, this.blocks[i].Block, Money.Coins(i), this.opReturnBytes); } this.consensusManager.Tip.Returns(this.blocks.Last().ChainedHeader); var depositExtractor = new DepositExtractor(this.conversionRequestRepository, this.federatedPegSettings, this.network, this.opReturnDataReader); var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.federatedPegSettings); SerializableResult <List <MaturedBlockDepositsModel> > depositsResult = await maturedBlocksProvider.RetrieveDepositsAsync(5); // Total deposits Assert.Equal(11, depositsResult.Value.SelectMany(b => b.Deposits).Count()); // Small Deposits Assert.Equal(6, depositsResult.Value.SelectMany(b => b.Deposits).Where(d => d.RetrievalType == DepositRetrievalType.Small).Count()); // Normal Deposits Assert.Equal(5, depositsResult.Value.SelectMany(b => b.Deposits).Where(d => d.RetrievalType == DepositRetrievalType.Normal).Count()); }
public async Task Stalling_DoesntAffectPeersThatFailedToDeliverNotImportantBlocksAsync() { this.puller.SetCallback((hash, block, peerId) => { this.helper.CallbacksCalled.Add(hash, block); }); INetworkPeer peer1 = this.helper.CreatePeer(out ExtendedBlockPullerBehavior behavior1); INetworkPeer peer2 = this.helper.CreatePeer(out ExtendedBlockPullerBehavior behavior2); this.puller.SetMaxBlocksBeingDownloaded(int.MaxValue); List <ChainedHeader> headers = ChainedHeadersHelper.CreateConsecutiveHeaders(this.puller.ImportantHeightMargin + 10000); this.puller.NewPeerTipClaimed(peer1, headers.Last()); // Assign first ImportantHeightMargin headers to peer 1 so when stalling happens it happens only on peer 1. this.puller.RequestBlocksDownload(headers.Take(this.puller.ImportantHeightMargin).ToList()); await this.puller.AssignDownloadJobsAsync(); this.puller.NewPeerTipClaimed(peer2, headers.Last()); this.puller.RequestBlocksDownload(headers.Skip(this.puller.ImportantHeightMargin).ToList()); behavior1.AddSample(100, 0.1); behavior2.AddSample(100, 0.1); behavior1.RecalculateQualityScore(10); behavior2.RecalculateQualityScore(10); Assert.True(this.helper.DoubleEqual(behavior1.QualityScore, behavior2.QualityScore)); await this.puller.AssignDownloadJobsAsync(); // Fake assign time to avoid waiting for a long time. foreach (AssignedDownload assignedDownload in this.puller.AssignedDownloadsByHash.Values) { assignedDownload.AssignedTime = (assignedDownload.AssignedTime - TimeSpan.FromSeconds(this.puller.MaxSecondsToDeliverBlock)); } Assert.Empty(this.puller.ReassignedJobsQueue); List <AssignedDownload> peer1Assignments = this.puller.AssignedDownloadsByHash.Values.Where(x => x.PeerId == peer1.Connection.Id).ToList(); this.puller.CheckStalling(); Assert.True(behavior1.QualityScore < behavior2.QualityScore); // Two jobs reassigned from peer 1. Assert.Equal(2, this.puller.ReassignedJobsQueue.Count); var chainedHeaders = new List <ChainedHeader>(); foreach (DownloadJob downloadJob in this.puller.ReassignedJobsQueue) { chainedHeaders.AddRange(downloadJob.Headers); } Assert.True(chainedHeaders.All(x => peer1Assignments.Exists(y => y.Header == x))); }
public void UpdateBestSentHeader_ChangedIfHeaderIsOnFork() { ConsensusManagerBehavior behavior = this.helper.CreateAndAttachBehavior(this.headers[20], null, this.headers[10]); ChainedHeader headerOnChainB = ChainedHeadersHelper.CreateConsecutiveHeaders(7, this.headers[8]).Last(); behavior.UpdateBestSentHeader(headerOnChainB); Assert.Equal(headerOnChainB, behavior.BestSentHeader); }
public void SignalBlockDisconnectedToBlockSignaler() { Block block = KnownNetworks.StratisMain.CreateBlock(); ChainedHeader header = ChainedHeadersHelper.CreateGenesisChainedHeader(); var chainedHeaderBlock = new ChainedHeaderBlock(block, header); this.signals.SignalBlockDisconnected(chainedHeaderBlock); this.blockDisconnectedSignaler.Verify(b => b.Broadcast(chainedHeaderBlock), Times.Exactly(1)); }
public TipsManagerTests() : base(KnownNetworks.StratisMain) { this.loggerFactory = new LoggerFactory(); string dir = CreateTestDir(this); this.keyValueRepo = new KeyValueRepository(dir, new DataStoreSerializer(this.Network.Consensus.ConsensusFactory)); this.tipsManager = new TipsManager(this.keyValueRepo, this.loggerFactory); this.mainChainHeaders = ChainedHeadersHelper.CreateConsecutiveHeaders(20, ChainedHeadersHelper.CreateGenesisChainedHeader(this.Network), true); }
public void RequestPeerServices_PeersThatDontSupportNewServicesAreNotAdded() { this.puller.RequestPeerServices(NetworkPeerServices.NODE_WITNESS); Mock <INetworkPeer> peer1 = this.helper.CreatePeerMock(out ExtendedBlockPullerBehavior behavior1); List <ChainedHeader> headers = ChainedHeadersHelper.CreateConsecutiveHeaders(5); this.puller.NewPeerTipClaimed(peer1.Object, headers.Last()); Assert.Equal(0, this.puller.PullerBehaviorsByPeerId.Count); }
public async Task ProcessHeadersAsync_NonConsecutiveHeadersPresentedAsync() { this.helper.CreateAndAttachBehavior(this.headers[5]); List <ChainedHeader> headersToPresent = ChainedHeadersHelper.CreateConsecutiveHeaders(5); headersToPresent.AddRange(ChainedHeadersHelper.CreateConsecutiveHeaders(10)); await this.helper.ReceivePayloadAsync(new HeadersPayload(headersToPresent.Select(x => x.Header))); Assert.True(this.helper.PeerWasBanned); }
public BlockPullerTestsHelper() { this.loggerFactory = ExtendedLoggerFactory.Create(); this.CallbacksCalled = new Dictionary <uint256, Block>(); this.ChainState = new ChainState() { ConsensusTip = ChainedHeadersHelper.CreateGenesisChainedHeader() }; this.Puller = new ExtendedBlockPuller(this.ChainState, new NodeSettings(new StratisMain()), new DateTimeProvider(), new NodeStats(new DateTimeProvider(), this.loggerFactory), this.loggerFactory); }
public void OnNextCoreProcessesOnTheWalletSyncManager() { var walletSyncManager = new Mock <IWalletSyncManager>(); var observer = new BlockObserver(walletSyncManager.Object); Block block = KnownNetworks.StratisMain.CreateBlock(); ChainedHeader header = ChainedHeadersHelper.CreateGenesisChainedHeader(); var chainedHeaderBlock = new ChainedHeaderBlock(block, header); observer.OnNext(chainedHeaderBlock); walletSyncManager.Verify(w => w.ProcessBlock(block), Times.Exactly(1)); }