Exemplo n.º 1
0
 private static ConsensusPayload MakeSignedPayload(ConsensusContext context, ConsensusMessage message, ushort validatorIndex, byte[] witnessInvocationScript)
 {
     return(new ConsensusPayload
     {
         Version = context.Block.Version,
         PrevHash = context.Block.PrevHash,
         BlockIndex = context.Block.Index,
         ValidatorIndex = validatorIndex,
         ConsensusMessage = message,
         Witness = new Witness
         {
             InvocationScript = witnessInvocationScript,
             VerificationScript = Contract.CreateSignatureRedeemScript(context.Validators[validatorIndex])
         }
     });
 }
        public async virtual Task ProcessMessageAsync(ConsensusMessage msg)
        {
            //_log.LogInformation($"ProcessMessage {msg.MsgType} _state is null? {!IsStateCreated()}");
            if (msg is AuthorizingMsg || msg is ViewChangeRequestMessage)
            {
                await InternalProcessMessageAsync(msg);

                if (IsStateCreated())
                {
                    await ProcessQueueAsync();
                }
            }
            else if (!IsStateCreated())
            {
                _outOfOrderedMessages.Enqueue(msg);
            }
            else
            {
                await InternalProcessMessageAsync(msg);
                await ProcessQueueAsync();
            }
        }
Exemplo n.º 3
0
 public MessageEnvelope(ConsensusMessage msg, int validatorIndex)
 {
     ExternalMessage = msg;
     InternalMessage = null;
     ValidatorIndex  = validatorIndex;
 }
Exemplo n.º 4
0
        private void LocalNode_NewInventory(object sender, Inventory inventory)
        {
            ConsensusPayload payload = inventory as ConsensusPayload;

            if (payload != null)
            {
                lock (context)
                {
                    if (payload.MinerIndex == context.MinerIndex)
                    {
                        return;
                    }
                    if (payload.Version != ConsensusContext.Version || payload.PrevHash != context.PrevHash || payload.Height != context.Height)
                    {
                        return;
                    }
                    if (payload.MinerIndex >= context.Miners.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;
                    }
                }
            }
            Transaction tx = inventory as Transaction;

            if (tx != null)
            {
                lock (context)
                {
                    if (!context.State.HasFlag(ConsensusState.Backup) || !context.State.HasFlag(ConsensusState.RequestReceived) || context.State.HasFlag(ConsensusState.SignatureSent))
                    {
                        return;
                    }
                    if (context.Transactions.ContainsKey(tx.Hash))
                    {
                        return;
                    }
                    if (!context.TransactionHashes.Contains(tx.Hash))
                    {
                        return;
                    }
                    AddTransaction(tx);
                }
            }
        }
Exemplo n.º 5
0
 public NetworkMessage ConsensusMessage(ConsensusMessage message)
 {
     return(new NetworkMessage {
         ConsensusMessage = message
     });
 }
Exemplo n.º 6
0
        // Some protocols may stop due to null value in some of fields in the message. We discard such cases
        private bool ValidateMessage(ConsensusMessage message)
        {
            switch (message.PayloadCase)
            {
            case ConsensusMessage.PayloadOneofCase.Bval:
                // all fields have default values
                return(true);

            case ConsensusMessage.PayloadOneofCase.Aux:
                // all fields have default values
                return(true);

            case ConsensusMessage.PayloadOneofCase.Conf:
                // all fields have default values
                return(true);

            case ConsensusMessage.PayloadOneofCase.Coin:
                // all fields have default values
                return(true);

            case ConsensusMessage.PayloadOneofCase.Decrypted:
                // all fields have default values
                return(true);

            case ConsensusMessage.PayloadOneofCase.ValMessage:
                // merkleTreeRoot cannot be null
                if (message.ValMessage.MerkleTreeRoot is null)
                {
                    return(false);
                }
                return(true);

            case ConsensusMessage.PayloadOneofCase.EchoMessage:
                // merkleTreeRoot cannot be null
                if (message.EchoMessage.MerkleTreeRoot is null)
                {
                    return(false);
                }
                return(true);

            case ConsensusMessage.PayloadOneofCase.ReadyMessage:
                // merkleTreeRoot cannot be null
                if (message.ReadyMessage.MerkleTreeRoot is null)
                {
                    return(false);
                }
                return(true);

            case ConsensusMessage.PayloadOneofCase.SignedHeaderMessage:
                // BlockHeader or Signature cannot be null
                var header = message.SignedHeaderMessage.Header;
                if (header is null || message.SignedHeaderMessage.Signature is null)
                {
                    return(false);
                }
                // Check fields of BlockHeader: UInt256 cannot be null
                if (header.MerkleRoot is null || header.PrevBlockHash is null || header.StateHash is null)
                {
                    return(false);
                }
                return(true);

            default:
                return(false);
            }
        }
