Skip to content

Commit e43e71a

Browse files
authored
9039 il pool (#9062)
* implement inclusion list by committee indices rpc logic
1 parent 7f3d03d commit e43e71a

File tree

5 files changed

+71
-17
lines changed

5 files changed

+71
-17
lines changed

ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/inclusionlist/InclusionListManager.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ public class InclusionListManager implements SlotEventsChannel {
3232

3333
private final SignedInclusionListValidator signedInclusionListValidator;
3434

35-
// TODO EIP7805 Could use a more efficient DS
3635
private final NavigableMap<UInt64, Map<UInt64, List<SignedInclusionList>>>
3736
slotToInclusionListsByValidatorIndex = new TreeMap<>();
3837

@@ -81,8 +80,11 @@ public List<SignedInclusionList> getInclusionLists(
8180
final Map<UInt64, List<SignedInclusionList>> inclusionListsForSlot =
8281
slotToInclusionListsByValidatorIndex.getOrDefault(slot, Map.of());
8382
return inclusionListsForSlot.entrySet().stream()
84-
.filter(e -> committeeIndices.isSet(e.getKey().intValue()))
85-
.flatMap(e -> e.getValue().stream())
83+
.filter(
84+
validatorIndexToInclusionLists ->
85+
committeeIndices.isSet(validatorIndexToInclusionLists.getKey().intValue()))
86+
.flatMap(
87+
validatorIndexToInclusionLists -> validatorIndexToInclusionLists.getValue().stream())
8688
.toList();
8789
}
8890
}

networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/peers/DefaultEth2Peer.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,13 @@ public void adjustBlobSidecarsRequest(
407407
blobSidecarsRequestTracker, blobSidecarsRequest, returnedBlobSidecarsCount);
408408
}
409409

