public void BinaryFindFirstFindsTheExpectedItem() { const int numItems = 1000000; const int numTests = 10000; int?[] testArray = Enumerable.Range(0, numItems).Select(n => (int?)n).ToArray(); var rand = new Random(0); for (int i = 0; i < 100; i++) { testArray[rand.Next(numItems)] = null; } for (int i = 0; i < numTests; i++) { int itemToFind = rand.Next(numItems); testArray[itemToFind] = itemToFind; Assert.Equal(itemToFind, BinarySearch.BinaryFindFirst <int?>(testArray, x => (x == null) ? (bool?)null : (x >= itemToFind))); } }
/// <inheritdoc /> public int?GetMultisigMinersApplicabilityHeight() { IConsensusManager consensusManager = this.fullNode.NodeService <IConsensusManager>(); ChainedHeader fork = (this.lastBlockChecked == null) ? null : consensusManager.Tip.FindFork(this.lastBlockChecked); if (this.multisigMinersApplicabilityHeight != null && fork?.HashBlock == this.lastBlockChecked?.HashBlock) { return(this.multisigMinersApplicabilityHeight); } this.lastBlockChecked = fork; this.multisigMinersApplicabilityHeight = null; var commitmentHeightEncoder = new CollateralHeightCommitmentEncoder(this.logger); ChainedHeader[] headers = consensusManager.Tip.EnumerateToGenesis().TakeWhile(h => h != this.lastBlockChecked && h.Height >= this.network.CollateralCommitmentActivationHeight).Reverse().ToArray(); ChainedHeader first = BinarySearch.BinaryFindFirst <ChainedHeader>(headers, (chainedHeader) => { ChainedHeaderBlock block = consensusManager.GetBlockData(chainedHeader.HashBlock); if (block == null) { return(null); } // Finding the height of the first STRAX collateral commitment height. (int?commitmentHeight, uint?magic) = commitmentHeightEncoder.DecodeCommitmentHeight(block.Block.Transactions.First()); if (commitmentHeight == null) { return(null); } return(magic == this.counterChainSettings.CounterChainNetwork.Magic); }); this.lastBlockChecked = headers.LastOrDefault(); this.multisigMinersApplicabilityHeight = first?.Height; this.UpdateMultisigMiners(first != null); return(this.multisigMinersApplicabilityHeight); }