void Intercept(IncomingMessage message, Action act) { if (message.Node.State == NodeState.HandShaked) { message.Message.IfPayloadIs <HeadersPayload>(headers => { bool updated = false; foreach (var h in headers.Headers) { updated |= AddToChain(h); } if (updated) { message.Node.SendMessageAsync(new GetHeadersPayload() { BlockLocators = Chain.GetTipLocator() }); } }); message.Message.IfPayloadIs <InvPayload>(invs => { var needSync = invs.Where(v => v.Type == InventoryType.MSG_BLOCK) .Any(b => !_Chain.Contains(b.Hash)); if (needSync) { TrySync(); } }); } act(); }
public void CanBuildSlimChain() { var b0 = RandomUInt256(); SlimChain chain = new SlimChain(b0); var b1 = RandomUInt256(); Assert.Throws <ArgumentException>(() => chain.TrySetTip(b0, b0)); Assert.True(chain.TrySetTip(b1, b0)); var b2 = RandomUInt256(); Assert.True(chain.TrySetTip(b2, b1)); Assert.True(chain.TrySetTip(b2, b1)); Assert.Equal(b0, chain.Genesis); Assert.Equal(b2, chain.Tip); Assert.True(chain.Contains(b2)); Assert.Equal(2, chain.Height); Assert.False(chain.TrySetTip(b1, b0, true)); Assert.True(chain.TrySetTip(b1, b0, false)); Assert.Equal(b1, chain.Tip); Assert.False(chain.TryGetHeight(b2, out int height)); Assert.False(chain.Contains(b2)); Assert.True(chain.TryGetHeight(b1, out height)); Assert.Equal(1, height); Assert.True(chain.TrySetTip(b2, b1)); Assert.Throws <ArgumentException>(() => chain.TrySetTip(b1, b2)); // Incoherent Assert.Throws <ArgumentException>(() => chain.TrySetTip(b0, b1, true)); // Genesis block should not have previosu Assert.Throws <ArgumentException>(() => chain.TrySetTip(b0, b1, false)); Assert.True(chain.TrySetTip(b0, null)); Assert.Equal(0, chain.Height); Assert.True(chain.TrySetTip(b1, b0, true)); Assert.True(chain.TrySetTip(b2, b1)); var b3 = RandomUInt256(); var block = chain.GetBlock(b2); Assert.Equal(b2, block.Hash); Assert.Equal(b1, block.Previous); Assert.Equal(2, block.Height); Assert.Null(chain.GetBlock(b3)); block = chain.GetBlock(2); Assert.Equal(b2, block.Hash); Assert.Equal(b1, block.Previous); Assert.Equal(2, block.Height); Assert.Null(chain.GetBlock(3)); Assert.Null(chain.GetBlock(-1)); block = chain.GetBlock(0); Assert.Equal(b0, block.Hash); Assert.Null(block.Previous); Assert.Equal(0, block.Height); var chain2 = new SlimChain(RandomUInt256()); var ms = new MemoryStream(); chain.Save(ms); ms.Position = 0; // Not good genesis Assert.Throws <InvalidOperationException>(() => chain2.Load(ms)); chain2 = new SlimChain(b0); ms.Position = 0; chain2.Load(ms); Assert.Equal(chain.Tip, chain2.Tip); Assert.Equal(2, chain2.Height); }