コード例 #1
0
        public void TestBlocks()
        {
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();
            var header1     = fakeHeaders.NextChained();

            var chainBuilder = new ChainBuilder();

            // verify block list with 0 blocks
            var chainEmpty = chainBuilder.ToImmutable();

            Assert.AreEqual(0, chainEmpty.Blocks.Count);

            // verify block list with 1 block
            chainBuilder.AddBlock(header0);
            var chain0 = chainBuilder.ToImmutable();

            CollectionAssert.AreEqual(new[] { header0 }, chain0.Blocks);

            // verify block list with 2 blocks
            chainBuilder.AddBlock(header1);
            var chain1 = chainBuilder.ToImmutable();

            CollectionAssert.AreEqual(new[] { header0, header1 }, chain1.Blocks);
        }
コード例 #2
0
        public void TestToBuilder()
        {
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();
            var header1     = fakeHeaders.NextChained();

            var chainBuilder = new ChainBuilder();

            // verify to builder with 0 blocks
            var chainEmpty        = chainBuilder.ToImmutable();
            var chainBuilderEmpty = chainEmpty.ToBuilder();

            Assert.AreEqual(0, chainBuilderEmpty.Blocks.Count);
            Assert.AreEqual(0, chainBuilderEmpty.BlocksByHash.Count);

            // verify to builder with 1 block
            chainBuilder.AddBlock(header0);
            var chain0        = chainBuilder.ToImmutable();
            var chainBuilder0 = chain0.ToBuilder();

            CollectionAssert.AreEqual(new[] { header0 }, chainBuilder0.Blocks);
            CollectionAssert.AreEquivalent(new Dictionary <UInt256, ChainedHeader> {
                { header0.Hash, header0 }
            }, chainBuilder0.BlocksByHash);

            // verify to builder with 2 blocks
            chainBuilder.AddBlock(header1);
            var chain1        = chainBuilder.ToImmutable();
            var chainBuilder1 = chain1.ToBuilder();

            CollectionAssert.AreEqual(new[] { header0, header1 }, chainBuilder1.Blocks);
            CollectionAssert.AreEquivalent(new Dictionary <UInt256, ChainedHeader> {
                { header0.Hash, header0 }, { header1.Hash, header1 }
            }, chainBuilder1.BlocksByHash);
        }
コード例 #3
0
        // IBlockStorage.ContainsChainedHeader
        private void TestContainsChainedHeader(ITestStorageProvider provider)
        {
            using (var storageManager = provider.OpenStorageManager())
            {
                var blockStorage = storageManager.BlockStorage;

                // create a chained header
                var fakeHeaders   = new FakeHeaders();
                var chainedHeader = fakeHeaders.GenesisChained();

                // header should not be present
                Assert.IsFalse(blockStorage.ContainsChainedHeader(chainedHeader.Hash));

                // add the header
                blockStorage.TryAddChainedHeader(chainedHeader);

                // header should be present
                Assert.IsTrue(blockStorage.ContainsChainedHeader(chainedHeader.Hash));

                // remove the header
                blockStorage.TryRemoveChainedHeader(chainedHeader.Hash);

                // header should not be present
                Assert.IsFalse(blockStorage.ContainsChainedHeader(chainedHeader.Hash));
            }
        }
コード例 #4
0
        // IBlockStorage.ContainsChainedHeader
        private void TestContainsChainedHeader(ITestStorageProvider provider)
        {
            using (var storageManager = provider.OpenStorageManager())
            {
                var blockStorage = storageManager.BlockStorage;

                // create a chained header
                var fakeHeaders = new FakeHeaders();
                var chainedHeader = fakeHeaders.GenesisChained();

                // header should not be present
                Assert.IsFalse(blockStorage.ContainsChainedHeader(chainedHeader.Hash));

                // add the header
                blockStorage.TryAddChainedHeader(chainedHeader);

                // header should be present
                Assert.IsTrue(blockStorage.ContainsChainedHeader(chainedHeader.Hash)); ;

                // remove the header
                blockStorage.TryRemoveChainedHeader(chainedHeader.Hash);

                // header should not be present
                Assert.IsFalse(blockStorage.ContainsChainedHeader(chainedHeader.Hash)); ;
            }
        }
コード例 #5
0
        public void TestNavigateTowardsEmpty()
        {
            // create chain
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();
            var header1     = fakeHeaders.NextChained();
            var header2     = fakeHeaders.NextChained();

            var chainEmpty = new ChainBuilder().ToImmutable();
            var chain      = new ChainBuilder(new[] { header0, header1, header2 }).ToImmutable();

            // verify chaining to empty does nothing
            Assert.AreEqual(0, chainEmpty.NavigateTowards(chainEmpty).Count());
            Assert.AreEqual(0, chain.NavigateTowards(chainEmpty).Count());

            // verify path from empty chain to chain
            CollectionAssert.AreEqual(
                new[]
            {
                Tuple.Create(+1, header0),
                Tuple.Create(+1, header1),
                Tuple.Create(+1, header2)
            }
                , chainEmpty.NavigateTowards(chain).ToList());
        }
コード例 #6
0
        // IBlockStorage.IsBlockInvalid
        // IBlockStorage.MarkBlockInvalid
        private void TestMarkBlockInvalid(ITestStorageProvider provider)
        {
            using (var storageManager = provider.OpenStorageManager())
            {
                var blockStorage = storageManager.BlockStorage;

                // create chained headers
                var fakeHeaders    = new FakeHeaders();
                var chainedHeader0 = fakeHeaders.GenesisChained();
                var chainedHeader1 = fakeHeaders.NextChained();

                // add headers
                blockStorage.TryAddChainedHeader(chainedHeader0);
                blockStorage.TryAddChainedHeader(chainedHeader1);

                // verify no blocks invalid
                Assert.IsFalse(blockStorage.IsBlockInvalid(chainedHeader0.Hash));
                Assert.IsFalse(blockStorage.IsBlockInvalid(chainedHeader1.Hash));

                // mark blocks invalid and verify

                // 0
                blockStorage.MarkBlockInvalid(chainedHeader0.Hash);
                Assert.IsTrue(blockStorage.IsBlockInvalid(chainedHeader0.Hash));
                Assert.IsFalse(blockStorage.IsBlockInvalid(chainedHeader1.Hash));

                // 1
                blockStorage.MarkBlockInvalid(chainedHeader1.Hash);
                Assert.IsTrue(blockStorage.IsBlockInvalid(chainedHeader0.Hash));
                Assert.IsTrue(blockStorage.IsBlockInvalid(chainedHeader1.Hash));
            }
        }
コード例 #7
0
        // IBlockStorage.TryAddChainedHeader
        // IBlockStorage.TryRemoveChainedHeader
        private void TestTryAddRemoveChainedHeader(ITestStorageProvider provider)
        {
            using (var storageManager = provider.OpenStorageManager())
            {
                var blockStorage = storageManager.BlockStorage;

                // create a chained header
                var fakeHeaders   = new FakeHeaders();
                var chainedHeader = fakeHeaders.GenesisChained();

                // verify header can be added
                Assert.IsTrue(blockStorage.TryAddChainedHeader(chainedHeader));
                Assert.IsTrue(blockStorage.ContainsChainedHeader(chainedHeader.Hash));

                // verify header cannot be added again
                Assert.IsFalse(blockStorage.TryAddChainedHeader(chainedHeader));

                // remove the header
                Assert.IsTrue(blockStorage.TryRemoveChainedHeader(chainedHeader.Hash));
                Assert.IsFalse(blockStorage.ContainsChainedHeader(chainedHeader.Hash));

                // verify header cannot be removed again
                Assert.IsFalse(blockStorage.TryRemoveChainedHeader(chainedHeader.Hash));

                // verify header can be added again, after being removed
                Assert.IsTrue(blockStorage.TryAddChainedHeader(chainedHeader));
                Assert.IsTrue(blockStorage.ContainsChainedHeader(chainedHeader.Hash));

                // verify header can be removed again, after being added again
                Assert.IsTrue(blockStorage.TryRemoveChainedHeader(chainedHeader.Hash));
                Assert.IsFalse(blockStorage.ContainsChainedHeader(chainedHeader.Hash));
            }
        }
コード例 #8
0
        public void TestReadChain()
        {
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();
            var header1     = fakeHeaders.NextChained();
            var header2     = fakeHeaders.NextChained();

            var chainedHeaders = new Dictionary <UInt256, ChainedHeader>();

            chainedHeaders.Add(header0.Hash, header0);
            chainedHeaders.Add(header1.Hash, header1);
            chainedHeaders.Add(header2.Hash, header2);

            Chain chain;

            Assert.IsTrue(Chain.TryReadChain(header2.Hash, out chain,
                                             headerHash =>
            {
                ChainedHeader chainedHeader;
                chainedHeaders.TryGetValue(headerHash, out chainedHeader);
                return(chainedHeader);
            }));

            CollectionAssert.AreEqual(fakeHeaders.ChainedHeaders, chain.Blocks);
        }
