Пример #1
0
        private ConsensusPayload MakeSignedPayload(ConsensusMessage message)
        {
            message.ViewNumber = ViewNumber;
            ConsensusPayload payload = new ConsensusPayload
            {
                Version        = Version,
                PrevHash       = PrevHash,
                BlockIndex     = BlockIndex,
                ValidatorIndex = (ushort)MyIndex,
                Timestamp      = Timestamp,
                Data           = message.ToArray()
            };

            SignPayload(payload);
            return(payload);
        }
Пример #2
0
        public static ConsensusMessage DeserializeFrom(byte[] data)
        {
            ConsensusMessage message = ReflectionCache.CreateInstance <ConsensusMessage>(data[0]);

            if (message == null)
            {
                throw new FormatException();
            }

            using (MemoryStream ms = new MemoryStream(data, false))
                using (BinaryReader r = new BinaryReader(ms))
                {
                    message.Deserialize(r);
                }
            return(message);
        }
Пример #3
0
        public static ConsensusMessage DeserializeFrom(byte[] data)
        {
            ConsensusMessageType type = (ConsensusMessageType)data[0];

            if (!Enum.IsDefined(typeof(ConsensusMessageType), type))
            {
                throw new FormatException();
            }
            string           typeName = $"{typeof(ConsensusMessage).Namespace}.{type}";
            ConsensusMessage message  = typeof(ConsensusMessage).GetTypeInfo().Assembly.CreateInstance(typeName) as ConsensusMessage;

            using (MemoryStream ms = new MemoryStream(data, false))
                using (BinaryReader r = new BinaryReader(ms))
                {
                    message.Deserialize(r);
                }
            return(message);
        }
Пример #4
0
        public ExtensiblePayload CreatePayload(ConsensusMessage message, byte[] invocationScript = null)
        {
            ExtensiblePayload payload = new ExtensiblePayload
            {
                Category        = "dBFT",
                ValidBlockStart = 0,
                ValidBlockEnd   = message.BlockIndex,
                Sender          = GetSender(message.ValidatorIndex),
                Data            = message.ToArray(),
                Witness         = invocationScript is null ? null : new Witness
                {
                    InvocationScript   = invocationScript,
                    VerificationScript = Contract.CreateSignatureRedeemScript(Validators[message.ValidatorIndex])
                }
            };

            cachedMessages.TryAdd(payload.Hash, message);
            return(payload);
        }
Пример #5
0
        private void LocalNode_InventoryReceived(object sender, IInventory inventory)
        {
            ConsensusPayload payload = inventory as ConsensusPayload;

            if (payload != null)
            {
                lock (context)
                {
                    if (payload.ValidatorIndex == context.MyIndex)
                    {
                        return;
                    }
                    if (payload.Version != ConsensusContext.Version || payload.PrevHash != context.PrevHash || payload.BlockIndex != context.BlockIndex)
                    {
                        return;
                    }
                    if (payload.ValidatorIndex >= context.Validators.Length)
                    {
                        return;
                    }
                    ConsensusMessage message = ConsensusMessage.DeserializeFrom(payload.Data);
                    if (message.ViewNumber != context.ViewNumber && message.Type != ConsensusMessageType.ChangeView)
                    {
                        return;
                    }
                    switch (message.Type)
                    {
                    case ConsensusMessageType.ChangeView:
                        OnChangeViewReceived(payload, (ChangeView)message);
                        break;

                    case ConsensusMessageType.PerpareRequest:
                        OnPerpareRequestReceived(payload, (PerpareRequest)message);
                        break;

                    case ConsensusMessageType.PerpareResponse:
                        OnPerpareResponseReceived(payload, (PerpareResponse)message);
                        break;
                    }
                }
            }
        }
Пример #6
0
            public static PreparationPayloadCompact FromPayload(ConsensusPayload payload)
            {
                byte[]           StateRootSignature = Array.Empty <byte>();
                ConsensusMessage message            = payload.ConsensusMessage;

                if (message is PrepareRequest req)
                {
                    StateRootSignature = req.StateRootSignature;
                }
                else if (message is PrepareResponse resp)
                {
                    StateRootSignature = resp.StateRootSignature;
                }
                return(new PreparationPayloadCompact
                {
                    ValidatorIndex = payload.ValidatorIndex,
                    InvocationScript = payload.Witness.InvocationScript,
                    StateRootSignature = StateRootSignature
                });
            }
Пример #7
0
        private void LocalNode_InventoryReceived(object sender, IInventory inventory)
        {
            ConsensusPayload payload = inventory as ConsensusPayload;

            if (payload != null)
            {
                lock (context)
                {
                    if (payload.ValidatorIndex == context.MyIndex)
                    {
                        return;
                    }

                    if (payload.Version != ConsensusContext.Version)
                    {
                        return;
                    }
                    if (payload.PrevHash != context.PrevHash || payload.BlockIndex != context.BlockIndex)
                    {
                        // Request blocks

                        if (Blockchain.Default?.Height + 1 < payload.BlockIndex)
                        {
                            Log($"chain sync: expected={payload.BlockIndex} current: {Blockchain.Default?.Height}");

                            localNode.RequestGetBlocks();
                        }

                        return;
                    }

                    if (payload.ValidatorIndex >= context.Validators.Length)
                    {
                        return;
                    }
                    ConsensusMessage message;
                    try
                    {
                        message = ConsensusMessage.DeserializeFrom(payload.Data);
                    }
                    catch
                    {
                        return;
                    }
                    if (message.ViewNumber != context.ViewNumber && message.Type != ConsensusMessageType.ChangeView)
                    {
                        return;
                    }
                    switch (message.Type)
                    {
                    case ConsensusMessageType.ChangeView:
                        OnChangeViewReceived(payload, (ChangeView)message);
                        break;

                    case ConsensusMessageType.PrepareRequest:
                        OnPrepareRequestReceived(payload, (PrepareRequest)message);
                        break;

                    case ConsensusMessageType.PrepareResponse:
                        OnPrepareResponseReceived(payload, (PrepareResponse)message);
                        break;
                    }
                }
            }
        }