BitSharp.Core.Test.Workers.TargetChainWorkerTest.TestTargetChainReorganize C# (CSharp) Method

TestTargetChainReorganize() private method

private TestTargetChainReorganize ( ) : void
return void
        public void TestTargetChainReorganize()
        {
            // prepare test kernel
            var kernel = new StandardKernel(new ConsoleLoggingModule(), new MemoryStorageModule());
            kernel.Bind<CoreStorage>().ToSelf().InSingletonScope();
            var coreStorage = kernel.Get<CoreStorage>();

            // initialize data
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.Genesis();
            var header1 = fakeHeaders.Next();
            var header2 = fakeHeaders.Next();

            var fakeHeadersA = new FakeHeaders(fakeHeaders);
            var header3A = fakeHeadersA.Next();
            var header4A = fakeHeadersA.Next();
            var header5A = fakeHeadersA.Next();

            var fakeHeadersB = new FakeHeaders(fakeHeaders);
            var header3B = fakeHeadersB.Next();
            var header4B = fakeHeadersB.Next(DataCalculator.ToCompact(UnitTestParams.Target2));

            // store genesis block
            var chainedHeader0 = ChainedHeader.CreateForGenesisBlock(header0);
            coreStorage.AddGenesisBlock(chainedHeader0);

            // mock chain params
            var mockChainParams = new Mock<IChainParams>();
            mockChainParams.Setup(rules => rules.GenesisChainedHeader).Returns(chainedHeader0);
            kernel.Bind<IChainParams>().ToConstant(mockChainParams.Object);

            // initialize the target chain worker
            using (var targetChainWorker = kernel.Get<TargetChainWorker>(new ConstructorArgument("workerConfig", new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.Zero, maxIdleTime: TimeSpan.MaxValue))))
            {
                // monitor event firing
                var targetChainChangedEvent = new AutoResetEvent(false);
                var onTargetChainChangedCount = 0;
                targetChainWorker.OnTargetChainChanged += () => { onTargetChainChangedCount++; targetChainChangedEvent.Set(); };

                // start worker and wait for initial chain
                targetChainWorker.Start();
                targetChainChangedEvent.WaitOne();

                // verify chained to block 0
                Assert.AreEqual(chainedHeader0, targetChainWorker.TargetChain.LastBlock);
                AssertBlockListEquals(new[] { chainedHeader0 }, targetChainWorker.TargetChain.Blocks);
                Assert.AreEqual(1, onTargetChainChangedCount);

                // add block 1
                ChainedHeader chainedHeader1;
                coreStorage.TryChainHeader(header1, out chainedHeader1);

                // wait for worker
                targetChainChangedEvent.WaitOne();

                // verify chained to block 1
                Assert.AreEqual(chainedHeader1, targetChainWorker.TargetChain.LastBlock);
                AssertBlockListEquals(new[] { chainedHeader0, chainedHeader1 }, targetChainWorker.TargetChain.Blocks);
                Assert.AreEqual(2, onTargetChainChangedCount);

                // add block 2
                ChainedHeader chainedHeader2;
                coreStorage.TryChainHeader(header2, out chainedHeader2);

                // wait for worker
                targetChainChangedEvent.WaitOne();

                // verify chained to block 2
                Assert.AreEqual(chainedHeader2, targetChainWorker.TargetChain.LastBlock);
                AssertBlockListEquals(new[] { chainedHeader0, chainedHeader1, chainedHeader2 }, targetChainWorker.TargetChain.Blocks);
                Assert.AreEqual(3, onTargetChainChangedCount);

                // add block 3A
                ChainedHeader chainedHeader3A;
                coreStorage.TryChainHeader(header3A, out chainedHeader3A);

                // wait for worker
                targetChainChangedEvent.WaitOne();

                // verify chained to block 3A
                Assert.AreEqual(chainedHeader3A, targetChainWorker.TargetChain.LastBlock);
                AssertBlockListEquals(new[] { chainedHeader0, chainedHeader1, chainedHeader2, chainedHeader3A }, targetChainWorker.TargetChain.Blocks);
                Assert.AreEqual(4, onTargetChainChangedCount);

                // add block 4A
                ChainedHeader chainedHeader4A;
                coreStorage.TryChainHeader(header4A, out chainedHeader4A);

                // wait for worker
                targetChainChangedEvent.WaitOne();

                // verify chained to block 4A
                Assert.AreEqual(chainedHeader4A, targetChainWorker.TargetChain.LastBlock);
                AssertBlockListEquals(new[] { chainedHeader0, chainedHeader1, chainedHeader2, chainedHeader3A, chainedHeader4A }, targetChainWorker.TargetChain.Blocks);
                Assert.AreEqual(5, onTargetChainChangedCount);

                // add block 5A
                ChainedHeader chainedHeader5A;
                coreStorage.TryChainHeader(header5A, out chainedHeader5A);

                // wait for worker
                targetChainChangedEvent.WaitOne();

                // verify chained to block 5A
                Assert.AreEqual(chainedHeader5A, targetChainWorker.TargetChain.LastBlock);
                AssertBlockListEquals(new[] { chainedHeader0, chainedHeader1, chainedHeader2, chainedHeader3A, chainedHeader4A, chainedHeader5A }, targetChainWorker.TargetChain.Blocks);
                Assert.AreEqual(6, onTargetChainChangedCount);

                // add block 3B
                ChainedHeader chainedHeader3B;
                coreStorage.TryChainHeader(header3B, out chainedHeader3B);

                // wait for worker, it should not fire
                Assert.IsFalse(targetChainChangedEvent.WaitOne(50));

                // verify no chaining done
                Assert.AreEqual(chainedHeader5A, targetChainWorker.TargetChain.LastBlock);
                AssertBlockListEquals(new[] { chainedHeader0, chainedHeader1, chainedHeader2, chainedHeader3A, chainedHeader4A, chainedHeader5A }, targetChainWorker.TargetChain.Blocks);
                Assert.AreEqual(6, onTargetChainChangedCount);

                // add block 4B
                ChainedHeader chainedHeader4B;
                coreStorage.TryChainHeader(header4B, out chainedHeader4B);

                // wait for worker
                targetChainChangedEvent.WaitOne();

                // verify chained to block 4B
                Assert.AreEqual(chainedHeader4B, targetChainWorker.TargetChain.LastBlock);
                AssertBlockListEquals(new[] { chainedHeader0, chainedHeader1, chainedHeader2, chainedHeader3B, chainedHeader4B }, targetChainWorker.TargetChain.Blocks);
                Assert.AreEqual(7, onTargetChainChangedCount);

                // verify no other work was done
                Assert.IsFalse(targetChainChangedEvent.WaitOne(50));
            }
        }