public void AddValidator(Address from) { Runtime.Expect(IsWitness(from), "witness failed"); var count = _validatorList.Count(); var max = GetMaxValidators(); Runtime.Expect(count < max, "no open validators spots"); var requiredStake = GetRequiredStake(); var stakedAmount = (BigInteger)Runtime.CallContext("energy", "GetStake", from); Runtime.Expect(stakedAmount >= requiredStake, "not enough stake"); _validatorList.Add(from); var entry = new ValidatorEntry() { address = from, joinDate = Runtime.Time, lastActivity = Runtime.Time, slashes = 0 }; _validatorMap.Set(from, entry); Runtime.Notify(EventKind.ValidatorAdd, Runtime.Chain.Address, from); }
public void AddValidator(Address from) { Runtime.Expect(from.IsUser, "must be user address"); Runtime.Expect(IsWitness(from), "witness failed"); var count = _validatorList.Count(); if (count > 0) { var max = Runtime.GetGovernanceValue(ActiveValidatorCountTag); Runtime.Expect(count < max, "no open validators spots"); var pollName = ConsensusContract.SystemPoll + ValidatorPollTag; var hasConsensus = (bool)Runtime.CallContext("consensus", "HasRank", pollName, from, max); Runtime.Expect(hasConsensus, "no consensus for electing this address"); } var requiredStake = EnergyContract.MasterAccountThreshold; var stakedAmount = (BigInteger)Runtime.CallContext("energy", "GetStake", from); Runtime.Expect(stakedAmount >= requiredStake, "not enough stake"); _validatorList.Add(from); var entry = new ValidatorEntry() { address = from, election = Runtime.Time, }; _validatorMap.Set(from, entry); Runtime.Notify(EventKind.ValidatorAdd, Runtime.Chain.Address, from); }
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); }
// NOTE - witness not required, as anyone should be able to call this, permission is granted based on consensus public void SetValidator(Address from, BigInteger index, ValidatorType type) { Runtime.Expect(from.IsUser, "must be user address"); Runtime.Expect(type != ValidatorType.Invalid, "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"); if (primaryValidators > 1) { var pollName = ConsensusContract.SystemPoll + ValidatorPollTag; var obtainedRank = Runtime.CallContext("consensus", "GetRank", pollName, from).AsNumber(); Runtime.Expect(obtainedRank >= 0, "no consensus for electing this address"); Runtime.Expect(obtainedRank == index, "this address was elected at a different index"); } else if (primaryValidators == 1) { var firstValidator = GetValidatorByIndex(0).address; Runtime.Expect(IsWitness(firstValidator), "invalid witness"); } else if (primaryValidators == 0) { Runtime.Expect(IsWitness(Runtime.Nexus.GenesisAddress), "invalid witness"); } var expectedType = index < GetMaxPrimaryValidators() ? ValidatorType.Primary : ValidatorType.Secondary; Runtime.Expect(type == expectedType, "unexpected validator type"); var requiredStake = Runtime.CallContext(Nexus.StakeContractName, "GetMasterThreshold", from).AsNumber(); var stakedAmount = Runtime.CallContext(Nexus.StakeContractName, "GetStake", from).AsNumber(); 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 entry = new ValidatorEntry() { address = from, 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"); } Runtime.Notify(EventKind.ValidatorAdd, Runtime.Chain.Address, from); }