@@ -323,28 +323,39 @@ func (vals *ValidatorSet) Size() int {
323323}
324324
325325// updateTotalVotingPower forces recalculation of the set's total voting power.
326- // Panics if total voting power is bigger than MaxTotalVotingPower.
327- func (vals * ValidatorSet ) updateTotalVotingPower () {
326+ // Returns an error if total voting power exceeds MaxTotalVotingPower.
327+ func (vals * ValidatorSet ) updateTotalVotingPower () error {
328328 sum := int64 (0 )
329329 for _ , val := range vals .Validators {
330330 // mind overflow
331331 sum = safeAddClip (sum , val .VotingPower )
332332 if sum > MaxTotalVotingPower {
333- panic (fmt .Sprintf (
334- "Total voting power should be guarded to not exceed %v; got: %v" ,
335- MaxTotalVotingPower ,
336- sum ))
333+ return fmt .Errorf ("total voting power %d exceeds maximum %d" , sum , MaxTotalVotingPower )
337334 }
338335 }
339336
340337 vals .totalVotingPower = sum
338+ return nil
339+ }
340+
341+ // TotalVotingPowerSafe returns the sum of the voting powers of all validators,
342+ // or an error if the total exceeds MaxTotalVotingPower.
343+ func (vals * ValidatorSet ) TotalVotingPowerSafe () (int64 , error ) {
344+ if vals .totalVotingPower == 0 {
345+ if err := vals .updateTotalVotingPower (); err != nil {
346+ return 0 , err
347+ }
348+ }
349+ return vals .totalVotingPower , nil
341350}
342351
343352// TotalVotingPower returns the sum of the voting powers of all validators.
344353// It recomputes the total voting power if required.
345354func (vals * ValidatorSet ) TotalVotingPower () int64 {
346355 if vals .totalVotingPower == 0 {
347- vals .updateTotalVotingPower ()
356+ if err := vals .updateTotalVotingPower (); err != nil {
357+ panic (err )
358+ }
348359 }
349360 return vals .totalVotingPower
350361}
@@ -682,7 +693,9 @@ func (vals *ValidatorSet) updateWithChangeSet(changes []*Validator, allowDeletes
682693 // Should go after additions.
683694 vals .checkAllKeysHaveSameType ()
684695
685- vals .updateTotalVotingPower () // will panic if total voting power > MaxTotalVotingPower
696+ if err = vals .updateTotalVotingPower (); err != nil {
697+ panic (err )
698+ }
686699
687700 // Scale and center.
688701 vals .RescalePriorities (PriorityWindowSizeFactor * vals .TotalVotingPower ())
@@ -952,7 +965,10 @@ func ValidatorSetFromProto(vp *cmtproto.ValidatorSet) (*ValidatorSet, error) {
952965 // power hence we need to recompute it.
953966 // FIXME: We should look to remove TotalVotingPower from proto or add it in the validators hash
954967 // so we don't have to do this
955- vals .TotalVotingPower ()
968+ // NOTE: Use TotalVotingPowerSafe to return error instead of panicking on invalid input.
969+ if _ , err := vals .TotalVotingPowerSafe (); err != nil {
970+ return nil , err
971+ }
956972
957973 return vals , vals .ValidateBasic ()
958974}
@@ -977,7 +993,9 @@ func ValidatorSetFromExistingValidators(valz []*Validator) (*ValidatorSet, error
977993 }
978994 vals .checkAllKeysHaveSameType ()
979995 vals .Proposer = vals .findPreviousProposer ()
980- vals .updateTotalVotingPower ()
996+ if err := vals .updateTotalVotingPower (); err != nil {
997+ return nil , err
998+ }
981999 sort .Sort (ValidatorsByVotingPower (vals .Validators ))
9821000 return vals , nil
9831001}
0 commit comments