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); }
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); }
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); }
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, chain0.TotalWork); // verify total work with 2 blocks chainBuilder.AddBlock(header1); var chain1 = chainBuilder.ToImmutable(); Assert.AreEqual(totalWork1, chain1.TotalWork); }
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); }
public static bool TryReadChain(UInt256 blockHash, out Chain chain, Func<UInt256, ChainedHeader> getChainedHeader) { // return an empty chain for null blockHash // when retrieving a chain by its tip, a null tip represents an empty chain if (blockHash == null) { chain = new ChainBuilder().ToImmutable(); return true; } var retrievedHeaders = new List<ChainedHeader>(); var chainedHeader = getChainedHeader(blockHash); if (chainedHeader != null) { var expectedHeight = chainedHeader.Height; do { if (chainedHeader.Height != expectedHeight) { chain = default(Chain); return false; } retrievedHeaders.Add(chainedHeader); expectedHeight--; } while (expectedHeight >= 0 && chainedHeader.PreviousBlockHash != chainedHeader.Hash && (chainedHeader = getChainedHeader(chainedHeader.PreviousBlockHash)) != null); if (retrievedHeaders.Last().Height != 0) { chain = default(Chain); return false; } var chainBuilder = new ChainBuilder(); for (var i = retrievedHeaders.Count - 1; i >= 0; i--) chainBuilder.AddBlock(retrievedHeaders[i]); chain = chainBuilder.ToImmutable(); return true; } else { chain = default(Chain); return false; } }
/// <summary> /// Create a new Chain instance consisting of a single genesis header. /// </summary> /// <param name="genesisBlock">The genesis header.</param> /// <returns>The Chain instance.</returns> public static Chain CreateForGenesisBlock(ChainedHeader genesisBlock) { var chainBuilder = new ChainBuilder(); chainBuilder.AddBlock(genesisBlock); return chainBuilder.ToImmutable(); }