Exemplo n.º 7
0
        public void Dispatch(ConsensusMessage message, int from)
        {
            if (_terminated)
            {
                Logger.LogTrace($"Era {_era} is already finished, skipping Dispatch");
                return;
            }

            if (message.Validator.Era != _era)
            {
                throw new InvalidOperationException(
                          $"Message for era {message.Validator.Era} dispatched to era {_era}");
            }

            if (!ValidateMessage(message))
            {
                Logger.LogWarning(
                    $"Faulty behaviour: null value in required field of the consensus message from validator: {from}"
                    + $" ({GetPublicKeyById(from)!.ToHex()}). Discarding message as it could crash targeted protocol.");
                return;
            }

            switch (message.PayloadCase)
            {
            case ConsensusMessage.PayloadOneofCase.Bval:
                var idBval = new BinaryBroadcastId(message.Validator.Era, message.Bval.Agreement,
                                                   message.Bval.Epoch);
                EnsureProtocol(idBval)?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            case ConsensusMessage.PayloadOneofCase.Aux:
                var idAux = new BinaryBroadcastId(message.Validator.Era, message.Aux.Agreement, message.Aux.Epoch);
                EnsureProtocol(idAux)?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            case ConsensusMessage.PayloadOneofCase.Conf:
                var idConf = new BinaryBroadcastId(message.Validator.Era, message.Conf.Agreement,
                                                   message.Conf.Epoch);
                EnsureProtocol(idConf)?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            case ConsensusMessage.PayloadOneofCase.Coin:
                var idCoin = new CoinId(message.Validator.Era, message.Coin.Agreement, message.Coin.Epoch);
                EnsureProtocol(idCoin)?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            case ConsensusMessage.PayloadOneofCase.Decrypted:
                var hbbftId = new HoneyBadgerId((int)message.Validator.Era);
                EnsureProtocol(hbbftId)?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            case ConsensusMessage.PayloadOneofCase.ValMessage:
                var reliableBroadcastId = new ReliableBroadcastId(message.ValMessage.SenderId, (int)message.Validator.Era);
                EnsureProtocol(reliableBroadcastId)?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            case ConsensusMessage.PayloadOneofCase.EchoMessage:
                var rbIdEchoMsg = new ReliableBroadcastId(message.EchoMessage.SenderId, (int)message.Validator.Era);
                EnsureProtocol(rbIdEchoMsg)?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            case ConsensusMessage.PayloadOneofCase.ReadyMessage:
                var rbIdReadyMsg = new ReliableBroadcastId(message.ReadyMessage.SenderId, (int)message.Validator.Era);
                EnsureProtocol(rbIdReadyMsg)?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            case ConsensusMessage.PayloadOneofCase.SignedHeaderMessage:
                var rootId = new RootProtocolId(message.Validator.Era);
                EnsureProtocol(rootId)?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            default:
                throw new InvalidOperationException($"Unknown message type {message}");
            }
        }
