예제 #1
0
        private bool IsVotingOnMultisigMember(VotingData votingData)
        {
            if (votingData.Key != VoteKey.AddFederationMember && votingData.Key != VoteKey.KickFederationMember)
            {
                return(false);
            }

            if (!(this.network.Consensus.ConsensusFactory is PoAConsensusFactory poaConsensusFactory))
            {
                return(false);
            }

            IFederationMember member = poaConsensusFactory.DeserializeFederationMember(votingData.Data);

            // Ignore votes on multisig-members.
            return(FederationVotingController.IsMultisigMember(this.network, member.PubKey));
        }
예제 #2
0
        private void OnBlockConnected(BlockConnected blockConnectedData)
        {
            // Update last active time.
            uint   timestamp = blockConnectedData.ConnectedBlock.ChainedHeader.Header.Time;
            PubKey key       = this.slotsManager.GetFederationMemberForTimestamp(timestamp).PubKey;

            this.fedPubKeysByLastActiveTime.AddOrReplace(key, timestamp);

            this.SaveMembersByLastActiveTime();

            // Check if any fed member was idle for too long.
            ChainedHeader tip = this.consensusManager.Tip;

            foreach (KeyValuePair <PubKey, uint> fedMemberToActiveTime in this.fedPubKeysByLastActiveTime)
            {
                uint inactiveForSeconds = tip.Header.Time - fedMemberToActiveTime.Value;

                if (inactiveForSeconds > this.federationMemberMaxIdleTimeSeconds && this.federationManager.IsFederationMember &&
                    !FederationVotingController.IsMultisigMember(this.network, fedMemberToActiveTime.Key))
                {
                    IFederationMember memberToKick = this.federationManager.GetFederationMembers().SingleOrDefault(x => x.PubKey == fedMemberToActiveTime.Key);

                    byte[] federationMemberBytes = this.consensusFactory.SerializeFederationMember(memberToKick);

                    bool alreadyKicking = this.votingManager.AlreadyVotingFor(VoteKey.KickFederationMember, federationMemberBytes);

                    if (!alreadyKicking)
                    {
                        this.logger.LogWarning("Federation member '{0}' was inactive for {1} seconds and will be scheduled to be kicked.", fedMemberToActiveTime.Key, inactiveForSeconds);

                        this.votingManager.ScheduleVote(new VotingData()
                        {
                            Key  = VoteKey.KickFederationMember,
                            Data = federationMemberBytes
                        });
                    }
                    else
                    {
                        this.logger.LogDebug("Skipping because kicking is already voted for.");
                    }
                }
            }
        }