コード例 #1
0
        public ValidatorEntry[] GetValidators()
        {
            var totalValidators = (int)Runtime.GetGovernanceValue(ValidatorCountTag);
            var result          = new ValidatorEntry[totalValidators];

            for (int i = 0; i < totalValidators; i++)
            {
                result[i] = GetValidatorByIndex(i);
            }
            return(result);
        }
コード例 #2
0
        // NOTE - witness not required, as anyone should be able to call this, permission is granted based on consensus
        public void SetValidator(Address target, BigInteger index, ValidatorType type)
        {
            Runtime.Expect(target.IsUser, "must be user address");
            Runtime.Expect(type == ValidatorType.Primary || type == ValidatorType.Secondary, "invalid validator type");

            var primaryValidators   = GetValidatorCount(ValidatorType.Primary);
            var secondaryValidators = GetValidatorCount(ValidatorType.Secondary);

            Runtime.Expect(index >= 0, "invalid index");

            var totalValidators = GetMaxTotalValidators();

            Runtime.Expect(index < totalValidators, "invalid index");

            var expectedType = index < GetMaxPrimaryValidators() ? ValidatorType.Primary : ValidatorType.Secondary;

            Runtime.Expect(type == expectedType, "unexpected validator type");

            var requiredStake = Runtime.CallContext(NativeContractKind.Stake, nameof(StakeContract.GetMasterThreshold), target).AsNumber();
            var stakedAmount  = Runtime.GetStake(target);

            Runtime.Expect(stakedAmount >= requiredStake, "not enough stake");

            if (index > 0)
            {
                var isPreviousSet = _validators.ContainsKey <BigInteger>(index - 1);
                Runtime.Expect(isPreviousSet, "previous validator slot is not set");

                var previousEntry = _validators.Get <BigInteger, ValidatorEntry>(index - 1);
                Runtime.Expect(previousEntry.type != ValidatorType.Invalid, " previous validator has unexpected status");
            }

            if (primaryValidators > 0)
            {
                var isValidatorProposed = _validators.ContainsKey <BigInteger>(index);

                if (isValidatorProposed)
                {
                    var currentEntry = _validators.Get <BigInteger, ValidatorEntry>(index);
                    if (currentEntry.type != ValidatorType.Proposed)
                    {
                        Runtime.Expect(currentEntry.type == ValidatorType.Invalid, "invalid validator state");
                        isValidatorProposed = false;
                    }
                }

                if (isValidatorProposed)
                {
                    Runtime.Expect(Runtime.IsWitness(target), "invalid witness");
                }
                else
                {
                    if (primaryValidators > 1)
                    {
                        var pollName     = ConsensusContract.SystemPoll + ValidatorPollTag;
                        var obtainedRank = Runtime.CallContext("consensus", "GetRank", pollName, target).AsNumber();
                        Runtime.Expect(obtainedRank >= 0, "no consensus for electing this address");
                        Runtime.Expect(obtainedRank == index, "this address was elected at a different index");
                    }
                    else
                    {
                        var firstValidator = GetValidatorByIndex(0).address;
                        Runtime.Expect(Runtime.IsWitness(firstValidator), "invalid witness");
                    }

                    type = ValidatorType.Proposed;
                }
            }
            else
            {
                Runtime.Expect(Runtime.IsWitness(Runtime.GenesisAddress), "invalid witness");
            }

            var entry = new ValidatorEntry()
            {
                address  = target,
                election = Runtime.Time,
                type     = type,
            };

            _validators.Set <BigInteger, ValidatorEntry>(index, entry);

            if (type == ValidatorType.Primary)
            {
                var newValidators = GetValidatorCount(ValidatorType.Primary);
                Runtime.Expect(newValidators > primaryValidators, "number of primary validators did not change");
            }
            else
            if (type == ValidatorType.Secondary)
            {
                var newValidators = GetValidatorCount(ValidatorType.Secondary);
                Runtime.Expect(newValidators > secondaryValidators, "number of secondary validators did not change");
            }

            if (type != ValidatorType.Proposed)
            {
                Runtime.AddMember(DomainSettings.ValidatorsOrganizationName, this.Address, target);
            }

            Runtime.Notify(type == ValidatorType.Proposed ? EventKind.ValidatorPropose : EventKind.ValidatorElect, Runtime.Chain.Address, target);
        }