コード例 #9
0
        public void TestHeight()
        {
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();
            var header1     = fakeHeaders.NextChained();

            var chainBuilder = new ChainBuilder();

            // verify height with 0 blocks
            var chainEmpty = chainBuilder.ToImmutable();

            Assert.AreEqual(-1, chainEmpty.Height);

            // verify height with 1 block
            chainBuilder.AddBlock(header0);
            var chain0 = chainBuilder.ToImmutable();

            Assert.AreEqual(0, chain0.Height);

            // verify height with 2 blocks
            chainBuilder.AddBlock(header1);
            var chain1 = chainBuilder.ToImmutable();

            Assert.AreEqual(1, chain1.Height);
        }
コード例 #10
0
        public void TestLastBlock()
        {
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();
            var header1     = fakeHeaders.NextChained();

            var chainBuilder = new ChainBuilder();

            // verify last block with 0 blocks
            var chainEmpty = chainBuilder.ToImmutable();

            Assert.IsNull(chainEmpty.LastBlock);

            // verify last block with 1 block
            chainBuilder.AddBlock(header0);
            var chain0 = chainBuilder.ToImmutable();

            Assert.AreEqual(header0, chain0.LastBlock);

            // verify last block with 2 blocks
            chainBuilder.AddBlock(header1);
            var chain1 = chainBuilder.ToImmutable();

            Assert.AreEqual(header1, chain1.LastBlock);
        }
コード例 #11
0
        public void Init()
        {
            var fakeHeaders = new FakeHeaders();

            this.chainedHeader0 = fakeHeaders.GenesisChained();
            this.chainedHeader1 = fakeHeaders.NextChained();

            var fakeHeadersA = new FakeHeaders(fakeHeaders);

            this.chainedHeaderA2 = fakeHeadersA.NextChained();
            this.chainedHeaderA3 = fakeHeadersA.NextChained();
            this.chainedHeaderA4 = fakeHeadersA.NextChained();

            var fakeHeadersB = new FakeHeaders(fakeHeaders);

            this.chainedHeaderB2 = fakeHeadersB.NextChained();
            this.chainedHeaderB3 = fakeHeadersB.NextChained();
            this.chainedHeaderB4 = fakeHeadersB.NextChained();

            var fakeHeadersX = new FakeHeaders();

            this.chainedHeaderX0 = fakeHeadersX.GenesisChained();
            this.chainedHeaderX1 = fakeHeadersX.NextChained();

            this.chain = ImmutableDictionary.CreateRange(
                new[] { chainedHeader0, chainedHeader1, chainedHeaderA2, chainedHeaderA3, chainedHeaderA4, chainedHeaderB2, chainedHeaderB3, chainedHeaderB4, chainedHeaderX0, chainedHeaderX1 }
                .Select(x => new KeyValuePair <UInt256, ChainedHeader>(x.Hash, x)));

            this.getChainedHeader = blockHash => this.chain[blockHash];
        }
コード例 #12
0
        public void TestTotalWork()
        {
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();
            var header1     = fakeHeaders.NextChained();
            var totalWork0  = DataCalculator.CalculateWork(header0);
            var totalWork1  = totalWork0 + DataCalculator.CalculateWork(header1);

            var chainBuilder = new ChainBuilder();

            // verify total work with 0 blocks
            var chainEmpty = chainBuilder.ToImmutable();

            Assert.AreEqual(0, chainEmpty.TotalWork);

            // verify total work with 1 block
            chainBuilder.AddBlock(header0);
            var chain0 = chainBuilder.ToImmutable();

            Assert.AreEqual(totalWork0.ToBigInteger(), chain0.TotalWork);

            // verify total work with 2 blocks
            chainBuilder.AddBlock(header1);
            var chain1 = chainBuilder.ToImmutable();

            Assert.AreEqual(totalWork1.ToBigInteger(), chain1.TotalWork);
        }
コード例 #13
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);
        }
コード例 #14
0
        public void TestInitWithChain()
        {
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();
            var header1 = 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.ChainTip).Returns(header1);
            chainStateCursor.Setup(x => x.TryGetHeader(header0.Hash, out header0)).Returns(true);
            chainStateCursor.Setup(x => x.TryGetHeader(header1.Hash, out header1)).Returns(true);

            var chainStateBuilder = new ChainStateBuilder(rules, coreStorage.Object, storageManager.Object);

            CollectionAssert.AreEqual(new[] { header0, header1 }, chainStateBuilder.Chain.Blocks);
        }
コード例 #15
0
        public void TestInitWithChain()
        {
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();
            var header1     = 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.ChainTip).Returns(header1);
            chainStateCursor.Setup(x => x.TryGetHeader(header0.Hash, out header0)).Returns(true);
            chainStateCursor.Setup(x => x.TryGetHeader(header1.Hash, out header1)).Returns(true);

            var chainStateBuilder = new ChainStateBuilder(rules, coreStorage.Object, storageManager.Object);

            CollectionAssert.AreEqual(new[] { header0, header1 }, chainStateBuilder.Chain.Blocks);
        }
コード例 #16
0
        public void TestNavigateTowardsFunc()
        {
            // create chains
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();
            var header1     = fakeHeaders.NextChained();
            var header2     = fakeHeaders.NextChained();
            var header3     = fakeHeaders.NextChained();

            var chain0 = new ChainBuilder(new[] { header0, }).ToImmutable();
            var chain1 = new ChainBuilder(new[] { header0, header1, }).ToImmutable();
            var chain2 = new ChainBuilder(new[] { header0, header1, header2 }).ToImmutable();
            var chain3 = new ChainBuilder(new[] { header0, header1, header2, header3 }).ToImmutable();

            // the list of target chains to use, stays 1 ahead and then catches up with chain 3
            var targetStack = new Stack <Chain>(new[] { chain1, chain2, chain3, chain3 }.Reverse());

            // verify navigating towards an updating chain
            CollectionAssert.AreEqual(
                new[]
            {
                Tuple.Create(+1, header1),
                Tuple.Create(+1, header2),
                Tuple.Create(+1, header3)
            }
                , chain0.NavigateTowards(() => targetStack.Pop()).ToList());

            // verify all targets used
            Assert.AreEqual(0, targetStack.Count);
        }
コード例 #17
0
        public void TestAddBlockConfirmingTx()
        {
            // create tx spending a previous output that exists
            var decodedTx = Transaction.Create(
                0,
                ImmutableArray.Create(new TxInput(UInt256.One, 0, ImmutableArray <byte> .Empty, 0)),
                ImmutableArray.Create(new TxOutput(0, ImmutableArray <byte> .Empty)),
                0);
            var tx = decodedTx.Transaction;

            // create prev output tx
            var unspentTx = new UnspentTx(tx.Inputs[0].PrevTxHash, 0, 1, 0, false, new OutputStates(1, OutputState.Unspent));
            var txOutput  = new TxOutput(0, ImmutableArray <byte> .Empty);

            // create a fake chain
            var fakeHeaders   = new FakeHeaders();
            var genesisHeader = fakeHeaders.GenesisChained();

            // create a block confirming the tx
            var block         = Block.Create(RandomData.RandomBlockHeader().With(PreviousBlock: genesisHeader.Hash), ImmutableArray.Create(tx));
            var chainedHeader = new ChainedHeader(block.Header, 1, 0, DateTimeOffset.Now);

            // mock core storage with chained header
            var coreStorage  = new Mock <ICoreStorage>();
            var initialChain = new ChainBuilder().ToImmutable();

            coreStorage.Setup(x => x.TryReadChain(null, out initialChain)).Returns(true);
            coreStorage.Setup(x => x.TryGetChainedHeader(chainedHeader.Hash, out chainedHeader)).Returns(true);

            // mock chain state with prev output
            var chainState = new Mock <IChainState>();

            chainState.Setup(x => x.TryGetUnspentTx(tx.Inputs[0].PrevTxHash, out unspentTx)).Returns(true);
            chainState.Setup(x => x.TryGetUnspentTxOutput(tx.Inputs[0].PrevTxOutputKey, out txOutput)).Returns(true);

            // mock core daemon for chain state retrieval
            var coreDaemon = new Mock <ICoreDaemon>();

            coreDaemon.Setup(x => x.GetChainState()).Returns(chainState.Object);

            using (var unconfirmedTxesBuilder = new UnconfirmedTxesBuilder(coreDaemon.Object, coreStorage.Object, storageManager))
            {
                // add the tx
                Assert.IsTrue(unconfirmedTxesBuilder.TryAddTransaction(decodedTx));

                // add the block
                unconfirmedTxesBuilder.AddBlock(genesisHeader, Enumerable.Empty <BlockTx>());
                unconfirmedTxesBuilder.AddBlock(chainedHeader, block.BlockTxes);

                // verify the confirmed tx was removed
                UnconfirmedTx unconfirmedTx;
                Assert.IsFalse(unconfirmedTxesBuilder.TryGetTransaction(tx.Hash, out unconfirmedTx));
                Assert.IsNull(unconfirmedTx);

                // verify the confirmed tx was de-indexed against its input
                Assert.AreEqual(0, unconfirmedTxesBuilder.GetTransactionsSpending(tx.Inputs[0].PrevTxOutputKey).Count);
            }
        }
