code: func (api *HandshakeAPI) Handshake(pubkeyid string, topic Topic, sync bool, flush bool) (keys []string, err error) {
  	var hsc chan []string
  	var keycount uint8
  	if flush {
  		keycount = api.ctrl.symKeyCapacity
  	} else {
  		validkeys := api.ctrl.validKeys(pubkeyid, &topic, false)
  		keycount = api.ctrl.symKeyCapacity - uint8(len(validkeys))
  	}
  	if keycount == 0 {
  		return keys, errors.New("Incoming symmetric key store is already full")
  	}
  	if sync {
  		hsc = api.ctrl.alertHandshake(pubkeyid, []string{})
  	}
  	_, err = api.ctrl.sendKey(pubkeyid, &topic, keycount)
  	if err != nil {
  		return keys, err
  	}
  	if sync {
  		ctx, cancel := context.WithTimeout(context.Background(), api.ctrl.symKeyRequestTimeout)
  		defer cancel()
  		select {
  		case keys = <-hsc:
  			log.Trace("sync handshake response receive", "key", keys)
  		case <-ctx.Done():
  			return []string{}, errors.New("timeout")
  		}
  	}
  	return keys, nil
  }
docs: // Initiate a handshake session for a peer (public key) and topic
  // combination.
  //
  // If `sync` is set, the call will block until keys are received from peer,
  // or if the handshake request times out
  //
  // If `flush` is set, the max amount of keys will be sent to the peer
  // regardless of how many valid keys that currently exist in the store.
  //
  // Returns list of symmetric key ids that can be passed to pss.GetSymmetricKey()
  // for retrieval of the symmetric key bytes themselves.
  //
  // Fails if the incoming symmetric key store is already full (and `flush` is false),
  // or if the underlying key dispatcher fails