@@ -310,28 +310,40 @@ func (vals *ValidatorSet) Size() int {
310310}
311311
312312// Forces recalculation of the set's total voting power.
313- // Panics if total voting power is bigger than MaxTotalVotingPower.
314- func (vals * ValidatorSet ) updateTotalVotingPower () {
313+ // Returns an error if total voting power exceeds MaxTotalVotingPower.
314+ func (vals * ValidatorSet ) updateTotalVotingPower () error {
315315 sum := int64 (0 )
316316 for _ , val := range vals .Validators {
317317 // mind overflow
318318 sum = safeAddClip (sum , val .VotingPower )
319319 if sum > MaxTotalVotingPower {
320- panic (fmt .Sprintf (
321- "Total voting power should be guarded to not exceed %v; got: %v" ,
322- MaxTotalVotingPower ,
323- sum ))
320+ return fmt .Errorf ("total voting power %d exceeds maximum %d" , sum , MaxTotalVotingPower )
324321 }
325322 }
326323
327324 vals .totalVotingPower = sum
325+ return nil
326+ }
327+
328+ // TotalVotingPowerSafe returns the sum of the voting powers of all validators,
329+ // or an error if the total exceeds MaxTotalVotingPower.
330+ func (vals * ValidatorSet ) TotalVotingPowerSafe () (int64 , error ) {
331+ if vals .totalVotingPower == 0 {
332+ if err := vals .updateTotalVotingPower (); err != nil {
333+ return 0 , err
334+ }
335+ }
336+ return vals .totalVotingPower , nil
328337}
329338
330339// TotalVotingPower returns the sum of the voting powers of all validators.
331340// It recomputes the total voting power if required.
332341func (vals * ValidatorSet ) TotalVotingPower () int64 {
333342 if vals .totalVotingPower == 0 {
334- vals .updateTotalVotingPower ()
343+ err := vals .updateTotalVotingPower ()
344+ if err != nil {
345+ panic (err )
346+ }
335347 }
336348 return vals .totalVotingPower
337349}
@@ -665,7 +677,9 @@ func (vals *ValidatorSet) updateWithChangeSet(changes []*Validator, allowDeletes
665677 // Should go after additions.
666678 vals .checkAllKeysHaveSameType ()
667679
668- vals .updateTotalVotingPower () // will panic if total voting power > MaxTotalVotingPower
680+ if err = vals .updateTotalVotingPower (); err != nil {
681+ panic (err )
682+ }
669683
670684 // Scale and center.
671685 vals .RescalePriorities (PriorityWindowSizeFactor * vals .TotalVotingPower ())
@@ -935,7 +949,10 @@ func ValidatorSetFromProto(vp *cmtproto.ValidatorSet) (*ValidatorSet, error) {
935949 // power hence we need to recompute it.
936950 // FIXME: We should look to remove TotalVotingPower from proto or add it in the validators hash
937951 // so we don't have to do this
938- vals .TotalVotingPower ()
952+ // NOTE: Use TotalVotingPowerSafe to return error on invalid input.
953+ if _ , err := vals .TotalVotingPowerSafe (); err != nil {
954+ return nil , err
955+ }
939956
940957 return vals , vals .ValidateBasic ()
941958}
@@ -960,7 +977,9 @@ func ValidatorSetFromExistingValidators(valz []*Validator) (*ValidatorSet, error
960977 }
961978 vals .checkAllKeysHaveSameType ()
962979 vals .Proposer = vals .findPreviousProposer ()
963- vals .updateTotalVotingPower ()
980+ if err := vals .updateTotalVotingPower (); err != nil {
981+ return nil , err
982+ }
964983 sort .Sort (ValidatorsByVotingPower (vals .Validators ))
965984 return vals , nil
966985}
0 commit comments