コード例 #18
0
        public void TestCreateForGenesisBlock()
        {
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();

            var chain = Chain.CreateForGenesisBlock(header0);

            CollectionAssert.AreEqual(new[] { header0 }, chain.Blocks);
        }
コード例 #19
0
ファイル: ChainBuilderTest.cs プロジェクト: cole2295/BitSharp
        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 }));
        }
コード例 #20
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 }));
        }
コード例 #21
0
        private void TestReadChain(ITestStorageProvider provider)
        {
            var fakeHeaders    = new FakeHeaders();
            var chainedHeader0 = fakeHeaders.GenesisChained();
            var chainedHeader1 = fakeHeaders.NextChained();
            var chainedHeader2 = fakeHeaders.NextChained();

            using (var storageManager = provider.OpenStorageManager())
                using (var handle = storageManager.OpenChainStateCursor())
                {
                    var chainStateCursor = handle.Item;

                    // begin transaction
                    chainStateCursor.BeginTransaction();

                    // verify initial empty chain
                    Assert.AreEqual(0, chainStateCursor.ReadChain().Count());

                    // add header 0
                    chainStateCursor.AddChainedHeader(chainedHeader0);

                    // verify chain
                    CollectionAssert.AreEqual(new[] { chainedHeader0 }, chainStateCursor.ReadChain().ToList());

                    // add header 1
                    chainStateCursor.AddChainedHeader(chainedHeader1);

                    // verify chain
                    CollectionAssert.AreEqual(new[] { chainedHeader0, chainedHeader1 }, chainStateCursor.ReadChain().ToList());

                    // add header 2
                    chainStateCursor.AddChainedHeader(chainedHeader2);

                    // verify chain
                    CollectionAssert.AreEqual(new[] { chainedHeader0, chainedHeader1, chainedHeader2 }, chainStateCursor.ReadChain().ToList());

                    // remove header 2
                    chainStateCursor.RemoveChainedHeader(chainedHeader2);

                    // verify chain
                    CollectionAssert.AreEqual(new[] { chainedHeader0, chainedHeader1 }, chainStateCursor.ReadChain().ToList());

                    // remove header 1
                    chainStateCursor.RemoveChainedHeader(chainedHeader1);

                    // verify chain
                    CollectionAssert.AreEqual(new[] { chainedHeader0 }, chainStateCursor.ReadChain().ToList());

                    // remove header 0
                    chainStateCursor.RemoveChainedHeader(chainedHeader0);

                    // verify chain
                    Assert.AreEqual(0, chainStateCursor.ReadChain().Count());
                }
        }
コード例 #22
0
        private void TestGetChainTip(ITestStorageProvider provider)
        {
            var fakeHeaders    = new FakeHeaders();
            var chainedHeader0 = fakeHeaders.GenesisChained();
            var chainedHeader1 = fakeHeaders.NextChained();
            var chainedHeader2 = fakeHeaders.NextChained();

            using (var storageManager = provider.OpenStorageManager())
                using (var handle = storageManager.OpenChainStateCursor())
                {
                    var chainStateCursor = handle.Item;

                    // begin transaction
                    chainStateCursor.BeginTransaction();

                    // verify initial empty chain
                    Assert.IsNull(chainStateCursor.GetChainTip());

                    // add header 0
                    chainStateCursor.AddChainedHeader(chainedHeader0);

                    // verify chain tip
                    Assert.AreEqual(chainedHeader0, chainStateCursor.GetChainTip());

                    // add header 1
                    chainStateCursor.AddChainedHeader(chainedHeader1);

                    // verify chain tip
                    Assert.AreEqual(chainedHeader1, chainStateCursor.GetChainTip());

                    // add header 2
                    chainStateCursor.AddChainedHeader(chainedHeader2);

                    // verify chain tip
                    Assert.AreEqual(chainedHeader2, chainStateCursor.GetChainTip());

                    // remove header 2
                    chainStateCursor.RemoveChainedHeader(chainedHeader2);

                    // verify chain tip
                    Assert.AreEqual(chainedHeader1, chainStateCursor.GetChainTip());

                    // remove header 1
                    chainStateCursor.RemoveChainedHeader(chainedHeader1);

                    // verify chain tip
                    Assert.AreEqual(chainedHeader0, chainStateCursor.GetChainTip());

                    // remove header 0
                    chainStateCursor.RemoveChainedHeader(chainedHeader0);

                    // verify chain tip
                    Assert.IsNull(chainStateCursor.GetChainTip());
                }
        }
コード例 #23
0
        private void TestRollbackTransaction(ITestStorageProvider provider)
        {
            var fakeHeaders    = new FakeHeaders();
            var chainedHeader0 = fakeHeaders.GenesisChained();
            var chainedHeader1 = fakeHeaders.NextChained();
            var chainedHeader2 = fakeHeaders.NextChained();

            var unspentTx = new UnspentTx(txHash: 0, blockIndex: 0, txIndex: 0, outputStates: new OutputStates(1, OutputState.Unspent));

            var spentTxes = ImmutableList.Create(new SpentTx(txHash: 1, confirmedBlockIndex: 0, txIndex: 0, outputCount: 1, spentBlockIndex: 0));

            using (var storageManager = provider.OpenStorageManager())
                using (var handle = storageManager.OpenChainStateCursor())
                {
                    var chainStateCursor = handle.Item;

                    // begin transaction
                    chainStateCursor.BeginTransaction();

                    // add header 0
                    chainStateCursor.AddChainedHeader(chainedHeader0);

                    // verify chain
                    CollectionAssert.AreEqual(new[] { chainedHeader0 }, chainStateCursor.ReadChain().ToList());

                    // add unspent tx
                    chainStateCursor.TryAddUnspentTx(unspentTx);

                    // verify unspent tx
                    Assert.IsTrue(chainStateCursor.ContainsUnspentTx(unspentTx.TxHash));
                    Assert.AreEqual(1, chainStateCursor.UnspentTxCount);

                    // add spent txes
                    chainStateCursor.TryAddBlockSpentTxes(0, spentTxes);

                    // verify spent txes
                    IImmutableList <SpentTx> actualSpentTxes;
                    Assert.IsTrue(chainStateCursor.TryGetBlockSpentTxes(0, out actualSpentTxes));
                    CollectionAssert.AreEqual(spentTxes, (ICollection)actualSpentTxes);

                    // rollback transaction
                    chainStateCursor.RollbackTransaction();

                    // verify chain
                    Assert.AreEqual(0, chainStateCursor.ReadChain().Count());

                    // verify unspent tx
                    Assert.IsFalse(chainStateCursor.ContainsUnspentTx(unspentTx.TxHash));
                    Assert.AreEqual(0, chainStateCursor.UnspentTxCount);

                    // verify spent txes
                    Assert.IsFalse(chainStateCursor.TryGetBlockSpentTxes(0, out actualSpentTxes));
                }
        }
コード例 #24
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);
        }
