public void TestSimpleChain()
{
// 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();
// 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);
// verify no other work was done
Assert.IsFalse(targetChainChangedEvent.WaitOne(50));
}
}