示例#1
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);
        }
示例#2
0
        private ConsensusPayload MakeSignedPayload(ConsensusMessage message)
        {
            message.ViewNumber = ViewNumber;
            ConsensusPayload payload = new ConsensusPayload
            {
                Version        = Version,
                PrevHash       = PrevHash,
                ChainHash      = blockchain.ChainHash,
                BlockIndex     = BlockIndex,
                ValidatorIndex = (ushort)MyIndex,
                Timestamp      = Timestamp,
                Data           = message.ToArray()
            };

            SignPayload(payload);
            return(payload);
        }
示例#3
0
        private void OnConsensusPayload(ConsensusPayload payload)
        {
            if (payload.ValidatorIndex == context.MyIndex)
            {
                return;
            }
            if (payload.Version != ConsensusContext.Version)
            {
                return;
            }
            if (payload.PrevHash != context.PrevHash || payload.BlockIndex != context.BlockIndex)
            {
                if (context.BlockIndex != payload.BlockIndex)
                {
                    Log($"chain sync: expected={payload.BlockIndex} current={context.BlockIndex} nodes={localNodeObj.ConnectedCount}", LogLevel.Warning);

                    if (context.BlockIndex < payload.BlockIndex)
                    {
                        AddUnhandledPayloadToCache(payload);
                    }
                }
                if (payload.BlockIndex == context.BlockIndex && payload.PrevHash != context.PrevHash)
                {
                    Log($"block hash unmatched: sender={payload.ValidatorIndex} remote={payload.PrevHash} local={context.PrevHash}", LogLevel.Error);
                }
                return;
            }
            if (context.State.HasFlag(ConsensusState.BlockSent))
            {
                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;
            }
        }