コード例 #25
0
        public void TestDoubleSpend()
        {
            // prepare block
            var fakeHeaders      = new FakeHeaders();
            var chainedHeader0   = fakeHeaders.GenesisChained();
            var chainedHeader1   = fakeHeaders.NextChained();
            var chainedHeader2   = fakeHeaders.NextChained();
            var chain            = Chain.CreateForGenesisBlock(chainedHeader0).ToBuilder();
            var emptyCoinbaseTx0 = BlockTx.Create(0, Transaction.Create(0, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0));
            var emptyCoinbaseTx1 = BlockTx.Create(0, Transaction.Create(1, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0));

            // initialize memory utxo builder storage
            var memoryStorage          = new MemoryStorageManager();
            var memoryChainStateCursor = memoryStorage.OpenChainStateCursor().Item;

            memoryChainStateCursor.BeginTransaction();

            // initialize utxo builder
            var utxoBuilder = new UtxoBuilder();

            // prepare an unspent transaction
            var txHash      = new UInt256(100);
            var unspentTx   = new UnspentTx(txHash, chainedHeader1.Height, 0, 0, false, 1, OutputState.Unspent);
            var txOutputKey = new TxOutputKey(txHash, 0);
            var txOutput    = new TxOutput(0, ImmutableArray <byte> .Empty);

            // add the unspent transaction
            memoryChainStateCursor.TryAddUnspentTx(unspentTx);
            memoryChainStateCursor.TryAddUnspentTxOutput(txOutputKey, txOutput);

            // create an input to spend the unspent transaction
            var input = new TxInput(txHash, 0, ImmutableArray.Create <byte>(), 0);
            var tx    = BlockTx.Create(1, Transaction.Create(0, ImmutableArray.Create(input), ImmutableArray.Create <TxOutput>(), 0));

            // spend the input
            chain.AddBlock(chainedHeader1);
            utxoBuilder.CalculateUtxo(memoryChainStateCursor, chain.ToImmutable(), new[] { emptyCoinbaseTx0, tx }.ToBufferBlock()).ToEnumerable().ToList();

            // verify utxo storage
            UnspentTx actualUnspentTx; TxOutput actualTxOutput;

            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTx(txHash, out actualUnspentTx));
            Assert.IsTrue(actualUnspentTx.IsFullySpent);
            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTxOutput(txOutputKey, out actualTxOutput));
            Assert.AreEqual(txOutput, actualTxOutput);

            // attempt to spend the input again, validation exception should be thrown
            chain.AddBlock(chainedHeader2);
            AssertMethods.AssertAggregateThrows <ValidationException>(() =>
                                                                      utxoBuilder.CalculateUtxo(memoryChainStateCursor, chain.ToImmutable(), new[] { emptyCoinbaseTx1, tx }.ToBufferBlock()).ToEnumerable().ToList());
        }
コード例 #26
0
ファイル: ChainBuilderTest.cs プロジェクト: cole2295/BitSharp
        public void TestCreateFromEnumerable()
        {
            // create a chain
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();
            var header1 = fakeHeaders.NextChained();

            // create builder from enumerable
            var chainBuilder = new ChainBuilder(new[] { header0, header1 });

            // verify
            CollectionAssert.AreEqual(new[] { header0, header1 }, chainBuilder.Blocks);
            CollectionAssert.AreEquivalent(new Dictionary<UInt256, ChainedHeader> { { header0.Hash, header0 }, { header1.Hash, header1 } }, chainBuilder.BlocksByHash);
        }
コード例 #27
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);
        }
コード例 #28
0
        public void TestCreateFromEnumerable()
        {
            // create a chain
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();
            var header1     = fakeHeaders.NextChained();

            // create builder from enumerable
            var chainBuilder = new ChainBuilder(new[] { header0, header1 });

            // verify
            CollectionAssert.AreEqual(new[] { header0, header1 }, chainBuilder.Blocks);
            CollectionAssert.AreEquivalent(new Dictionary <UInt256, ChainedHeader> {
                { header0.Hash, header0 }, { header1.Hash, header1 }
            }, chainBuilder.BlocksByHash);
        }
コード例 #29
0
        private void TestCommitTransaction(ITestStorageProvider provider)
        {
            var fakeHeaders    = new FakeHeaders();
            var chainedHeader0 = fakeHeaders.GenesisChained();
            var unspentTx      = new UnspentTx(txHash: 0, blockIndex: 0, txIndex: 0, outputStates: new OutputStates(1, OutputState.Unspent));
            var spentTxes      = ImmutableList.Create(new SpentTx(txHash: 1, confirmedBlockIndex: 0, txIndex: 0, outputCount: 1, spentBlockIndex: 0));

            using (var storageManager = provider.OpenStorageManager())
                using (var handle = storageManager.OpenChainStateCursor())
                {
                    var chainStateCursor = handle.Item;

                    // begin transaction
                    chainStateCursor.BeginTransaction();

                    // add data
                    chainStateCursor.AddChainedHeader(chainedHeader0);
                    chainStateCursor.TryAddUnspentTx(unspentTx);
                    chainStateCursor.TryAddBlockSpentTxes(0, spentTxes);

                    // verify data
                    Assert.AreEqual(chainedHeader0, chainStateCursor.GetChainTip());
                    Assert.AreEqual(1, chainStateCursor.UnspentTxCount);

                    UnspentTx actualUnspentTx;
                    Assert.IsTrue(chainStateCursor.TryGetUnspentTx(unspentTx.TxHash, out actualUnspentTx));
                    Assert.AreEqual(unspentTx, actualUnspentTx);

                    IImmutableList <SpentTx> actualSpentTxes;
                    Assert.IsTrue(chainStateCursor.TryGetBlockSpentTxes(0, out actualSpentTxes));
                    CollectionAssert.AreEqual((ICollection)spentTxes, (ICollection)actualSpentTxes);

                    // commit transaction
                    chainStateCursor.CommitTransaction();

                    // verify data
                    Assert.AreEqual(chainedHeader0, chainStateCursor.GetChainTip());
                    Assert.AreEqual(1, chainStateCursor.UnspentTxCount);

                    Assert.IsTrue(chainStateCursor.TryGetUnspentTx(unspentTx.TxHash, out actualUnspentTx));
                    Assert.AreEqual(unspentTx, actualUnspentTx);

                    Assert.IsTrue(chainStateCursor.TryGetBlockSpentTxes(0, out actualSpentTxes));
                    CollectionAssert.AreEqual((ICollection)spentTxes, (ICollection)actualSpentTxes);
                }
        }
コード例 #30
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));
        }
コード例 #31
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));
        }
コード例 #32
0
        public void TestDoubleSpend()
        {
            // prepare block
            var fakeHeaders = new FakeHeaders();
            var chainedHeader0 = fakeHeaders.GenesisChained();
            var chainedHeader1 = fakeHeaders.NextChained();
            var chainedHeader2 = fakeHeaders.NextChained();
            var chain = Chain.CreateForGenesisBlock(chainedHeader0).ToBuilder();
            var emptyCoinbaseTx0 = new BlockTx(0, new Transaction(0, ImmutableArray.Create<TxInput>(), ImmutableArray.Create<TxOutput>(), 0));
            var emptyCoinbaseTx1 = new BlockTx(0, new Transaction(1, ImmutableArray.Create<TxInput>(), ImmutableArray.Create<TxOutput>(), 0));

            // initialize memory utxo builder storage
            var memoryStorage = new MemoryStorageManager();
            var memoryChainStateCursor = memoryStorage.OpenChainStateCursor().Item;
            memoryChainStateCursor.BeginTransaction();

            // initialize utxo builder
            var utxoBuilder = new UtxoBuilder();

            // prepare an unspent transaction
            var txHash = new UInt256(100);
            var unspentTx = new UnspentTx(txHash, chainedHeader1.Height, 0, 1, OutputState.Unspent);

            // add the unspent transaction
            memoryChainStateCursor.TryAddUnspentTx(unspentTx);

            // create an input to spend the unspent transaction
            var input = new TxInput(new TxOutputKey(txHash, txOutputIndex: 0), ImmutableArray.Create<byte>(), 0);
            var tx = new BlockTx(1, new Transaction(0, ImmutableArray.Create(input), ImmutableArray.Create<TxOutput>(), 0));

            // spend the input
            chain.AddBlock(chainedHeader1);
            utxoBuilder.CalculateUtxo(memoryChainStateCursor, chain.ToImmutable(), new[] { emptyCoinbaseTx0, tx }.ToBufferBlock()).ToEnumerable().ToList();

            // verify utxo storage
            UnspentTx actualUnspentTx;
            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTx(txHash, out actualUnspentTx));
            Assert.IsTrue(actualUnspentTx.IsFullySpent);

            // attempt to spend the input again, validation exception should be thrown
            chain.AddBlock(chainedHeader2);
            AssertMethods.AssertAggregateThrows<ValidationException>(() =>
                utxoBuilder.CalculateUtxo(memoryChainStateCursor, chain.ToImmutable(), new[] { emptyCoinbaseTx1, tx }.ToBufferBlock()).ToEnumerable().ToList());
        }
