Skip to content

Commit

Permalink
Merge branch 'master' into update_prometheus
Browse files Browse the repository at this point in the history
  • Loading branch information
gfukushima authored Jul 3, 2024
2 parents f3adfa0 + c541a40 commit 4705612
Show file tree
Hide file tree
Showing 52 changed files with 709 additions and 189 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/codespell.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# A Github action that using codespell to check spell.
# A Github action that uses codespell to check spell.
# .codespell/.codespellrc is a config file.
# .codespell/wordlist.txt is a list of words that will ignore word checks.
# More details please check the following link:
Expand Down
2 changes: 1 addition & 1 deletion .openapidoc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This directory contains NodeJS project which publishes Teku OpenAPI specificatio
[`gh-pages`](https://github.com/Consensys/teku/tree/gh-pages) branch via CI job after tests are green.
See `publishOpenApiSpec` job in `.circleci/config.yml`.

The actual up to date generated doc is available at https://consensys.github.io/teku/
The actual up-to-date generated doc is available at https://consensys.github.io/teku/

## Procedure

Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ You'll find us on [Discord] and that's the fastest way to get an answer.
### Your first code contribution
Start by looking through the 'good first issue' and 'help wanted' issues:
* [Good First Issue][search-label-good-first-issue] - issues which should only require a few lines of code, and a test or two.
* [Help wanted issues][search-label-help-wanted] - issues which are a bit more involved than `good first issue` issues.
* [Help wanted issues][search-label-help-wanted] - issues that are a bit more involved than `good first issue` issues.

### Local Development
The codebase is maintained using the "*contributor workflow*" where everyone without exception contributes patch proposals using "*pull-requests*". This facilitates social contribution, easy testing and peer review.
Expand All @@ -47,7 +47,7 @@ In general a commit serves a single purpose and diffs should be easily comprehen

### Architectural Best Practices

Questions on architectural best practices will be guided by the principles set forth in [Effective Java](http://index-of.es/Java/Effective%20Java.pdf) by Joshua Bloch
Questions on architectural best practices will be guided by the principles set forth in Effective Java by Joshua Bloch

### Automated Test coverage
All code submissions must be accompanied by appropriate automated tests. The goal is to provide confidence in the code’s robustness, while avoiding redundant tests.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ void shouldFetchBlocksLaterThanOneWhichWasBeforeTheCachePeriod() {
blockFetcher.fetch(BigInteger.valueOf(6), BigInteger.valueOf(6));
verifyNoMoreInteractions(eth1Provider);

// When block 5 complete, it should request block 6
// When block 5 is complete, it should request block 6
block5Future.complete(Optional.of(block5));
verify(eth1Provider).getEth1Block(UInt64.valueOf(6));
verifyNoMoreInteractions(eth1Provider);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ void shouldFallbackOnGetGuaranteedEth1Block_byHash()
final SafeFuture<EthBlock.Block> blockByHash =
fallbackAwareEth1Provider.getGuaranteedEth1Block("");

// we expect a delayed action after all nodes has been contacted
// we expect a delayed action after all nodes have been contacted
assertThat(asyncRunner.hasDelayedActions()).isTrue();
verify(node1, atLeastOnce()).getEth1Block("");
verify(node2, atLeastOnce()).getEth1Block("");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import tech.pegasys.teku.api.ChainDataProvider;
import tech.pegasys.teku.api.NetworkDataProvider;
import tech.pegasys.teku.api.NodeDataProvider;
import tech.pegasys.teku.beacon.sync.events.SyncState;
import tech.pegasys.teku.beacon.sync.events.SyncStateProvider;
Expand Down Expand Up @@ -86,6 +87,7 @@ public class ValidatorApiHandlerIntegrationTest {
mock(BlobSidecarGossipChannel.class);
private final ChainDataProvider chainDataProvider = mock(ChainDataProvider.class);
private final NodeDataProvider nodeDataProvider = mock(NodeDataProvider.class);
private final NetworkDataProvider networkDataProvider = mock(NetworkDataProvider.class);
private final ForkChoiceTrigger forkChoiceTrigger = mock(ForkChoiceTrigger.class);
private final ProposersDataManager proposersDataManager = mock(ProposersDataManager.class);

Expand All @@ -102,6 +104,7 @@ public class ValidatorApiHandlerIntegrationTest {
new ValidatorApiHandler(
chainDataProvider,
nodeDataProvider,
networkDataProvider,
combinedChainDataClient,
syncStateProvider,
blockFactory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@
import org.apache.tuweni.bytes.Bytes32;
import org.hyperledger.besu.plugin.services.metrics.OperationTimer;
import tech.pegasys.teku.api.ChainDataProvider;
import tech.pegasys.teku.api.NetworkDataProvider;
import tech.pegasys.teku.api.NodeDataProvider;
import tech.pegasys.teku.api.migrated.ValidatorLivenessAtEpoch;
import tech.pegasys.teku.api.response.v1.beacon.ValidatorStatus;
import tech.pegasys.teku.beacon.sync.events.SyncStateProvider;
import tech.pegasys.teku.bls.BLSPublicKey;
import tech.pegasys.teku.bls.BLSSignature;
import tech.pegasys.teku.ethereum.json.types.beacon.StateValidatorData;
import tech.pegasys.teku.ethereum.json.types.node.PeerCount;
import tech.pegasys.teku.ethereum.json.types.validator.AttesterDuties;
import tech.pegasys.teku.ethereum.json.types.validator.BeaconCommitteeSelectionProof;
import tech.pegasys.teku.ethereum.json.types.validator.ProposerDuties;
Expand Down Expand Up @@ -127,6 +129,7 @@ public class ValidatorApiHandler implements ValidatorApiChannel {
blockProductionAndPublishingPerformanceFactory;
private final ChainDataProvider chainDataProvider;
private final NodeDataProvider nodeDataProvider;
private final NetworkDataProvider networkDataProvider;
private final CombinedChainDataClient combinedChainDataClient;
private final SyncStateProvider syncStateProvider;
private final BlockFactory blockFactory;
Expand All @@ -149,6 +152,7 @@ public class ValidatorApiHandler implements ValidatorApiChannel {
public ValidatorApiHandler(
final ChainDataProvider chainDataProvider,
final NodeDataProvider nodeDataProvider,
final NetworkDataProvider networkDataProvider,
final CombinedChainDataClient combinedChainDataClient,
final SyncStateProvider syncStateProvider,
final BlockFactory blockFactory,
Expand All @@ -174,6 +178,7 @@ public ValidatorApiHandler(
blockProductionAndPublishingPerformanceFactory;
this.chainDataProvider = chainDataProvider;
this.nodeDataProvider = nodeDataProvider;
this.networkDataProvider = networkDataProvider;
this.combinedChainDataClient = combinedChainDataClient;
this.syncStateProvider = syncStateProvider;
this.blockFactory = blockFactory;
Expand Down Expand Up @@ -299,6 +304,11 @@ public SafeFuture<Optional<ProposerDuties>> getProposerDuties(final UInt64 epoch
optionalState.map(state -> getProposerDutiesFromIndicesAndState(state, epoch)));
}

@Override
public SafeFuture<Optional<PeerCount>> getPeerCount() {
return SafeFuture.completedFuture(Optional.of(networkDataProvider.getPeerCount()));
}

@Override
public SafeFuture<Optional<Map<BLSPublicKey, ValidatorStatus>>> getValidatorStatuses(
final Collection<BLSPublicKey> validatorIdentifiers) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import tech.pegasys.teku.api.ChainDataProvider;
import tech.pegasys.teku.api.NetworkDataProvider;
import tech.pegasys.teku.api.NodeDataProvider;
import tech.pegasys.teku.api.migrated.ValidatorLivenessAtEpoch;
import tech.pegasys.teku.api.response.v1.beacon.ValidatorStatus;
Expand Down Expand Up @@ -157,6 +158,7 @@ class ValidatorApiHandlerTest {
mock(DefaultPerformanceTracker.class);
private final ChainDataProvider chainDataProvider = mock(ChainDataProvider.class);
private final NodeDataProvider nodeDataProvider = mock(NodeDataProvider.class);
private final NetworkDataProvider networkDataProvider = mock(NetworkDataProvider.class);
private final DutyMetrics dutyMetrics = mock(DutyMetrics.class);
private final ForkChoiceTrigger forkChoiceTrigger = mock(ForkChoiceTrigger.class);
private final ProposersDataManager proposersDataManager = mock(ProposersDataManager.class);
Expand Down Expand Up @@ -198,6 +200,7 @@ public void setUp() {
new ValidatorApiHandler(
chainDataProvider,
nodeDataProvider,
networkDataProvider,
chainDataClient,
syncStateProvider,
blockFactory,
Expand Down Expand Up @@ -452,6 +455,7 @@ void getSyncCommitteeDuties_shouldNotUseEpochPriorToFork() {
new ValidatorApiHandler(
chainDataProvider,
nodeDataProvider,
networkDataProvider,
chainDataClient,
syncStateProvider,
blockFactory,
Expand Down Expand Up @@ -1362,6 +1366,7 @@ private void setupDeneb() {
new ValidatorApiHandler(
chainDataProvider,
nodeDataProvider,
networkDataProvider,
chainDataClient,
syncStateProvider,
blockFactory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void setup() {
when(eth2P2PNetwork.getNodeId()).thenReturn(node1);
when(eth2P2PNetwork.getEnr()).thenReturn(Optional.of(enr));
when(eth2P2PNetwork.getNodeAddresses()).thenReturn(List.of(address));
when(eth2P2PNetwork.getDiscoveryAddress()).thenReturn(Optional.of(discoveryAddress));
when(eth2P2PNetwork.getDiscoveryAddresses()).thenReturn(Optional.of(List.of(discoveryAddress)));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public void handleRequest(final RestApiRequest request) throws JsonProcessingExc
private boolean belowTargetPeerCount(final RestApiRequest request) {
return request
.getOptionalQueryParameter(TARGET_PEER_COUNT_PARAMETER)
.map(targetPeerCount -> networkDataProvider.getPeerCount() < targetPeerCount)
.map(targetPeerCount -> networkDataProvider.countPeers() < targetPeerCount)
.orElse(false);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,19 @@
import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_OK;
import static tech.pegasys.teku.infrastructure.http.RestApiConstants.CACHE_NONE;
import static tech.pegasys.teku.infrastructure.http.RestApiConstants.TAG_NODE;
import static tech.pegasys.teku.infrastructure.json.types.CoreTypes.UINT64_TYPE;

import com.fasterxml.jackson.core.JsonProcessingException;
import io.javalin.http.Header;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import tech.pegasys.teku.api.DataProvider;
import tech.pegasys.teku.api.NetworkDataProvider;
import tech.pegasys.teku.infrastructure.json.types.SerializableTypeDefinition;
import tech.pegasys.teku.ethereum.json.types.node.PeerCountBuilder;
import tech.pegasys.teku.infrastructure.restapi.endpoints.EndpointMetadata;
import tech.pegasys.teku.infrastructure.restapi.endpoints.RestApiEndpoint;
import tech.pegasys.teku.infrastructure.restapi.endpoints.RestApiRequest;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.networking.eth2.peers.Eth2Peer;

public class GetPeerCount extends RestApiEndpoint {
public static final String ROUTE = "/eth/v1/node/peer_count";

private static final SerializableTypeDefinition<ResponseData> PEER_COUNT_TYPE =
SerializableTypeDefinition.object(ResponseData.class)
.withField("disconnected", UINT64_TYPE, ResponseData::getDisconnected)
.withField("connecting", UINT64_TYPE, responseData -> UInt64.valueOf(0))
.withField("connected", UINT64_TYPE, ResponseData::getConnected)
.withField("disconnecting", UINT64_TYPE, responseData -> UInt64.valueOf(0))
.build();

private static final SerializableTypeDefinition<ResponseData> RESPONSE_TYPE =
SerializableTypeDefinition.object(ResponseData.class)
.name("GetPeerCountResponse")
.withField("data", PEER_COUNT_TYPE, Function.identity())
.build();

private final NetworkDataProvider network;

public GetPeerCount(final DataProvider provider) {
Expand All @@ -62,61 +42,14 @@ public GetPeerCount(final DataProvider provider) {
.summary("Get peer count")
.description("Retrieves number of known peers.")
.tags(TAG_NODE)
.response(SC_OK, "Request successful", RESPONSE_TYPE)
.response(SC_OK, "Request successful", PeerCountBuilder.PEER_COUNT_TYPE)
.build());
this.network = network;
}

@Override
public void handleRequest(final RestApiRequest request) throws JsonProcessingException {
request.header(Header.CACHE_CONTROL, CACHE_NONE);
request.respondOk(new ResponseData(network.getEth2Peers()));
}

static class ResponseData {
final UInt64 disconnected;
final UInt64 connected;

ResponseData(final List<Eth2Peer> peers) {
long disconnected = 0;
long connected = 0;

for (Eth2Peer peer : peers) {
if (peer.isConnected()) {
connected++;
} else {
disconnected++;
}
}

this.disconnected = UInt64.valueOf(disconnected);
this.connected = UInt64.valueOf(connected);
}

UInt64 getDisconnected() {
return disconnected;
}

UInt64 getConnected() {
return connected;
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final ResponseData that = (ResponseData) o;
return Objects.equals(disconnected, that.disconnected)
&& Objects.equals(connected, that.connected);
}

@Override
public int hashCode() {
return Objects.hash(disconnected, connected);
}
request.respondOk(network.getPeerCount());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,18 @@
import static tech.pegasys.teku.infrastructure.restapi.MetadataTestUtil.verifyMetadataErrorResponse;

import com.fasterxml.jackson.core.JsonProcessingException;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import tech.pegasys.teku.api.NetworkDataProvider;
import tech.pegasys.teku.beaconrestapi.AbstractMigratedBeaconHandlerTest;
import tech.pegasys.teku.networking.eth2.peers.Eth2Peer;
import tech.pegasys.teku.ethereum.json.types.node.PeerCount;
import tech.pegasys.teku.ethereum.json.types.node.PeerCountBuilder;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;

class GetPeerCountTest extends AbstractMigratedBeaconHandlerTest {
private final Eth2Peer peer1 = mock(Eth2Peer.class);
private final Eth2Peer peer2 = mock(Eth2Peer.class);
private final NetworkDataProvider networkDataProvider = mock(NetworkDataProvider.class);
private final List<Eth2Peer> data = List.of(peer1, peer2);
private final GetPeerCount.ResponseData peerCountData = new GetPeerCount.ResponseData(data);
private final PeerCount peerCount =
new PeerCountBuilder().disconnected(UInt64.valueOf(2)).connected(UInt64.valueOf(4)).build();

@BeforeEach
void setUp() {
Expand All @@ -45,11 +44,11 @@ void setUp() {
@Test
public void shouldReturnListOfPeers() throws Exception {

when(networkDataProvider.getEth2Peers()).thenReturn(data);
when(networkDataProvider.getPeerCount()).thenReturn(peerCount);

handler.handleRequest(request);
assertThat(request.getResponseCode()).isEqualTo(SC_OK);
assertThat(request.getResponseBody()).isEqualTo(peerCountData);
assertThat(request.getResponseBody()).isEqualTo(peerCount);
}

@Test
Expand All @@ -64,9 +63,9 @@ void metadata_shouldHandle500() throws JsonProcessingException {

@Test
void metadata_shouldHandle200() throws JsonProcessingException {
final String data = getResponseStringFromMetadata(handler, SC_OK, peerCountData);
final String data = getResponseStringFromMetadata(handler, SC_OK, peerCount);
assertThat(data)
.isEqualTo(
"{\"data\":{\"disconnected\":\"2\",\"connecting\":\"0\",\"connected\":\"0\",\"disconnecting\":\"0\"}}");
"{\"data\":{\"disconnected\":\"2\",\"connecting\":\"0\",\"connected\":\"4\",\"disconnecting\":\"0\"}}");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
import tech.pegasys.teku.api.response.v1.node.Direction;
import tech.pegasys.teku.api.response.v1.node.Peer;
import tech.pegasys.teku.api.response.v1.node.State;
import tech.pegasys.teku.ethereum.json.types.node.PeerCount;
import tech.pegasys.teku.ethereum.json.types.node.PeerCountBuilder;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.networking.eth2.Eth2P2PNetwork;
import tech.pegasys.teku.networking.eth2.peers.Eth2Peer;
import tech.pegasys.teku.networking.p2p.peer.NodeId;
Expand Down Expand Up @@ -53,7 +56,7 @@ public String getNodeIdAsBase58() {
*
* @return the the number of peers currently connected to the client
*/
public long getPeerCount() {
public long countPeers() {
return network.streamPeers().count();
}

Expand All @@ -62,8 +65,7 @@ public List<String> getListeningAddresses() {
}

public List<String> getDiscoveryAddresses() {
Optional<String> discoveryAddressOptional = network.getDiscoveryAddress();
return discoveryAddressOptional.map(List::of).orElseGet(List::of);
return network.getDiscoveryAddresses().orElseGet(List::of);
}

public MetadataMessage getMetadata() {
Expand All @@ -78,6 +80,24 @@ public List<Eth2Peer> getEth2Peers() {
return network.streamPeers().toList();
}

public PeerCount getPeerCount() {
long disconnected = 0;
long connected = 0;

for (Eth2Peer peer : getEth2Peers()) {
if (peer.isConnected()) {
connected++;
} else {
disconnected++;
}
}

return new PeerCountBuilder()
.disconnected(UInt64.valueOf(disconnected))
.connected(UInt64.valueOf(connected))
.build();
}

public List<Eth2Peer> getPeerScores() {
return network.streamPeers().toList();
}
Expand Down
Loading

0 comments on commit 4705612

Please sign in to comment.