private void OnBillBoardBroadcast(ChatMsg msg)
 {
     if (!IsThisNodeSeed0)
     {
         _board = JsonConvert.DeserializeObject <BillBoard>(msg.Text);
         _log.LogInformation("BillBoard updated!");
     }
 }
Example #2
0
        public bool GetIsAuthoringSuccess(BillBoard billBoard)
        {
            if (billBoard == null)
            {
                throw new Exception("The BillBoard mustn't be null!");
            }

            var topNodes   = billBoard.AllNodes.Values.Where(a => a.AbleToAuthorize).OrderByDescending(b => b.Balance).Take(21);
            var agreeCount = (topNodes.Count() / 3) * 2 + 1;

            if (agreeCount < ProtocolSettings.Default.ConsensusNumber)
            {
                agreeCount = (int)ProtocolSettings.Default.ConsensusNumber;      // we must do genesis when authorizers are there
            }
            var q = from m in OutputMsgs
                    where m.IsSuccess && billBoard.AllNodes.ContainsKey(m.From) && billBoard.AllNodes[m.From].AbleToAuthorize
                    select m;

            IsConsensusSuccess = q.Count() >= agreeCount;
            return(IsConsensusSuccess == true);
        }
Example #3
0
        private ConsensusResult GetConsensusSuccess(BillBoard billBoard)
        {
            if (billBoard == null)
            {
                throw new Exception("The BillBoard mustn't be null!");
            }

            //// wait for a proper UID
            //if (!OutputMsgs.ToList().Any(a => a.From == ProtocolSettings.Default.StandbyValidators[0]))
            //{
            //    return false;
            //}

            var selectedNodes = billBoard.AllNodes.Values.ToList().Where(a => a.AbleToAuthorize).OrderByDescending(b => b.Balance).Take(ProtocolSettings.Default.ConsensusTotalNumber);

            var q = from m in OutputMsgs
                    where m.IsSuccess && selectedNodes.Any(a => a.AccountID == m.From)
                    select m;

            var q2 = from m in OutputMsgs
                     where m.IsSuccess && selectedNodes.Any(a => a.AccountID == m.From)
                     select m;

            if (q.Count() >= ProtocolSettings.Default.ConsensusWinNumber)
            {
                return(ConsensusResult.Yay);
            }
            else if (q2.Count() >= ProtocolSettings.Default.ConsensusWinNumber)
            {
                return(ConsensusResult.Nay);
            }
            else
            {
                return(ConsensusResult.Uncertain);
            }
        }
        public ConsensusService(IActorRef localNode)
        {
            _localNode = localNode;
            _log       = new SimpleLogger("ConsensusService").Logger;

            _outOfOrderedMessages = new Dictionary <string, List <SourceSignedMessage> >();
            _activeConsensus      = new Dictionary <string, AuthState>();

            _authorizers = new AuthorizersFactory();
            while (BlockChain.Singleton == null)
            {
                Task.Delay(100).Wait();
            }

            _UIndexSeed = BlockChain.Singleton.GetBlockCount() + 1;
            Mode        = ConsensusWorkingMode.OutofSyncWaiting;

            Receive <Consolidate>((_) =>
            {
                _log.LogInformation("Doing Consolidate");
                OnNodeActive(NodeService.Instance.PosWallet.AccountId);     // update billboard

                if (Mode == ConsensusWorkingMode.Normal)
                {
                    BroadCastBillBoard();
                    GenerateConsolidateBlock();
                }
            });

            Receive <BillBoard>((bb) => {
                _board = bb;
            });

            Receive <AskForBillboard>((_) => Sender.Tell(_board));

            Receive <AuthorizingMsg>(async msg => {
                if (msg.Version != LyraGlobal.ProtocolVersion)
                {
                    Sender.Tell(null);
                }

                OnNodeActive(NodeService.Instance.PosWallet.AccountId);     // update billboard

                // first try auth locally
                var state           = CreateAuthringState(msg);
                var localAuthResult = LocalAuthorizingAsync(msg);
                state.AddAuthResult(localAuthResult);

                if (!localAuthResult.IsSuccess)
                {
                    state.Done.Set();
                    Sender.Tell(state);
                }
                else
                {
                    Send2P2pNetwork(msg);
                    Send2P2pNetwork(localAuthResult);

                    var sender = Context.Sender;

                    await Task.Run(() =>
                    {
                        _ = state.Done.WaitOne();
                    }).ConfigureAwait(false);

                    sender.Tell(state);
                }
            });

            Receive <SignedMessageRelay>(relayMsg =>
            {
                if (relayMsg.signedMessage.Version == LyraGlobal.ProtocolVersion)
                {
                    OnNextConsensusMessage(relayMsg.signedMessage);
                }
                else
                {
                    _log.LogWarning("Protocol Version Mismatch. Do nothing.");
                }
            });

            Receive <BlockChainSynced>(_ =>
            {
                Mode        = ConsensusWorkingMode.Normal;
                _UIndexSeed = BlockChain.Singleton.GetBlockCount() + 1;

                // declare to the network
                var msg = new ChatMsg
                {
                    From    = NodeService.Instance.PosWallet.AccountId,
                    MsgType = ChatMessageType.NodeUp,
                    Text    = "Staking with () Lyra"
                };

                Send2P2pNetwork(msg);
            });

            Task.Run(async() => {
                while (true)
                {
                    StateClean();
                    await Task.Delay(1000).ConfigureAwait(false);
                }
            });
        }