コード例 #33
0
        // IBlockStorage.FindMaxTotalWork
        private void TestFindMaxTotalWork(ITestStorageProvider provider)
        {
            using (var storageManager = provider.OpenStorageManager())
            {
                var blockStorage = storageManager.BlockStorage;

                // create chained headers
                var fakeHeaders    = new FakeHeaders();
                var chainedHeader0 = fakeHeaders.GenesisChained();
                var chainedHeader1 = fakeHeaders.NextChained();
                var chainedHeader2 = fakeHeaders.NextChained();

                // verify initial null state
                Assert.IsNull(blockStorage.FindMaxTotalWork());

                // add headers and verify max total work

                // 0
                blockStorage.TryAddChainedHeader(chainedHeader0);
                Assert.AreEqual(chainedHeader0, blockStorage.FindMaxTotalWork());

                // 1
                blockStorage.TryAddChainedHeader(chainedHeader1);
                Assert.AreEqual(chainedHeader1, blockStorage.FindMaxTotalWork());

                // 2
                blockStorage.TryAddChainedHeader(chainedHeader2);
                Assert.AreEqual(chainedHeader2, blockStorage.FindMaxTotalWork());

                // remove headers and verify max total work

                // 2
                blockStorage.TryRemoveChainedHeader(chainedHeader2.Hash);
                Assert.AreEqual(chainedHeader1, blockStorage.FindMaxTotalWork());

                // 1
                blockStorage.TryRemoveChainedHeader(chainedHeader1.Hash);
                Assert.AreEqual(chainedHeader0, blockStorage.FindMaxTotalWork());

                // 0
                blockStorage.TryRemoveChainedHeader(chainedHeader0.Hash);
                Assert.IsNull(blockStorage.FindMaxTotalWork());
            }
        }
コード例 #34
0
        // IBlockStorage.ReadChainedHeaders
        private void TestReadChainedHeaders(ITestStorageProvider provider)
        {
            using (var storageManager = provider.OpenStorageManager())
            {
                var blockStorage = storageManager.BlockStorage;

                // create chained headers
                var fakeHeaders    = new FakeHeaders();
                var chainedHeader0 = fakeHeaders.GenesisChained();
                var chainedHeader1 = fakeHeaders.NextChained();
                var chainedHeader2 = fakeHeaders.NextChained();

                // verify initial empty state
                Assert.AreEqual(0, blockStorage.ReadChainedHeaders().ToList().Count);

                // add headers and verify reading them

                // 0
                blockStorage.TryAddChainedHeader(chainedHeader0);
                CollectionAssert.AreEquivalent(new[] { chainedHeader0 }, blockStorage.ReadChainedHeaders().ToList());

                // 1
                blockStorage.TryAddChainedHeader(chainedHeader1);
                CollectionAssert.AreEquivalent(new[] { chainedHeader0, chainedHeader1 }, blockStorage.ReadChainedHeaders().ToList());

                // 2
                blockStorage.TryAddChainedHeader(chainedHeader2);
                CollectionAssert.AreEquivalent(new[] { chainedHeader0, chainedHeader1, chainedHeader2 }, blockStorage.ReadChainedHeaders().ToList());

                // remove headers and verify reading them

                // 2
                blockStorage.TryRemoveChainedHeader(chainedHeader2.Hash);
                CollectionAssert.AreEquivalent(new[] { chainedHeader0, chainedHeader1 }, blockStorage.ReadChainedHeaders().ToList());

                // 1
                blockStorage.TryRemoveChainedHeader(chainedHeader1.Hash);
                CollectionAssert.AreEquivalent(new[] { chainedHeader0 }, blockStorage.ReadChainedHeaders().ToList());

                // 0
                blockStorage.TryRemoveChainedHeader(chainedHeader0.Hash);
                Assert.AreEqual(0, blockStorage.ReadChainedHeaders().ToList().Count);
            }
        }
コード例 #35
0
        public void TestGenesisBlock()
        {
            var fakeHeaders = new FakeHeaders();
            var header0     = fakeHeaders.GenesisChained();
            var header1     = fakeHeaders.NextChained();

            var chainBuilder = new ChainBuilder();

            // verify genesis with 0 blocks
            Assert.IsNull(chainBuilder.GenesisBlock);

            // verify genesis with 1 block
            chainBuilder.AddBlock(header0);
            Assert.AreEqual(header0, chainBuilder.GenesisBlock);

            // verify genesis with 2 blocks
            chainBuilder.AddBlock(header1);
            Assert.AreEqual(header0, chainBuilder.GenesisBlock);
        }
コード例 #36
0
ファイル: ChainBuilderTest.cs プロジェクト: cole2295/BitSharp
        public void TestLastBlock()
        {
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();
            var header1 = fakeHeaders.NextChained();

            var chainBuilder = new ChainBuilder();

            // verify last block with 0 blocks
            Assert.IsNull(chainBuilder.LastBlock);

            // verify last block with 1 block
            chainBuilder.AddBlock(header0);
            Assert.AreEqual(header0, chainBuilder.LastBlock);

            // verify last block with 2 blocks
            chainBuilder.AddBlock(header1);
            Assert.AreEqual(header1, chainBuilder.LastBlock);
        }
コード例 #37
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());
        }
コード例 #38
0
ファイル: ChainTest.cs プロジェクト: cole2295/BitSharp
        public void TestHeight()
        {
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();
            var header1 = fakeHeaders.NextChained();

            var chainBuilder = new ChainBuilder();

            // verify height with 0 blocks
            var chainEmpty = chainBuilder.ToImmutable();
            Assert.AreEqual(-1, chainEmpty.Height);

            // verify height with 1 block
            chainBuilder.AddBlock(header0);
            var chain0 = chainBuilder.ToImmutable();
            Assert.AreEqual(0, chain0.Height);

            // verify height with 2 blocks
            chainBuilder.AddBlock(header1);
            var chain1 = chainBuilder.ToImmutable();
            Assert.AreEqual(1, chain1.Height);
        }
コード例 #39
0
ファイル: ChainTest.cs プロジェクト: cole2295/BitSharp
        public void TestGenesisBlock()
        {
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();
            var header1 = fakeHeaders.NextChained();

            var chainBuilder = new ChainBuilder();

            // verify genesis with 0 blocks
            var chainEmpty = chainBuilder.ToImmutable();
            Assert.IsNull(chainEmpty.GenesisBlock);

            // verify genesis with 1 block
            chainBuilder.AddBlock(header0);
            var chain0 = chainBuilder.ToImmutable();
            Assert.AreEqual(header0, chain0.GenesisBlock);

            // verify genesis with 2 blocks
            chainBuilder.AddBlock(header1);
            var chain1 = chainBuilder.ToImmutable();
            Assert.AreEqual(header0, chain1.GenesisBlock);
        }
コード例 #40
0
ファイル: ChainTest.cs プロジェクト: cole2295/BitSharp
        public void TestNavigateTowardsFunc()
        {
            // create chains
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();
            var header1 = fakeHeaders.NextChained();
            var header2 = fakeHeaders.NextChained();
            var header3 = fakeHeaders.NextChained();

            var chain0 = new ChainBuilder(new[] { header0, }).ToImmutable();
            var chain1 = new ChainBuilder(new[] { header0, header1, }).ToImmutable();
            var chain2 = new ChainBuilder(new[] { header0, header1, header2 }).ToImmutable();
            var chain3 = new ChainBuilder(new[] { header0, header1, header2, header3 }).ToImmutable();

            // the list of target chains to use, stays 1 ahead and then catches up with chain 3
            var targetStack = new Stack<Chain>(new[] { chain1, chain2, chain3, chain3 }.Reverse());

            // verify navigating towards an updating chain
            CollectionAssert.AreEqual(
                new[]
                {
                    Tuple.Create(+1, header1),
                    Tuple.Create(+1, header2),
                    Tuple.Create(+1, header3)
                }
                , chain0.NavigateTowards(() => targetStack.Pop()).ToList());

            // verify all targets used
            Assert.AreEqual(0, targetStack.Count);
        }
コード例 #41
0
        private void TestTransactionIsolation(ITestStorageProvider provider)
        {
            var fakeHeaders = new FakeHeaders();
            var chainedHeader0 = fakeHeaders.GenesisChained();

            // open two chain state cursors
            using (var storageManager = provider.OpenStorageManager())
            using (var txBeganEvent = new ManualResetEventSlim())
            using (var headerAddedEvent = new ManualResetEventSlim())
            using (var doCommitEvent = new ManualResetEventSlim())
            using (var committedEvent = new ManualResetEventSlim())
            {
                var thread1 = new Thread(() =>
                {
                    using (var handle1 = storageManager.OpenChainStateCursor())
                    {
                        var chainStateCursor1 = handle1.Item;

                        // open transactions on cusor 1
                        chainStateCursor1.BeginTransaction();

                        // add a header on cursor 1
                        chainStateCursor1.ChainTip = chainedHeader0;

                        // alert header has been added
                        headerAddedEvent.Set();

                        doCommitEvent.Wait();

                        // commit transaction on cursor 1
                        chainStateCursor1.CommitTransaction();

                        // alert transaction has been committed
                        committedEvent.Set();
                    }
                });
                thread1.Start();

                // wait for header to be added on cursor 1
                headerAddedEvent.Wait();

                using (var handle2 = storageManager.OpenChainStateCursor())
                {
                    var chainStateCursor2 = handle2.Item;

                    // open transactions on cusor 2
                    chainStateCursor2.BeginTransaction(readOnly: true);

                    // verify empty chain
                    Assert.IsNull(chainStateCursor2.ChainTip);

                    doCommitEvent.Set();
                    committedEvent.Wait();

                    // verify empty chain
                    Assert.IsNull(chainStateCursor2.ChainTip);

                    chainStateCursor2.CommitTransaction();
                    chainStateCursor2.BeginTransaction();

                    // verify cursor 2 now sees the new header
                    Assert.AreEqual(chainedHeader0, chainStateCursor2.ChainTip);

                    chainStateCursor2.RollbackTransaction();
                }

                thread1.Join();
            }
        }
