// Package salts contains MTProto server salt storage.
package salts import ( ) // Salts is a simple struct store server salts. type Salts struct { // server salts fetched by getSalts. salts []mt.FutureSalt saltsMux sync.Mutex } // Get returns next valid salt. func ( *Salts) ( time.Time) (int64, bool) { .saltsMux.Lock() defer .saltsMux.Unlock() : if len(.salts) < 1 { return 0, false } := int(.Unix()) if := .salts[len(.salts)-1]; .ValidUntil > { return .Salt, true } // Filter (in place) from SliceTricks. := 0 // Check that the salt will be valid until deadline. for , := range .salts { // Filter expired salts. if .ValidUntil > { // Keep valid salt. .salts[] = ++ } } .salts = .salts[:] goto } type saltSlice []mt.FutureSalt func ( saltSlice) () int { return len() } func ( saltSlice) (, int) bool { return [].ValidUntil > [].ValidUntil } func ( saltSlice) (, int) { [], [] = [], [] } // Store stores all given salts. func ( *Salts) ( []mt.FutureSalt) { .saltsMux.Lock() defer .saltsMux.Unlock() .salts = append(.salts, ...) // Filter duplicates. := 0 := make(map[int64]struct{}, len(.salts)+1) for , := range .salts { if , := [.Salt]; ! { [.Salt] = struct{}{} .salts[] = ++ } } .salts = .salts[:] // Sort slice by valid until. sort.Sort(saltSlice(.salts)) } // Reset deletes all stored salts. func ( *Salts) () { .saltsMux.Lock() .salts = .salts[:0] .saltsMux.Unlock() }