Exemplo n.º 8
0
        public void ConsensusService_Primary_Sends_PrepareRequest_After_OnStart()
        {
            TestProbe subscriber = CreateTestProbe();

            var mockConsensusContext = new Mock <IConsensusContext>();

            // context.Reset(): do nothing
            //mockConsensusContext.Setup(mr => mr.Reset()).Verifiable(); // void
            mockConsensusContext.SetupGet(mr => mr.MyIndex).Returns(2); // MyIndex == 2
            mockConsensusContext.SetupGet(mr => mr.BlockIndex).Returns(2);
            mockConsensusContext.SetupGet(mr => mr.PrimaryIndex).Returns(2);
            mockConsensusContext.SetupGet(mr => mr.ViewNumber).Returns(0);
            mockConsensusContext.SetupProperty(mr => mr.Nonce);
            mockConsensusContext.SetupProperty(mr => mr.NextConsensus);
            mockConsensusContext.Object.NextConsensus = UInt160.Zero;
            mockConsensusContext.Setup(mr => mr.GetPrimaryIndex(It.IsAny <byte>())).Returns(2);
            mockConsensusContext.SetupProperty(mr => mr.State);  // allows get and set to update mock state on Initialize method
            mockConsensusContext.Object.State = ConsensusState.Initial;

            int timeIndex  = 0;
            var timeValues = new[] {
                new DateTime(1968, 06, 01, 0, 0, 15, DateTimeKind.Utc), // For tests here
                new DateTime(1968, 06, 01, 0, 0, 1, DateTimeKind.Utc),  // For receiving block
                new DateTime(1968, 06, 01, 0, 0, 15, DateTimeKind.Utc), // For Initialize
                new DateTime(1968, 06, 01, 0, 0, 15, DateTimeKind.Utc), // unused
                new DateTime(1968, 06, 01, 0, 0, 15, DateTimeKind.Utc)  // unused
            };

            Console.WriteLine($"time 0: {timeValues[0].ToString()} 1: {timeValues[1].ToString()} 2: {timeValues[2].ToString()} 3: {timeValues[3].ToString()}");

            //mockConsensusContext.Object.block_received_time = new DateTime(1968, 06, 01, 0, 0, 1, DateTimeKind.Utc);
            //mockConsensusContext.Setup(mr => mr.GetUtcNow()).Returns(new DateTime(1968, 06, 01, 0, 0, 15, DateTimeKind.Utc));

            var timeMock = new Mock <TimeProvider>();

            timeMock.SetupGet(tp => tp.UtcNow).Returns(() => timeValues[timeIndex])
            .Callback(() => timeIndex++);
            //new DateTime(1968, 06, 01, 0, 0, 15, DateTimeKind.Utc));
            TimeProvider.Current = timeMock.Object;

            //public void Log(string message, LogLevel level)
            // TODO: create ILogPlugin for Tests

            /*
             * mockConsensusContext.Setup(mr => mr.Log(It.IsAny<string>(), It.IsAny<LogLevel>()))
             *           .Callback((string message, LogLevel level) => {
             *                           Console.WriteLine($"CONSENSUS LOG: {message}");
             *                                                     }
             *                    );
             */

            // Creating proposed block
            Header header = new Header();

            TestUtils.SetupHeaderWithValues(header, UInt256.Zero, out UInt256 merkRootVal, out UInt160 val160, out uint timestampVal, out uint indexVal, out ulong consensusDataVal, out Witness scriptVal);
            header.Size.Should().Be(109);

            Console.WriteLine($"header {header} hash {header.Hash} timstamp {timestampVal}");

            timestampVal.Should().Be(4244941696);                              //1968-06-01 00:00:00
            TimeProvider.Current.UtcNow.ToTimestamp().Should().Be(4244941711); //1968-06-01 00:00:15
                                                                               // check basic ConsensusContext
            mockConsensusContext.Object.MyIndex.Should().Be(2);
            //mockConsensusContext.Object.block_received_time.ToTimestamp().Should().Be(4244941697); //1968-06-01 00:00:01

            MinerTransaction minerTx = new MinerTransaction
            {
                Attributes = new TransactionAttribute[0],
                Inputs     = new CoinReference[0],
                Outputs    = new TransactionOutput[0],
                Witnesses  = new Witness[0],
                Nonce      = 42
            };

            PrepareRequest prep = new PrepareRequest
            {
                Nonce             = mockConsensusContext.Object.Nonce,
                NextConsensus     = mockConsensusContext.Object.NextConsensus,
                TransactionHashes = new UInt256[0],
                MinerTransaction  = minerTx,     //(MinerTransaction)Transactions[TransactionHashes[0]],
                Signature         = new byte[64] //Signatures[MyIndex]
            };

            ConsensusMessage mprep = prep;

            byte[] prepData = mprep.ToArray();

            ConsensusPayload prepPayload = new ConsensusPayload
            {
                Version        = 0,
                PrevHash       = mockConsensusContext.Object.PrevHash,
                BlockIndex     = mockConsensusContext.Object.BlockIndex,
                ValidatorIndex = (ushort)mockConsensusContext.Object.MyIndex,
                Timestamp      = mockConsensusContext.Object.Timestamp,
                Data           = prepData
            };

            mockConsensusContext.Setup(mr => mr.MakePrepareRequest()).Returns(prepPayload);

            // ============================================================================
            //                      creating ConsensusService actor
            // ============================================================================

            TestActorRef <ConsensusService> actorConsensus = ActorOfAsTestActorRef <ConsensusService>(
                Akka.Actor.Props.Create(() => new ConsensusService(subscriber, subscriber, mockConsensusContext.Object))
                );

            Console.WriteLine("will trigger OnPersistCompleted!");

            actorConsensus.Tell(new Blockchain.PersistCompleted
            {
                Block = new Block
                {
                    Version       = header.Version,
                    PrevHash      = header.PrevHash,
                    MerkleRoot    = header.MerkleRoot,
                    Timestamp     = header.Timestamp,
                    Index         = header.Index,
                    ConsensusData = header.ConsensusData,
                    NextConsensus = header.NextConsensus
                }
            });

            //Console.WriteLine("will start consensus!");
            //actorConsensus.Tell(new ConsensusService.Start());

            Console.WriteLine("OnTimer should expire!");
            Console.WriteLine("Waiting for subscriber message!");

            var answer = subscriber.ExpectMsg <LocalNode.SendDirectly>();

            Console.WriteLine($"MESSAGE 1: {answer}");
            //var answer2 = subscriber.ExpectMsg<LocalNode.SendDirectly>(); // expects to fail!

            // ============================================================================
            //                      finalize ConsensusService actor
            // ============================================================================

            //Thread.Sleep(4000);
            Sys.Stop(actorConsensus);
            TimeProvider.ResetToDefault();

            Assert.AreEqual(1, 1);
        }