コード例 #42
0
ファイル: ChainTest.cs プロジェクト: cole2295/BitSharp
        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());
        }
コード例 #43
0
ファイル: ChainTest.cs プロジェクト: cole2295/BitSharp
        public void TestNavigateTowardsEmpty()
        {
            // create chain
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();
            var header1 = fakeHeaders.NextChained();
            var header2 = fakeHeaders.NextChained();

            var chainEmpty = new ChainBuilder().ToImmutable();
            var chain = new ChainBuilder(new[] { header0, header1, header2 }).ToImmutable();

            // verify chaining to empty does nothing
            Assert.AreEqual(0, chainEmpty.NavigateTowards(chainEmpty).Count());
            Assert.AreEqual(0, chain.NavigateTowards(chainEmpty).Count());

            // verify path from empty chain to chain
            CollectionAssert.AreEqual(
                new[]
                {
                    Tuple.Create(+1, header0),
                    Tuple.Create(+1, header1),
                    Tuple.Create(+1, header2)
                }
                , chainEmpty.NavigateTowards(chain).ToList());
        }
コード例 #44
0
ファイル: ChainBuilderTest.cs プロジェクト: cole2295/BitSharp
        public void TestBlocks()
        {
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();
            var header1 = fakeHeaders.NextChained();

            var chainBuilder = new ChainBuilder();

            // verify block list with 0 blocks
            Assert.AreEqual(0, chainBuilder.Blocks.Count);

            // verify block list with 1 block
            chainBuilder.AddBlock(header0);
            CollectionAssert.AreEqual(new[] { header0 }, chainBuilder.Blocks);

            // verify block list with 2 blocks
            chainBuilder.AddBlock(header1);
            CollectionAssert.AreEqual(new[] { header0, header1 }, chainBuilder.Blocks);
        }
コード例 #45
0
ファイル: ChainTest.cs プロジェクト: cole2295/BitSharp
        public void TestCreateForGenesisBlock()
        {
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();

            var chain = Chain.CreateForGenesisBlock(header0);

            CollectionAssert.AreEqual(new[] { header0 }, chain.Blocks);
        }
コード例 #46
0
ファイル: UtxoBuilderTest.cs プロジェクト: cole2295/BitSharp
        public void TestSimpleSpend()
        {
            // prepare block
            var fakeHeaders = new FakeHeaders();
            var chainedHeader0 = fakeHeaders.GenesisChained();
            var chainedHeader1 = fakeHeaders.NextChained();
            var chainedHeader2 = fakeHeaders.NextChained();
            var chainedHeader3 = fakeHeaders.NextChained();
            var chain = Chain.CreateForGenesisBlock(chainedHeader0).ToBuilder();
            var emptyCoinbaseTx0 = BlockTx.Create(0, Transaction.Create(0, ImmutableArray.Create<TxInput>(), ImmutableArray.Create<TxOutput>(), 0));
            var emptyCoinbaseTx1 = BlockTx.Create(1, Transaction.Create(1, ImmutableArray.Create<TxInput>(), ImmutableArray.Create<TxOutput>(), 0));
            var emptyCoinbaseTx2 = BlockTx.Create(2, Transaction.Create(2, ImmutableArray.Create<TxInput>(), ImmutableArray.Create<TxOutput>(), 0));

            // initialize memory utxo builder storage
            var memoryStorage = new MemoryStorageManager();
            var memoryChainStateCursor = memoryStorage.OpenChainStateCursor().Item;
            memoryChainStateCursor.BeginTransaction();

            // initialize utxo builder
            var utxoBuilder = new UtxoBuilder();

            // prepare an unspent transaction
            var txHash = new UInt256(100);
            var unspentTx = new UnspentTx(txHash, chainedHeader1.Height, 0, 0, false, 3, OutputState.Unspent);
            var txOutput1Key = new TxOutputKey(txHash, 0);
            var txOutput1 = new TxOutput(0, ImmutableArray<byte>.Empty);
            var txOutput2Key = new TxOutputKey(txHash, 1);
            var txOutput2 = new TxOutput(1, ImmutableArray<byte>.Empty);
            var txOutput3Key = new TxOutputKey(txHash, 2);
            var txOutput3 = new TxOutput(2, ImmutableArray<byte>.Empty);

            // prepare unspent output
            var unspentTransactions = ImmutableDictionary.Create<UInt256, UnspentTx>().Add(txHash, unspentTx);

            // add the unspent transaction
            memoryChainStateCursor.TryAddUnspentTx(unspentTx);
            memoryChainStateCursor.TryAddUnspentTxOutput(txOutput1Key, txOutput1);
            memoryChainStateCursor.TryAddUnspentTxOutput(txOutput2Key, txOutput2);
            memoryChainStateCursor.TryAddUnspentTxOutput(txOutput3Key, txOutput3);

            // create an input to spend the unspent transaction's first output
            var input0 = new TxInput(txHash, 0, ImmutableArray.Create<byte>(), 0);
            var tx0 = BlockTx.Create(1, Transaction.Create(0, ImmutableArray.Create(input0), ImmutableArray.Create<TxOutput>(), 0));

            // spend the input
            chain.AddBlock(chainedHeader1);
            utxoBuilder.CalculateUtxo(memoryChainStateCursor, chain.ToImmutable(), new[] { emptyCoinbaseTx0, tx0 }.ToBufferBlock()).ToEnumerable().ToList();

            // verify utxo storage
            UnspentTx actualUnspentTx; TxOutput actualTxOutput;
            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTx(txHash, out actualUnspentTx));
            Assert.IsTrue(actualUnspentTx.OutputStates.Length == 3);
            Assert.IsTrue(actualUnspentTx.OutputStates[0] == OutputState.Spent);
            Assert.IsTrue(actualUnspentTx.OutputStates[1] == OutputState.Unspent);
            Assert.IsTrue(actualUnspentTx.OutputStates[2] == OutputState.Unspent);

            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTxOutput(txOutput1Key, out actualTxOutput));
            Assert.AreEqual(txOutput1, actualTxOutput);
            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTxOutput(txOutput2Key, out actualTxOutput));
            Assert.AreEqual(txOutput2, actualTxOutput);
            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTxOutput(txOutput3Key, out actualTxOutput));
            Assert.AreEqual(txOutput3, actualTxOutput);

            // create an input to spend the unspent transaction's second output
            var input1 = new TxInput(txHash, 1, ImmutableArray.Create<byte>(), 0);
            var tx1 = BlockTx.Create(1, Transaction.Create(0, ImmutableArray.Create(input1), ImmutableArray.Create<TxOutput>(), 0));

            // spend the input
            chain.AddBlock(chainedHeader2);
            utxoBuilder.CalculateUtxo(memoryChainStateCursor, chain.ToImmutable(), new[] { emptyCoinbaseTx1, tx1 }.ToBufferBlock()).ToEnumerable().ToList();

            // verify utxo storage
            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTx(txHash, out actualUnspentTx));
            Assert.IsTrue(actualUnspentTx.OutputStates.Length == 3);
            Assert.IsTrue(actualUnspentTx.OutputStates[0] == OutputState.Spent);
            Assert.IsTrue(actualUnspentTx.OutputStates[1] == OutputState.Spent);
            Assert.IsTrue(actualUnspentTx.OutputStates[2] == OutputState.Unspent);

            // create an input to spend the unspent transaction's third output
            var input2 = new TxInput(txHash, 2, ImmutableArray.Create<byte>(), 0);
            var tx2 = BlockTx.Create(2, Transaction.Create(0, ImmutableArray.Create(input2), ImmutableArray.Create<TxOutput>(), 0));

            // spend the input
            chain.AddBlock(chainedHeader3);
            utxoBuilder.CalculateUtxo(memoryChainStateCursor, chain.ToImmutable(), new[] { emptyCoinbaseTx2, tx2 }.ToBufferBlock()).ToEnumerable().ToList();

            // verify utxo storage
            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTx(txHash, out actualUnspentTx));
            Assert.IsTrue(actualUnspentTx.IsFullySpent);
        }
