private void handlePermissionsUpdate(
      final boolean addRestrictions, final Optional<List<Peer>> affectedPeers) {
    if (!addRestrictions) {
      // Nothing to do if permissions were relaxed
      return;
    }

    // If we have an explicit list of peers, drop each peer from our discovery table
    if (affectedPeers.isPresent()) {
      affectedPeers.get().forEach(this::dropPeerIfDisallowed);
      return;
    }

    // Otherwise, signal that we need to clean up the peer table
    peerTableIsDirty.set(true);
  }
This component is the entrypoint for managing the lifecycle of peers.

<p>It keeps track of the interactions with each peer, including the expectations of what we
expect to receive next from each peer. In other words, it implements the state machine for
(discovery) peers.

<p>When necessary, it updates the underlying {@link PeerTable}, particularly with additions which
may succeed or not depending on the contents of the target bucket for the peer.

<h3>Peer state machine</h3>

<pre>{@code
                                                               +--------------------+
                                                               |                    |
                                                   +-----------+  MESSAGE_EXPECTED  +-----------+
                                                   |           |                    |           |
                                                   |           +---+----------------+           |
+------------+         +-----------+         +-----+----+          |                      +-----v-----+
|            |         |           |         |          <----------+                      |           |
|  KNOWN  +--------->  BONDING  +--------->  BONDED     |                                 |  DROPPED  |
|            |         |           |         |          ^                                 |           |
+------------+         +-----------+         +----------+                                 +-----------+

}</pre>

<ul>
  <li><em>KNOWN:</em> the peer is known but there is no ongoing interaction with it.
  <li><em>BONDING:</em> an attempt to bond is being made (e.g. a PING has been sent).
  <li><em>BONDED:</em> the bonding handshake has taken place (e.g. an expected PONG has been
      received after having sent a PING). This is the same as having an "active" channel.
  <li><em>MESSAGE_EXPECTED (*)</em>: a message has been sent and a response is expected.
  <li><em>DROPPED (*):</em> the peer is no longer in our peer table.
</ul>

<p>(*) It is worthy to note that the <code>MESSAGE_EXPECTED</code> and <code>DROPPED</code>
states are not modelled explicitly in {@link PeerDiscoveryStatus}, but they have been included in
the diagram for clarity. These two states define the elimination path for a peer from the
underlying table.

<p>If an expectation to receive a message was unmet, following the evaluation of a failure
condition, the peer will be physically dropped (eliminated) from the table.
ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerDiscoveryController.java