Exemplo n.º 9
0
        public void Dispatch(ConsensusMessage message, int from)
        {
            if (_silenced.Contains(from))
            {
                return;
            }
            if (_silenced.Contains(GetMyId()))
            {
                return;
            }

            switch (message.PayloadCase)
            {
            case ConsensusMessage.PayloadOneofCase.Bval:
                var idBval = new BinaryBroadcastId(message.Validator.Era, message.Bval.Agreement,
                                                   message.Bval.Epoch);
                CheckRequest(idBval);
                Registry[idBval]?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            case ConsensusMessage.PayloadOneofCase.Aux:
                var idAux = new BinaryBroadcastId(message.Validator.Era, message.Aux.Agreement, message.Aux.Epoch);
                CheckRequest(idAux);
                Registry[idAux]?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            case ConsensusMessage.PayloadOneofCase.Conf:
                var idConf = new BinaryBroadcastId(message.Validator.Era, message.Conf.Agreement,
                                                   message.Conf.Epoch);
                CheckRequest(idConf);
                Registry[idConf]?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            case ConsensusMessage.PayloadOneofCase.Coin:
                var idCoin = new CoinId(message.Validator.Era, message.Coin.Agreement, message.Coin.Epoch);
                CheckRequest(idCoin);
                Registry[idCoin]?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            case ConsensusMessage.PayloadOneofCase.Decrypted:
                var hbbftId = new HoneyBadgerId((int)message.Validator.Era);
                CheckRequest(hbbftId);
                Registry[hbbftId]?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            case ConsensusMessage.PayloadOneofCase.ReadyMessage:
                var rbIdReadyMsg =
                    new ReliableBroadcastId(message.ReadyMessage.SenderId, (int)message.Validator.Era);
                CheckRequest(rbIdReadyMsg);
                Registry[rbIdReadyMsg]?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            case ConsensusMessage.PayloadOneofCase.ValMessage:
                var reliableBroadcastId =
                    new ReliableBroadcastId(message.ValMessage.SenderId, (int)message.Validator.Era);
                CheckRequest(reliableBroadcastId);
                Registry[reliableBroadcastId]?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            case ConsensusMessage.PayloadOneofCase.EchoMessage:
                var rbIdEchoMsg =
                    new ReliableBroadcastId(message.EchoMessage.SenderId, (int)message.Validator.Era);
                CheckRequest(rbIdEchoMsg);
                Registry[rbIdEchoMsg]?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            case ConsensusMessage.PayloadOneofCase.SignedHeaderMessage:
                var idRoot = new RootProtocolId(message.Validator.Era);
                CheckRequest(idRoot);
                Registry[idRoot]?.ReceiveMessage(new MessageEnvelope(message, from));
                break;

            default:
                throw new InvalidOperationException($"Unknown message type {message.PayloadCase}");
            }
        }
 protected virtual Task InternalProcessMessageAsync(ConsensusMessage msg)
 {
     throw new InvalidOperationException("Must override.");
 }