コード例 #47
0
        private void TestContainsHeader(ITestStorageProvider provider)
        {
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();
            var header1 = fakeHeaders.NextChained();

            using (var storageManager = provider.OpenStorageManager())
            using (var handle = storageManager.OpenChainStateCursor())
            {
                var chainStateCursor = handle.Item;

                // begin transaction
                chainStateCursor.BeginTransaction();

                // verify presence
                Assert.IsFalse(chainStateCursor.ContainsHeader(header0.Hash));
                Assert.IsFalse(chainStateCursor.ContainsHeader(header1.Hash));

                // add header 0
                chainStateCursor.TryAddHeader(header0);

                // verify presence
                Assert.IsTrue(chainStateCursor.ContainsHeader(header0.Hash));
                Assert.IsFalse(chainStateCursor.ContainsHeader(header1.Hash));

                // add header 1
                chainStateCursor.TryAddHeader(header1);

                // verify presence
                Assert.IsTrue(chainStateCursor.ContainsHeader(header0.Hash));
                Assert.IsTrue(chainStateCursor.ContainsHeader(header1.Hash));

                // remove header 1
                chainStateCursor.TryRemoveHeader(header1.Hash);

                // verify presence
                Assert.IsTrue(chainStateCursor.ContainsHeader(header0.Hash));
                Assert.IsFalse(chainStateCursor.ContainsHeader(header1.Hash));

                // remove header 0
                chainStateCursor.TryRemoveHeader(header0.Hash);

                // verify presence
                Assert.IsFalse(chainStateCursor.ContainsHeader(header0.Hash));
                Assert.IsFalse(chainStateCursor.ContainsHeader(header1.Hash));
            }
        }
コード例 #48
0
ファイル: ChainBuilderTest.cs プロジェクト: cole2295/BitSharp
        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));
        }
コード例 #49
0
ファイル: ChainBuilderTest.cs プロジェクト: cole2295/BitSharp
        public void TestToImmutable()
        {
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();
            var header1 = fakeHeaders.NextChained();

            var chainBuilder = new ChainBuilder();

            // verify to builder with 0 blocks
            var chainEmpty = chainBuilder.ToImmutable();
            Assert.AreEqual(0, chainEmpty.Blocks.Count);
            Assert.AreEqual(0, chainEmpty.BlocksByHash.Count);

            // verify to builder with 1 block
            chainBuilder.AddBlock(header0);
            var chain0 = chainBuilder.ToImmutable();
            CollectionAssert.AreEqual(new[] { header0 }, chain0.Blocks);
            CollectionAssert.AreEquivalent(new Dictionary<UInt256, ChainedHeader> { { header0.Hash, header0 } }, chain0.BlocksByHash);

            // verify to builder with 2 blocks
            chainBuilder.AddBlock(header1);
            var chain1 = chainBuilder.ToImmutable();
            CollectionAssert.AreEqual(new[] { header0, header1 }, chain1.Blocks);
            CollectionAssert.AreEquivalent(new Dictionary<UInt256, ChainedHeader> { { header0.Hash, header0 }, { header1.Hash, header1 } }, chain1.BlocksByHash);
        }
コード例 #50
0
ファイル: ChainBuilderTest.cs プロジェクト: cole2295/BitSharp
        public void TestRemoveBlock()
        {
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();
            var header1 = fakeHeaders.NextChained();

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

            // remove header 1 and verify
            chainBuilder.RemoveBlock(header1);
            CollectionAssert.AreEqual(new[] { header0 }, chainBuilder.Blocks);
            CollectionAssert.AreEquivalent(new Dictionary<UInt256, ChainedHeader> { { header0.Hash, header0 } }, chainBuilder.BlocksByHash);

            // remove header 0 and verify
            chainBuilder.RemoveBlock(header0);
            Assert.AreEqual(0, chainBuilder.Blocks.Count);
            Assert.AreEqual(0, chainBuilder.BlocksByHash.Count);
        }
コード例 #51
0
ファイル: ChainBuilderTest.cs プロジェクト: cole2295/BitSharp
        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));
        }
コード例 #52
0
ファイル: ChainBuilderTest.cs プロジェクト: cole2295/BitSharp
        public void TestBlocksByHash()
        {
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();
            var header1 = fakeHeaders.NextChained();

            var chainBuilder = new ChainBuilder();

            // verify blocks dictionary with 0 blocks
            Assert.AreEqual(0, chainBuilder.BlocksByHash.Count);

            // verify blocks dictionary with 1 block
            chainBuilder.AddBlock(header0);
            CollectionAssert.AreEquivalent(new Dictionary<UInt256, ChainedHeader> { { header0.Hash, header0 } }, chainBuilder.BlocksByHash);

            // verify blocks dictionary with 2 blocks
            chainBuilder.AddBlock(header1);
            CollectionAssert.AreEquivalent(new Dictionary<UInt256, ChainedHeader> { { header0.Hash, header0 }, { header1.Hash, header1 } }, chainBuilder.BlocksByHash);
        }
コード例 #53
0
        private void TestChainTip(ITestStorageProvider provider)
        {
            var fakeHeaders = new FakeHeaders();
            var chainedHeader0 = fakeHeaders.GenesisChained();
            var chainedHeader1 = fakeHeaders.NextChained();

            using (var storageManager = provider.OpenStorageManager())
            using (var handle = storageManager.OpenChainStateCursor())
            {
                var chainStateCursor = handle.Item;

                // begin transaction
                chainStateCursor.BeginTransaction();

                // verify initial tip
                Assert.IsNull(chainStateCursor.ChainTip);

                // set tip
                chainStateCursor.ChainTip = chainedHeader0;

                // verify tip
                Assert.AreEqual(chainedHeader0, chainStateCursor.ChainTip);

                // set tip
                chainStateCursor.ChainTip = chainedHeader1;

                // verify tip
                Assert.AreEqual(chainedHeader1, chainStateCursor.ChainTip);
            }
        }
コード例 #54
0
ファイル: ChainTest.cs プロジェクト: cole2295/BitSharp
        public void TestReadChainWithGap()
        {
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();
            var header1 = fakeHeaders.NextChained();
            var header2 = fakeHeaders.NextChained();

            var chainedHeaders = new Dictionary<UInt256, ChainedHeader>();
            chainedHeaders.Add(header0.Hash, header0);
            chainedHeaders.Add(header2.Hash, header2);

            Chain chain;
            Assert.IsFalse(Chain.TryReadChain(header2.Hash, out chain,
                headerHash =>
                {
                    ChainedHeader chainedHeader;
                    chainedHeaders.TryGetValue(headerHash, out chainedHeader);
                    return chainedHeader;
                }));
        }
コード例 #55
0
        private void TestCommitTransaction(ITestStorageProvider provider)
        {
            var fakeHeaders = new FakeHeaders();
            var chainedHeader0 = fakeHeaders.GenesisChained();
            var unspentTx = new UnspentTx(txHash: UInt256.Zero, blockIndex: 0, txIndex: 0, outputStates: new OutputStates(1, OutputState.Spent));
            var spentTxes = BlockSpentTxes.CreateRange(new[] { unspentTx.ToSpentTx() });

            using (var storageManager = provider.OpenStorageManager())
            using (var handle = storageManager.OpenChainStateCursor())
            {
                var chainStateCursor = handle.Item;

                // begin transaction
                chainStateCursor.BeginTransaction();

                // add data
                chainStateCursor.ChainTip = chainedHeader0;
                chainStateCursor.TryAddUnspentTx(unspentTx);
                chainStateCursor.UnspentTxCount++;
                chainStateCursor.TryAddBlockSpentTxes(0, spentTxes);

                // verify data
                Assert.AreEqual(chainedHeader0, chainStateCursor.ChainTip);
                Assert.AreEqual(1, chainStateCursor.UnspentTxCount);

                UnspentTx actualUnspentTx;
                Assert.IsTrue(chainStateCursor.TryGetUnspentTx(unspentTx.TxHash, out actualUnspentTx));
                Assert.AreEqual(unspentTx, actualUnspentTx);

                BlockSpentTxes actualSpentTxes;
                Assert.IsTrue(chainStateCursor.TryGetBlockSpentTxes(0, out actualSpentTxes));
                CollectionAssert.AreEqual(spentTxes.ToList(), actualSpentTxes.ToList());

                // commit transaction
                chainStateCursor.CommitTransaction();

                chainStateCursor.BeginTransaction();

                // verify data
                Assert.AreEqual(chainedHeader0, chainStateCursor.ChainTip);
                Assert.AreEqual(1, chainStateCursor.UnspentTxCount);

                Assert.IsTrue(chainStateCursor.TryGetUnspentTx(unspentTx.TxHash, out actualUnspentTx));
                Assert.AreEqual(unspentTx, actualUnspentTx);

                Assert.IsTrue(chainStateCursor.TryGetBlockSpentTxes(0, out actualSpentTxes));
                CollectionAssert.AreEqual(spentTxes.ToList(), actualSpentTxes.ToList());

                chainStateCursor.RollbackTransaction();
            }
        }