410+
@Override
411+
public void adjustInclusionListsRequest(
412+
final RequestApproval inclusionListsRequest, final long returnedInclusionListsCount) {
413+
adjustObjectsRequest(
414+
inclusionListRequestTracker, inclusionListsRequest, returnedInclusionListsCount);
415+
}
416+
410417
@Override
411418
public boolean approveRequest() {
412419
if (requestTracker.approveObjectsRequest(1L).isEmpty()) {

networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/peers/Eth2Peer.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ Optional<RequestApproval> approveInclusionListsRequest(
124124
void adjustBlobSidecarsRequest(
125125
RequestApproval blobSidecarsRequest, long returnedBlobSidecarsCount);
126126

127+
void adjustInclusionListsRequest(
128+
RequestApproval inclusionListsRequest, long returnedInclusionListsCount);
129+
127130
boolean approveRequest();
128131

129132
SafeFuture<UInt64> sendPing();

networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/rpc/beaconchain/methods/InclusionListByCommitteeIndicesMessageHandler.java

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,24 @@
1515

1616
import static tech.pegasys.teku.networking.eth2.rpc.core.RpcResponseStatus.INVALID_REQUEST_CODE;
1717

18+
import com.google.common.base.Throwables;
19+
import java.nio.channels.ClosedChannelException;
1820
import java.util.List;
1921
import java.util.Optional;
20-
import java.util.stream.Collectors;
22+
import java.util.concurrent.atomic.AtomicInteger;
2123
import org.apache.logging.log4j.LogManager;
2224
import org.apache.logging.log4j.Logger;
2325
import org.hyperledger.besu.plugin.services.MetricsSystem;
2426
import org.hyperledger.besu.plugin.services.metrics.Counter;
2527
import org.hyperledger.besu.plugin.services.metrics.LabelledMetric;
28+
import tech.pegasys.teku.infrastructure.async.SafeFuture;
2629
import tech.pegasys.teku.infrastructure.metrics.TekuMetricCategory;
27-
import tech.pegasys.teku.infrastructure.ssz.primitive.SszBit;
2830
import tech.pegasys.teku.networking.eth2.peers.Eth2Peer;
2931
import tech.pegasys.teku.networking.eth2.peers.RequestApproval;
3032
import tech.pegasys.teku.networking.eth2.rpc.core.PeerRequiredLocalMessageHandler;
3133
import tech.pegasys.teku.networking.eth2.rpc.core.ResponseCallback;
3234
import tech.pegasys.teku.networking.eth2.rpc.core.RpcException;
35+
import tech.pegasys.teku.networking.p2p.rpc.StreamClosedException;
3336
import tech.pegasys.teku.spec.Spec;
3437
import tech.pegasys.teku.spec.config.SpecConfigEip7805;
3538
import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.InclusionListByCommitteeRequestMessage;
@@ -72,9 +75,10 @@ public Optional<RpcException> validateRequest(
7275
final SpecConfigEip7805 specConfig =
7376
SpecConfigEip7805.required(spec.atSlot(request.getSlot()).getConfig());
7477

78+
final int requestedCount = request.getCommitteeIndices().getAllSetBits().size();
7579
final int maxRequestInclusionList = specConfig.getMaxRequestInclusionList();
7680

77-
if (request.size() > maxRequestInclusionList) {
81+
if (requestedCount > maxRequestInclusionList) {
7882
requestCounter.labels("count_too_big").inc();
7983
return Optional.of(
8084
new RpcException(
@@ -86,8 +90,6 @@ public Optional<RpcException> validateRequest(
8690
return Optional.empty();
8791
}
8892

89-
// TODO EIP7805 review logic, add counter
90-
@SuppressWarnings("FutureReturnValueIgnored")
9193
@Override
9294
protected void onIncomingMessage(
9395
final String protocolId,
@@ -96,28 +98,64 @@ protected void onIncomingMessage(
9698
final ResponseCallback<SignedInclusionList> callback) {
9799

98100
LOG.trace(
99-
"Peer {} requested Inclusion Lists for slot {} with committee indices {}",
101+
"Peer {} requested Inclusion Lists for slot {} for committee indices {}",
100102
peer.getId(),
101103
message.getSlot(),
102-
message.getCommitteeIndices().stream()
103-
.map(SszBit::toString)
104-
.collect(Collectors.joining(",")));
104+
message.getCommitteeIndices().getAllSetBits().intStream());
105105

106+
final int requestedCount = message.getCommitteeIndices().getAllSetBits().size();
106107
final Optional<RequestApproval> inclusionListsRequestApproval =
107-
peer.approveInclusionListsRequest(callback, message.size());
108+
peer.approveInclusionListsRequest(callback, requestedCount);
108109

109110
if (!peer.approveRequest() || inclusionListsRequestApproval.isEmpty()) {
110111
requestCounter.labels("rate_limited").inc();
111112
return;
112113
}
113114

114115
requestCounter.labels("ok").inc();
115-
totalInclusionListsRequestedCounter.inc(message.size());
116+
totalInclusionListsRequestedCounter.inc(requestedCount);
116117

117-
// TODO EIP7805 review logic / handle errors
118+
final AtomicInteger sentInclusionLists = new AtomicInteger(0);
118119
final List<SignedInclusionList> signedInclusionLists =
119120
inclusionListManager.getInclusionLists(message.getSlot(), message.getCommitteeIndices());
120-
signedInclusionLists.forEach(callback::respond);
121-
callback.completeSuccessfully();
121+
SafeFuture<Void> future = SafeFuture.COMPLETE;
122+
for (SignedInclusionList signedInclusionList : signedInclusionLists) {
123+
future =
124+
future.thenCompose(
125+
__ ->
126+
callback
127+
.respond(signedInclusionList)
128+
.thenRun(sentInclusionLists::incrementAndGet));
129+
}
130+
future.finish(
131+
() -> {
132+
if (sentInclusionLists.get() != requestedCount) {
133+
peer.adjustInclusionListsRequest(
134+
inclusionListsRequestApproval.get(), sentInclusionLists.get());
135+
}
136+
callback.completeSuccessfully();
137+
},
138+
err -> {
139+
peer.adjustInclusionListsRequest(inclusionListsRequestApproval.get(), 0);
140+
handleError(callback, err);
141+
});
142+
}
143+
144+
private void handleError(
145+
final ResponseCallback<SignedInclusionList> callback, final Throwable error) {
146+
final Throwable rootCause = Throwables.getRootCause(error);
147+
if (rootCause instanceof RpcException) {
148+
LOG.trace(
149+
"Rejecting inclusion lists by committee indices request", error); // Keep full context
150+
callback.completeWithErrorResponse((RpcException) rootCause);
151+
} else {
152+
if (rootCause instanceof StreamClosedException
153+
|| rootCause instanceof ClosedChannelException) {
154+
LOG.trace("Stream closed while sending requested inclusion lists", error);
155+
} else {
156+
LOG.error("Failed to process inclusion lists by committee indices request", error);
157+
}
158+
callback.completeWithUnexpectedError(error);
159+
}
122160
}
123161
}

networking/eth2/src/testFixtures/java/tech/pegasys/teku/networking/eth2/peers/RespondingEth2Peer.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,10 @@ public Optional<RequestApproval> approveInclusionListsRequest(
349349
public void adjustBlobSidecarsRequest(
350350
final RequestApproval blobSidecarRequests, final long returnedBlobSidecarsCount) {}
351351

352+
@Override
353+
public void adjustInclusionListsRequest(
354+
final RequestApproval inclusionListsRequest, final long returnedInclusionListsCount) {}
355+
352356
@Override
353357
public boolean approveRequest() {
354358
return true;

0 commit comments

Comments
 (0)