Fix discovery packet size (#2252)

* Fix discovery packet size

Signed-off-by: Antoine Toulme <antoine@lunar-ocean.com>

* Add assertion to check the size of the packet once encoded

Signed-off-by: Antoine Toulme <antoine@lunar-ocean.com>

* code review

Signed-off-by: Antoine Toulme <antoine@lunar-ocean.com>

Co-authored-by: Sally MacFarlane <sally.macfarlane@consensys.net>
pull/2273/head
Antoine Toulme 4 years ago committed by GitHub
parent b55c6b8321
commit c682ea48ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerDiscoveryController.java
  2. 13
      ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryAgentTest.java

@ -578,9 +578,12 @@ public class PeerDiscoveryController {
if (packetData.getExpiration() < Instant.now().getEpochSecond()) { if (packetData.getExpiration() < Instant.now().getEpochSecond()) {
return; return;
} }
// TODO: for now return 16 peers. Other implementations calculate how many // Each peer is encoded as 16 bytes for address, 4 bytes for port, 4 bytes for tcp port
// peers they can fit in a 1280-byte payload. // and 64 bytes for id. This is prepended by 97 bytes of hash, signature and type.
final List<DiscoveryPeer> peers = peerTable.nearestPeers(packetData.getTarget(), 16); // 16 + 4 + 4 + 64 = 88 bytes
// 88 * 13 = 1144 bytes
// To fit under 1280 bytes, we must return just 13 peers maximum.
final List<DiscoveryPeer> peers = peerTable.nearestPeers(packetData.getTarget(), 13);
final PacketData data = NeighborsPacketData.create(peers); final PacketData data = NeighborsPacketData.create(peers);
sendPacket(sender, PacketType.NEIGHBORS, data); sendPacket(sender, PacketType.NEIGHBORS, data);
} }

@ -224,19 +224,20 @@ public class PeerDiscoveryAgentTest {
final IncomingPacket neighborsPacket = incomingPackets.get(0); final IncomingPacket neighborsPacket = incomingPackets.get(0);
assertThat(neighborsPacket.fromAgent).isEqualTo(agent); assertThat(neighborsPacket.fromAgent).isEqualTo(agent);
// Assert that we only received 16 items. // Assert that we only received 13 items.
assertThat(neighborsPacket.packet.getPacketData(NeighborsPacketData.class).isPresent()) assertThat(neighborsPacket.packet.getPacketData(NeighborsPacketData.class).isPresent())
.isTrue(); .isTrue();
final NeighborsPacketData neighbors = final NeighborsPacketData neighbors =
neighborsPacket.packet.getPacketData(NeighborsPacketData.class).get(); neighborsPacket.packet.getPacketData(NeighborsPacketData.class).get();
assertThat(neighbors).isNotNull(); assertThat(neighbors).isNotNull();
assertThat(neighbors.getNodes()).hasSize(16); assertThat(neighbors.getNodes()).hasSize(13);
assertThat(neighborsPacket.packet.encode().length()).isLessThanOrEqualTo(1280); // under max MTU
// Assert that after removing those 16 items we're left with either 4 or 5. // Assert that after removing those 13 items we're left with either 7 or 8.
// If we are left with 5, the test peer was returned as an item, assert that this is the case. // If we are left with 8, the test peer was returned as an item, assert that this is the case.
otherPeers.removeAll(neighbors.getNodes()); otherPeers.removeAll(neighbors.getNodes());
assertThat(otherPeers.size()).isBetween(4, 5); assertThat(otherPeers.size()).isBetween(7, 8);
if (otherPeers.size() == 5) { if (otherPeers.size() == 8) {
assertThat(testAgent.getAdvertisedPeer().isPresent()).isTrue(); assertThat(testAgent.getAdvertisedPeer().isPresent()).isTrue();
assertThat(neighbors.getNodes()).contains(testAgent.getAdvertisedPeer().get()); assertThat(neighbors.getNodes()).contains(testAgent.getAdvertisedPeer().get());
} }

Loading…
Cancel
Save