コード例 #56
0
ファイル: ChainTest.cs プロジェクト: cole2295/BitSharp
        public void TestReadChain()
        {
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();
            var header1 = fakeHeaders.NextChained();
            var header2 = fakeHeaders.NextChained();

            var chainedHeaders = new Dictionary<UInt256, ChainedHeader>();
            chainedHeaders.Add(header0.Hash, header0);
            chainedHeaders.Add(header1.Hash, header1);
            chainedHeaders.Add(header2.Hash, header2);

            Chain chain;
            Assert.IsTrue(Chain.TryReadChain(header2.Hash, out chain,
                headerHash =>
                {
                    ChainedHeader chainedHeader;
                    chainedHeaders.TryGetValue(headerHash, out chainedHeader);
                    return chainedHeader;
                }));

            CollectionAssert.AreEqual(fakeHeaders.ChainedHeaders, chain.Blocks);
        }
コード例 #57
0
        private void TestRollbackTransaction(ITestStorageProvider provider)
        {
            var fakeHeaders = new FakeHeaders();
            var chainedHeader0 = fakeHeaders.GenesisChained();
            var chainedHeader1 = fakeHeaders.NextChained();
            var chainedHeader2 = fakeHeaders.NextChained();

            var unspentTx = new UnspentTx(txHash: UInt256.Zero, blockIndex: 0, txIndex: 0, outputStates: new OutputStates(1, OutputState.Spent));
            var spentTxes = BlockSpentTxes.CreateRange(new[] { unspentTx.ToSpentTx() });

            using (var storageManager = provider.OpenStorageManager())
            using (var handle = storageManager.OpenChainStateCursor())
            {
                var chainStateCursor = handle.Item;

                // begin transaction
                chainStateCursor.BeginTransaction();

                // add header 0
                chainStateCursor.ChainTip = chainedHeader0;

                // verify chain
                Assert.AreEqual(chainedHeader0, chainStateCursor.ChainTip);

                // add unspent tx
                chainStateCursor.TryAddUnspentTx(unspentTx);
                chainStateCursor.UnspentTxCount++;

                // verify unspent tx
                Assert.IsTrue(chainStateCursor.ContainsUnspentTx(unspentTx.TxHash));
                Assert.AreEqual(1, chainStateCursor.UnspentTxCount);

                // add spent txes
                chainStateCursor.TryAddBlockSpentTxes(0, spentTxes);

                // verify spent txes
                BlockSpentTxes actualSpentTxes;
                Assert.IsTrue(chainStateCursor.TryGetBlockSpentTxes(0, out actualSpentTxes));
                CollectionAssert.AreEqual(spentTxes.ToList(), actualSpentTxes.ToList());

                // rollback transaction
                chainStateCursor.RollbackTransaction();

                chainStateCursor.BeginTransaction();

                // verify chain
                Assert.IsNull(chainStateCursor.ChainTip);

                // verify unspent tx
                Assert.IsFalse(chainStateCursor.ContainsUnspentTx(unspentTx.TxHash));
                Assert.AreEqual(0, chainStateCursor.UnspentTxCount);

                // verify spent txes
                Assert.IsFalse(chainStateCursor.TryGetBlockSpentTxes(0, out actualSpentTxes));

                chainStateCursor.RollbackTransaction();
            }
        }
コード例 #58
0
ファイル: ChainBuilderTest.cs プロジェクト: cole2295/BitSharp
        public void TestTotalWork()
        {
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();
            var header1 = fakeHeaders.NextChained();
            var totalWork0 = DataCalculator.CalculateWork(header0);
            var totalWork1 = totalWork0 + DataCalculator.CalculateWork(header1);

            var chainBuilder = new ChainBuilder();

            // verify total work with 0 blocks
            Assert.AreEqual(0, chainBuilder.TotalWork);

            // verify total work with 1 block
            chainBuilder.AddBlock(header0);
            Assert.AreEqual(totalWork0, chainBuilder.TotalWork);

            // verify total work with 2 blocks
            chainBuilder.AddBlock(header1);
            Assert.AreEqual(totalWork1, chainBuilder.TotalWork);
        }
コード例 #59
0
        private void TestTryAddGetRemoveHeader(ITestStorageProvider provider)
        {
            var fakeHeaders = new FakeHeaders();
            var header0 = fakeHeaders.GenesisChained();
            var header1 = fakeHeaders.NextChained();

            using (var storageManager = provider.OpenStorageManager())
            using (var handle = storageManager.OpenChainStateCursor())
            {
                var chainStateCursor = handle.Item;

                // begin transaction
                chainStateCursor.BeginTransaction();

                // verify initial empty state
                ChainedHeader actualHeader0, actualHeader1;
                Assert.IsFalse(chainStateCursor.TryGetHeader(header0.Hash, out actualHeader0));
                Assert.IsFalse(chainStateCursor.TryGetHeader(header0.Hash, out actualHeader1));

                // add header 0
                Assert.IsTrue(chainStateCursor.TryAddHeader(header0));

                // verify unspent txes
                Assert.IsTrue(chainStateCursor.TryGetHeader(header0.Hash, out actualHeader0));
                Assert.AreEqual(header0, actualHeader0);
                Assert.IsFalse(chainStateCursor.TryGetHeader(header1.Hash, out actualHeader1));

                // add header 1
                Assert.IsTrue(chainStateCursor.TryAddHeader(header1));

                // verify unspent txes
                Assert.IsTrue(chainStateCursor.TryGetHeader(header0.Hash, out actualHeader0));
                Assert.AreEqual(header0, actualHeader0);
                Assert.IsTrue(chainStateCursor.TryGetHeader(header1.Hash, out actualHeader1));
                Assert.AreEqual(header1, actualHeader1);

                // remove header 1
                Assert.IsTrue(chainStateCursor.TryRemoveHeader(header1.Hash));

                // verify unspent txes
                Assert.IsTrue(chainStateCursor.TryGetHeader(header0.Hash, out actualHeader0));
                Assert.AreEqual(header0, actualHeader0);
                Assert.IsFalse(chainStateCursor.TryGetHeader(header1.Hash, out actualHeader1));

                // remove header 0
                Assert.IsTrue(chainStateCursor.TryRemoveHeader(header0.Hash));

                // verify unspent txes
                Assert.IsFalse(chainStateCursor.TryGetHeader(header0.Hash, out actualHeader0));
                Assert.IsFalse(chainStateCursor.TryGetHeader(header1.Hash, out actualHeader1));
            }
        }
コード例 #60
0
ファイル: ChainTest.cs プロジェクト: cole2295/BitSharp
        public void TestNavigateTowards()
        {
            // create forked chains
            var fakeHeadersA = new FakeHeaders();
            var header0 = fakeHeadersA.GenesisChained();
            var header1 = fakeHeadersA.NextChained();

            var fakeHeadersB = new FakeHeaders(fakeHeadersA);
            var header2A = fakeHeadersA.NextChained();
            var header3A = fakeHeadersA.NextChained();
            var header4A = fakeHeadersA.NextChained();
            var header2B = fakeHeadersB.NextChained();
            var header3B = fakeHeadersB.NextChained();
            var header4B = fakeHeadersB.NextChained();

            var chain0 = new ChainBuilder(new[] { header0, header1, header2A, header3A }).ToImmutable();
            var chain1 = new ChainBuilder(new[] { header0, header1, header2B, header3B, header4B }).ToImmutable();

            // verify path from chain 0 to chain 1
            CollectionAssert.AreEqual(
                new[]
                {
                    Tuple.Create(-1, header3A),
                    Tuple.Create(-1, header2A),
                    Tuple.Create(+1, header2B),
                    Tuple.Create(+1, header3B),
                    Tuple.Create(+1, header4B)
                }
                , chain0.NavigateTowards(chain1).ToList());

            // verify path from chain 1 to chain 0
            CollectionAssert.AreEqual(
                new[]
                {
                    Tuple.Create(-1, header4B),
                    Tuple.Create(-1, header3B),
                    Tuple.Create(-1, header2B),
                    Tuple.Create(+1, header2A),
                    Tuple.Create(+1, header3A)
                }
                , chain1.NavigateTowards(chain0).ToList());
        }