public void CanForkSide() { PersistantChain side = new PersistantChain(Network.Main); PersistantChain main = new PersistantChain(Network.Main); AppendBlock(side, main); AppendBlock(side, main); var common = AppendBlock(side, main); var sideb = AppendBlock(side); var mainb1 = AppendBlock(main); var mainb2 = AppendBlock(main); var mainb3 = AppendBlock(main); Assert.Equal(common.HashBlock, side.SetTip(main.Tip).HashBlock); Assert.NotNull(side.GetBlock(mainb1.HashBlock)); Assert.NotNull(side.GetBlock(mainb2.HashBlock)); Assert.NotNull(side.GetBlock(mainb3.HashBlock)); Assert.NotNull(side.GetBlock(common.HashBlock)); Assert.Null(side.GetBlock(sideb.HashBlock)); Assert.Equal(common.HashBlock, side.SetTip(sideb).HashBlock); Assert.Null(side.GetBlock(mainb1.HashBlock)); Assert.Null(side.GetBlock(mainb2.HashBlock)); Assert.Null(side.GetBlock(mainb3.HashBlock)); Assert.NotNull(side.GetBlock(sideb.HashBlock)); }
public void BenchmarkCreateChainFromBlocks() { BlockStore store = new BlockStore(@"E:\Bitcoin\blocks\", Network.Main); PersistantChain chain = null; var fullBuild = Bench(() => { chain = store.BuildChain(); }); chain.Changes.Rewind(); var rebuildFromMemory = Bench(() => { var chain2 = new PersistantChain(chain.Changes); }); chain.Changes.Rewind(); var halfChain = new StreamObjectStream <ChainChange>(); for (int i = 0; i < 300000; i++) { halfChain.WriteNext(chain.Changes.ReadNext()); } var halfBuild = Bench(() => { var fullChain = store.BuildChain(halfChain); }); }
public void CanSaveChain() { var stream = new StreamObjectStream <ChainChange>(); PersistantChain chain = new PersistantChain(Network.Main, stream); AppendBlock(chain); AppendBlock(chain); var fork = AppendBlock(chain); AppendBlock(chain); stream.Rewind(); var chain2 = new PersistantChain(stream); Assert.True(chain.SameTip(chain2)); stream.WriteNext(new ChainChange() { ChangeType = ChainChangeType.BackStep, HeightOrBackstep = 1 }); stream.Rewind(); var chain3 = new PersistantChain(stream); AssertHeight(stream, 3); var actualFork = chain3.FindFork(chain); Assert.Equal(fork.HashBlock, actualFork.HashBlock); }
public void CanForkSidePartialChain() { var block = TestUtils.CreateFakeBlock(); PersistantChain side = new PersistantChain(block.Header, 10, new StreamObjectStream <ChainChange>()); PersistantChain main = new PersistantChain(block.Header, 10, new StreamObjectStream <ChainChange>()); AppendBlock(side, main); AppendBlock(side, main); var common = AppendBlock(side, main); var sideb = AppendBlock(side); var mainb1 = AppendBlock(main); var mainb2 = AppendBlock(main); var mainb3 = AppendBlock(main); Assert.Equal(common.HashBlock, side.SetTip(main.Tip).HashBlock); Assert.NotNull(side.GetBlock(mainb1.HashBlock)); Assert.NotNull(side.GetBlock(mainb2.HashBlock)); Assert.NotNull(side.GetBlock(mainb3.HashBlock)); Assert.NotNull(side.GetBlock(common.HashBlock)); Assert.Null(side.GetBlock(sideb.HashBlock)); Assert.Equal(common.HashBlock, side.SetTip(sideb).HashBlock); Assert.Null(side.GetBlock(mainb1.HashBlock)); Assert.Null(side.GetBlock(mainb2.HashBlock)); Assert.Null(side.GetBlock(mainb3.HashBlock)); Assert.NotNull(side.GetBlock(sideb.HashBlock)); }
public PersistantChain BuildChain(BlockHeader firstBlock, int height) { PersistantChain chain = new PersistantChain(); chain.Initialize(firstBlock, height); return(BuildChain(chain)); }
public PersistantChain GetChain(uint256 hashStop = null, CancellationToken cancellationToken = default(CancellationToken)) { var ms = new MemoryStream(); PersistantChain chain = new PersistantChain(Network, new StreamObjectStream <ChainChange>(ms)); SynchronizeChain(chain, hashStop, cancellationToken); return(chain); }
private ChainedBlock AddBlock(PersistantChain chain) { BlockHeader header = new BlockHeader(); header.Nonce = RandomUtils.GetUInt32(); header.HashPrevBlock = chain.Tip.HashBlock; chain.SetTip(header); return(chain.GetBlock(header.GetHash())); }
public static PersistantChain CreateBlockChain(List <Block> blocks) { PersistantChain chain = new PersistantChain(Network.Main.GetGenesis().Header); foreach (var b in blocks) { b.Header.HashPrevBlock = chain.Tip.Header.GetHash(); chain.TrySetTip(b.Header); } return(chain); }
public void CanBuildPartialChain() { PersistantChain chain = new PersistantChain(TestUtils.CreateFakeBlock().Header, 10, new StreamObjectStream <ChainChange>()); AppendBlock(chain); AppendBlock(chain); AppendBlock(chain); var b = AppendBlock(chain); Assert.Equal(14, chain.Height); Assert.Equal(14, b.Height); Assert.Equal(b.HashBlock, chain.Tip.HashBlock); }
public void CanBuildChain() { PersistantChain chain = new PersistantChain(Network.Main); AppendBlock(chain); AppendBlock(chain); AppendBlock(chain); var b = AppendBlock(chain); Assert.Equal(4, chain.Height); Assert.Equal(4, b.Height); Assert.Equal(b.HashBlock, chain.Tip.HashBlock); }
public void CanCalculateDifficulty() { var o = Network.Main.ProofOfWorkLimit; var main = new PersistantChain(LoadMainChain()); var histories = File.ReadAllText("data/targethistory.csv").Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (var history in histories) { var height = int.Parse(history.Split(',')[0]); var expectedTarget = new Target(BigInteger.Parse(history.Split(',')[1])); var block = main.GetBlock(height).Header; Assert.Equal(expectedTarget, block.Bits); var target = main.GetWorkRequired(Network.Main, height); Assert.Equal(expectedTarget, target); } }
public void CanSaveForkedBlockInChain() { var chain = new PersistantChain(Network.Main); var common = AppendBlock(chain); var fork = AppendBlock(chain); var fork2 = AppendBlock(common, chain); Assert.True(chain.Tip == fork); var chain2 = chain.Clone(); var newTip = AppendBlock(fork2, chain); Assert.True(chain.Tip == newTip); Assert.True(chain2.Tip == fork); newTip = AppendBlock(fork2, chain2); Assert.True(chain2.Tip == newTip); }
public void CanBuildConcurrentChain() { ConcurrentChain cchain = new ConcurrentChain(); PersistantChain chain = new PersistantChain(Network.Main); Assert.Null(cchain.SetTip(chain.Tip)); var b0 = cchain.Tip; Assert.Equal(cchain.Tip, chain.Tip); var b1 = AddBlock(chain); var b2 = AddBlock(chain); AddBlock(chain); AddBlock(chain); var b5 = AddBlock(chain); Assert.Equal(cchain.SetTip(chain.Tip), b0); Assert.Equal(cchain.Tip, chain.Tip); Assert.Equal(cchain.GetBlock(5), chain.Tip); Assert.Equal(cchain.GetBlock(b5.HashBlock), chain.Tip); Assert.Equal(cchain.SetTip(b1), b1); Assert.Equal(cchain.GetBlock(b5.HashBlock), null); Assert.Equal(cchain.GetBlock(b2.HashBlock), null); Assert.Equal(cchain.SetTip(b5), b1); Assert.Equal(cchain.GetBlock(b5.HashBlock), chain.Tip); chain.SetTip(b2); AddBlock(chain); AddBlock(chain); var b5b = AddBlock(chain); var b6b = AddBlock(chain); Assert.Equal(cchain.SetTip(b6b), b2); Assert.Equal(cchain.GetBlock(b5.HashBlock), null); Assert.Equal(cchain.GetBlock(b2.HashBlock), b2); Assert.Equal(cchain.GetBlock(6), b6b); Assert.Equal(cchain.GetBlock(5), b5b); }
public void CanForkBackwardPartialChain() { PersistantChain chain = new PersistantChain(TestUtils.CreateFakeBlock().Header, 10, new StreamObjectStream <ChainChange>()); AppendBlock(chain); AppendBlock(chain); var fork = AppendBlock(chain); //Test single block back fork var last = AppendBlock(chain); Assert.Equal(14, chain.Height); Assert.Equal(14, last.Height); Assert.Equal(last.HashBlock, chain.Tip.HashBlock); Assert.Equal(fork.HashBlock, chain.SetTip(fork).HashBlock); Assert.Equal(13, chain.Height); Assert.Equal(13, fork.Height); Assert.Equal(fork.HashBlock, chain.Tip.HashBlock); Assert.Null(chain.GetBlock(last.HashBlock)); Assert.NotNull(chain.GetBlock(fork.HashBlock)); //Test 3 blocks back fork var b1 = AppendBlock(chain); var b2 = AppendBlock(chain); last = AppendBlock(chain); Assert.Equal(16, chain.Height); Assert.Equal(16, last.Height); Assert.Equal(last.HashBlock, chain.Tip.HashBlock); Assert.Equal(fork.HashBlock, chain.SetTip(fork).HashBlock); Assert.Equal(13, chain.Height); Assert.Equal(13, fork.Height); Assert.Equal(fork.HashBlock, chain.Tip.HashBlock); Assert.Null(chain.GetBlock(last.HashBlock)); Assert.Null(chain.GetBlock(b1.HashBlock)); Assert.Null(chain.GetBlock(b2.HashBlock)); chain.SetTip(last); Assert.Equal(16, chain.Height); Assert.Equal(16, last.Height); Assert.Equal(last.HashBlock, chain.Tip.HashBlock); }
public void CanForkBackward() { PersistantChain chain = new PersistantChain(Network.Main); AppendBlock(chain); AppendBlock(chain); var fork = AppendBlock(chain); //Test single block back fork var last = AppendBlock(chain); Assert.Equal(4, chain.Height); Assert.Equal(4, last.Height); Assert.Equal(last.HashBlock, chain.Tip.HashBlock); Assert.Equal(fork.HashBlock, chain.SetTip(fork).HashBlock); Assert.Equal(3, chain.Height); Assert.Equal(3, fork.Height); Assert.Equal(fork.HashBlock, chain.Tip.HashBlock); Assert.Null(chain.GetBlock(last.HashBlock)); Assert.NotNull(chain.GetBlock(fork.HashBlock)); //Test 3 blocks back fork var b1 = AppendBlock(chain); var b2 = AppendBlock(chain); last = AppendBlock(chain); Assert.Equal(6, chain.Height); Assert.Equal(6, last.Height); Assert.Equal(last.HashBlock, chain.Tip.HashBlock); Assert.Equal(fork.HashBlock, chain.SetTip(fork).HashBlock); Assert.Equal(3, chain.Height); Assert.Equal(3, fork.Height); Assert.Equal(fork.HashBlock, chain.Tip.HashBlock); Assert.Null(chain.GetBlock(last.HashBlock)); Assert.Null(chain.GetBlock(b1.HashBlock)); Assert.Null(chain.GetBlock(b2.HashBlock)); chain.SetTip(last); Assert.Equal(6, chain.Height); Assert.Equal(6, last.Height); Assert.Equal(last.HashBlock, chain.Tip.HashBlock); }
public void CanBuildChainIncrementally() { StreamObjectStream <ChainChange> changes = new StreamObjectStream <ChainChange>(); PersistantChain main = new PersistantChain(Network.Main, changes); AppendBlock(main); AppendBlock(main); var forkPoint = AppendBlock(main); AssertHeight(changes, 3); AssertLength(changes, 4); var current = AppendBlock(forkPoint, main); var oldFork = AppendBlock(current, main); AssertHeight(changes, 5); AssertLength(changes, 6); current = AppendBlock(forkPoint, main); AssertHeight(changes, 5); AssertLength(changes, 7); current = AppendBlock(current, main); AssertHeight(changes, 5); AssertLength(changes, 8); current = AppendBlock(current, main); AssertHeight(changes, 6); //1 back track (retour à 3) + 1 set tip AssertLength(changes, 10); current = AppendBlock(oldFork, main); AssertHeight(changes, 6); AssertLength(changes, 11); //1 back track (retour à 3) + 1 set tip à 7 current = AppendBlock(current, main); AssertHeight(changes, 7); AssertLength(changes, 13); }
public void CanLoadAndSaveConcurrentChain() { ConcurrentChain cchain = new ConcurrentChain(); PersistantChain chain = new PersistantChain(Network.Main); AddBlock(chain); AddBlock(chain); AddBlock(chain); cchain.SetTip(chain); var bytes = cchain.ToBytes(); cchain = new ConcurrentChain(); cchain.Load(bytes); Assert.Equal(cchain.Tip, chain.Tip); Assert.NotNull(cchain.GetBlock(0)); cchain = new ConcurrentChain(Network.TestNet); cchain.Load(cchain.ToBytes()); Assert.NotNull(cchain.GetBlock(0)); }
public PersistantChain BuildChain(PersistantChain chain) { Dictionary <uint256, BlockHeader> headers = new Dictionary <uint256, BlockHeader>(); HashSet <uint256> inChain = new HashSet <uint256>(); inChain.Add(chain.GetBlock(chain.StartHeight).HashBlock); foreach (var header in Enumerate(true).Select(b => b.Item.Header)) { var hash = header.GetHash(); headers.Add(hash, header); } List <uint256> toRemove = new List <uint256>(); while (headers.Count != 0) { foreach (var header in headers) { if (inChain.Contains(header.Value.HashPrevBlock)) { toRemove.Add(header.Key); chain.TrySetTip(header.Value); inChain.Add(header.Key); } } foreach (var item in toRemove) { headers.Remove(item); } if (toRemove.Count == 0) { break; } toRemove.Clear(); } return(chain); }
public PersistantChain BuildChain(ObjectStream <ChainChange> changes) { PersistantChain chain = new PersistantChain(changes); return(BuildChain(chain)); }
List <ChainChange> EnumerateFromBeginning(PersistantChain chain) { chain.Changes.Rewind(); return(chain.Changes.Enumerate().ToList()); }