package time import ( "sort" "time" ) // Now returns the current time in UTC with no monotonic component. func Now() time.Time { return Canonical(time.Now()) } // Canonical returns UTC time with no monotonic component. // Stripping the monotonic component is for time equality. // See https://github.com/tendermint/tendermint/pull/2203#discussion_r215064334 func Canonical(t time.Time) time.Time { return t.Round(0).UTC() } // WeightedTime for computing a median. type WeightedTime struct { Time time.Time Weight int64 } // NewWeightedTime with time and weight. func NewWeightedTime(time time.Time, weight int64) *WeightedTime { return &WeightedTime{ Time: time, Weight: weight, } } // WeightedMedian computes weighted median time for a given array of WeightedTime and the total voting power. func WeightedMedian(weightedTimes []*WeightedTime, totalVotingPower int64) (res time.Time) { median := totalVotingPower / 2 sort.Slice(weightedTimes, func(i, j int) bool { if weightedTimes[i] == nil { return false } if weightedTimes[j] == nil { return true } return weightedTimes[i].Time.UnixNano() < weightedTimes[j].Time.UnixNano() }) for _, weightedTime := range weightedTimes { if weightedTime != nil { if median <= weightedTime.Weight { res = weightedTime.Time break } median -= weightedTime.Weight } } return }