示例#1
0
        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();
        }
示例#2
0
        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);
        }