These should be used together to implement the session establishment protocol. Session establishment proceeds in three synchronous, symmetric, steps. The first two steps are implemented by authenticate. The third step is implemented by either accept or nack.
1. Hosts send each other an authentication message. The message contains notably a public key, a nonce, and proof of work stamp computed from the public key. PoW work is checked, and a session key is established (authenticated key exchange). The session key will be used to encrypt/authenticate all subsequent messages over this connection.
2. Hosts send each other a 'meta message.
3. Each host send either an Ack message (accept function) or an Nack message (nack function). If both hosts send an Ack, the connection is established and they can start to read/write 'msg.
Note that P2p_errors.Decipher_error can be raised from all functions receiving messages after step 1, when a message can't be decrypted.
Typically, the calling module will make additional checks after step 2 to decide what to do in step 3. For instance, based on network version or 'meta information.
nack ac motive alts sends a Nack message with the rejection motive and a list of proposed alternative points to the remote peer, notifying it that its connection is rejected. It then closes the connection.
alts must contain less than 100 points or you will be greylisted
Similar to write_now conn msg but with a preencoded message. msg will be overwritten and should not be used after this invocation. It will fail if called on a closed connection with the `P2p_errors.Connection_closed` error.