示例#1
0
        public void TestMissingHeader()
        {
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();
            var header1     = fakeHeaders.NextChained();
            var header2     = fakeHeaders.NextChained();

            var rules            = Mock.Of <ICoreRules>();
            var coreStorage      = new Mock <ICoreStorage>();
            var storageManager   = new Mock <IStorageManager>();
            var chainStateCursor = new Mock <IChainStateCursor>();

            storageManager.Setup(x => x.OpenChainStateCursor()).Returns(
                new DisposeHandle <IChainStateCursor>(_ => { }, chainStateCursor.Object));

            // don't mock header 1 so it is missing
            chainStateCursor.Setup(x => x.TryGetHeader(header0.Hash, out header0)).Returns(true);
            chainStateCursor.Setup(x => x.TryGetHeader(header2.Hash, out header2)).Returns(true);

            // return header 2 as the chain tip
            chainStateCursor.Setup(x => x.ChainTip).Returns(header2);

            // init chain state builder with missing header
            StorageCorruptException actualEx;

            AssertMethods.AssertThrows <StorageCorruptException>(() =>
            {
                var chain = new ChainStateBuilder(rules, coreStorage.Object, storageManager.Object).Chain;
            },
                                                                 out actualEx);

            Assert.AreEqual(StorageType.ChainState, actualEx.StorageType);
            Assert.AreEqual("ChainState is missing header.", actualEx.Message);
        }
示例#2
0
        public void TestCreateFromInvalidEnumerable()
        {
            // create a chain
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();
            var header1     = fakeHeaders.NextChained();

            // create builder from out of order enumerable
            AssertMethods.AssertThrows <InvalidOperationException>(() => new ChainBuilder(new[] { header1, header0 }));
        }
示例#3
0
        public void TestChainTipOutOfSync()
        {
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();
            var header1     = fakeHeaders.NextChained();
            var header2     = fakeHeaders.NextChained();

            var rules            = Mock.Of <ICoreRules>();
            var coreStorage      = new Mock <ICoreStorage>();
            var storageManager   = new Mock <IStorageManager>();
            var chainStateCursor = new Mock <IDeferredChainStateCursor>();

            storageManager.Setup(x => x.OpenChainStateCursor()).Returns(
                new DisposeHandle <IChainStateCursor>(_ => { }, chainStateCursor.Object));

            storageManager.Setup(x => x.OpenDeferredChainStateCursor(It.IsAny <IChainState>())).Returns(
                new DisposeHandle <IDeferredChainStateCursor>(_ => { }, chainStateCursor.Object));

            chainStateCursor.Setup(x => x.TryGetHeader(header0.Hash, out header0)).Returns(true);
            chainStateCursor.Setup(x => x.TryGetHeader(header1.Hash, out header1)).Returns(true);
            chainStateCursor.Setup(x => x.TryGetHeader(header2.Hash, out header2)).Returns(true);

            // return header 1 as the chain tip
            chainStateCursor.Setup(x => x.ChainTip).Returns(header1);

            // init chain state builder seeing header 1
            var chainStateBuilder = new ChainStateBuilder(rules, coreStorage.Object, storageManager.Object);

            Assert.AreEqual(header1.Hash, chainStateBuilder.Chain.LastBlock.Hash);

            // alter the chain tip outside of the chain state builder
            chainStateCursor.Setup(x => x.ChainTip).Returns(header2);

            // attempt to add block when out of sync
            ChainStateOutOfSyncException actualEx;

            AssertMethods.AssertAggregateThrows <ChainStateOutOfSyncException>(() =>
                                                                               chainStateBuilder.AddBlockAsync(header2, Enumerable.Empty <BlockTx>()).Wait(),
                                                                               out actualEx);

            Assert.AreEqual(header1.Hash, actualEx.ExpectedChainTip.Hash);
            Assert.AreEqual(header2.Hash, actualEx.ActualChainTip.Hash);

            // attempt to rollback block when out of sync
            AssertMethods.AssertThrows <ChainStateOutOfSyncException>(() =>
                                                                      chainStateBuilder.RollbackBlock(header2, Enumerable.Empty <BlockTx>()),
                                                                      out actualEx);

            Assert.AreEqual(header1.Hash, actualEx.ExpectedChainTip.Hash);
            Assert.AreEqual(header2.Hash, actualEx.ActualChainTip.Hash);
        }
示例#4
0
        public void TestRemoveBlockInvalid()
        {
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();
            var header1     = fakeHeaders.NextChained();
            var header2     = fakeHeaders.NextChained();

            var chainBuilder = new ChainBuilder(new[] { header0, header1, header2 });

            // removing header 1 first should fail
            AssertMethods.AssertThrows <InvalidOperationException>(() => chainBuilder.RemoveBlock(header1));

            // remove header 2
            chainBuilder.RemoveBlock(header2);

            // removing header 0 with header 1 present should fail
            AssertMethods.AssertThrows <InvalidOperationException>(() => chainBuilder.AddBlock(header0));
        }
示例#5
0
        public void TestAddBlockInvalid()
        {
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();
            var header1     = fakeHeaders.NextChained();
            var header2     = fakeHeaders.NextChained();

            var chainBuilder = new ChainBuilder();

            // adding header 1 first should fail
            AssertMethods.AssertThrows <InvalidOperationException>(() => chainBuilder.AddBlock(header1));

            // add header 0
            chainBuilder.AddBlock(header0);

            // adding header 2 without header 1 should fail
            AssertMethods.AssertThrows <InvalidOperationException>(() => chainBuilder.AddBlock(header2));
        }
示例#6
0
        public void TestNavigateTowardsInvalidChains()
        {
            // create distinct chains
            var fakeHeadersA = new FakeHeaders();
            var header0A     = fakeHeadersA.GenesisChained();
            var header1A     = fakeHeadersA.NextChained();

            var fakeHeadersB = new FakeHeaders();
            var header0B     = fakeHeadersB.GenesisChained();
            var header1B     = fakeHeadersB.NextChained();

            var chainEmpty = new ChainBuilder().ToImmutable();
            var chainA     = new ChainBuilder(new[] { header0A, header1A }).ToImmutable();
            var chainB     = new ChainBuilder(new[] { header0B, header1B, }).ToImmutable();

            // unrelated chains should error
            AssertMethods.AssertThrows <InvalidOperationException>(() => chainA.NavigateTowards(chainB).ToList());
            AssertMethods.AssertThrows <InvalidOperationException>(() => chainB.NavigateTowards(chainA).ToList());
        }