code: func (rets Retentions) Validate() error {
  	if len(rets) == 0 {
  		return fmt.Errorf("No retentions")
  	}
  	for i := 1; i < len(rets); i++ {
  		prev := rets[i-1]
  		ret := rets[i]
  
  		if prev.SecondsPerPoint >= ret.SecondsPerPoint {
  			return fmt.Errorf("retention must have lower resolution than prior retention")
  		}
  
  		if ret.SecondsPerPoint%prev.SecondsPerPoint != 0 {
  			return fmt.Errorf("lower resolution retentions must be evenly divisible by higher resolution retentions (%d does not divide by %d)", ret.SecondsPerPoint, prev.SecondsPerPoint)
  		}
  
  		if prev.MaxRetention() >= ret.MaxRetention() {
  			return fmt.Errorf("lower resolution archives must have longer retention than higher resolution archives")
  		}
  
  		if prev.NumberOfPoints < (ret.SecondsPerPoint / prev.SecondsPerPoint) {
  			return fmt.Errorf("Each archive must have at least enough points to consolidate to the next archive (archive%v consolidates %v of archive%v's points but it has only %v total points)", i, ret.SecondsPerPoint/prev.SecondsPerPoint, i-1, prev.NumberOfPoints)
  		}
  	}
  	return nil
  }
docs: // Validate assures the retentions are sane.  As the whisper source code says:
  // An ArchiveList must:
  // 1. Have at least one archive config. Example: (60, 86400)
  // 2. No archive may be a duplicate of another.
  // 3. Higher precision archives' precision must evenly divide all lower precision archives' precision.
  // 4. Lower precision archives must cover larger time intervals than higher precision archives.
  // 5. Each archive must have at least enough points to consolidate to the next archive