Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NO MERGE] PoC Dagger DI as a system builder #8411

Draft
wants to merge 28 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a73606c
Add EventChannelSubscriber
Nashatyrev Jun 5, 2024
330b4cd
Narrow down parameter from EventChannels to EventChannelSubscriber
Nashatyrev Jun 7, 2024
e73895d
Initial version of Dagger modules (no Dagger compile check)
Nashatyrev Jun 7, 2024
a7639ae
Add RecentChainData async creation and initialization. Add WSModule
Nashatyrev Jun 19, 2024
40acba3
Complete BeaconChainController Dagger draft
Nashatyrev Jun 20, 2024
4815f66
Fix compile errors
Nashatyrev Jun 20, 2024
b100903
Add BeaconChainControllerComponent
Nashatyrev Jun 20, 2024
0938622
Resolve missing and duplicate bindings
Nashatyrev Jun 20, 2024
6434467
Resolve circular dependencies
Nashatyrev Jun 21, 2024
f5b05a9
New Dagger based BeaconChainController
Nashatyrev Jun 21, 2024
259935a
Make old/new BeaconChainController easily interchangeable
Nashatyrev Jun 21, 2024
1dd893e
Initialize BeaconChainController Dagger components inside doStart() w…
Nashatyrev Jun 21, 2024
6f7bd8c
Start AsyncRunnerEventThread right after creation
Nashatyrev Jun 21, 2024
a7eb722
Fix the mess with currentTime & genesisTime parameters order for getC…
Nashatyrev Jun 21, 2024
b067905
WeakSubjectivityFinalizedConfig updates storage prior to RecentChainD…
Nashatyrev Jun 21, 2024
34059a0
Add missing ValidatorApiChannel subscription
Nashatyrev Jun 24, 2024
6bd40ff
!!! TO ROLLBACK !!! Temp remove -Werror option
Nashatyrev Jun 25, 2024
8d491ef
Fix compiler warnings
Nashatyrev Jun 26, 2024
7277cc5
Add stricter Dagger compiler options
Nashatyrev Jun 26, 2024
8c5ee39
Return back -Werror
Nashatyrev Jun 26, 2024
b7893a7
Enable errorprone disableWarningsInGeneratedCode
Nashatyrev Jun 26, 2024
f569747
Spotless
Nashatyrev Jun 26, 2024
e8c0296
Remove AbstractBeaconChainController
Nashatyrev Jun 26, 2024
a8958fb
Redesign BeaconChainController creation
Nashatyrev Jun 26, 2024
c99e740
Adopt TekuConfigurationTest
Nashatyrev Jun 26, 2024
8ed7f5d
Merge branch 'refs/heads/master' into experiment/dagger-beacon-chain
Nashatyrev Jun 27, 2024
04e8b3b
Adopt latest config PRs to master
Nashatyrev Jul 1, 2024
124292c
Made method params final
Nashatyrev Jul 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ allprojects {

options.errorprone {
enabled = !'true'.equalsIgnoreCase(System.getProperty('avt.disableErrorProne'))
disableWarningsInGeneratedCode
disableWarningsInGeneratedCode = true

// Our equals need to be symmetric, this checker doesn't respect that
check('EqualsGetClass', net.ltgt.gradle.errorprone.CheckSeverity.OFF)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public class OperationsReOrgManager implements ChainHeadChannel {
private final OperationPool<AttesterSlashing> attesterSlashingPool;
private final AttestationManager attestationManager;
private final AggregatingAttestationPool attestationPool;
private final MappedOperationPool<SignedBlsToExecutionChange> blsToExecutionOperationPool;
private final OperationPool<SignedBlsToExecutionChange> blsToExecutionOperationPool;
private final RecentChainData recentChainData;

public OperationsReOrgManager(
Expand All @@ -52,7 +52,7 @@ public OperationsReOrgManager(
final OperationPool<SignedVoluntaryExit> exitPool,
final AggregatingAttestationPool attestationPool,
final AttestationManager attestationManager,
final MappedOperationPool<SignedBlsToExecutionChange> blsToExecutionOperationPool,
final OperationPool<SignedBlsToExecutionChange> blsToExecutionOperationPool,
final RecentChainData recentChainData) {
this.exitPool = exitPool;
this.proposerSlashingPool = proposerSlashingPool;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright Consensys Software Inc., 2024
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/

package tech.pegasys.teku.infrastructure.events;

public interface EventChannelSubscriber<T extends ChannelInterface> {

void subscribe(T listener);
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ public <T extends ChannelInterface> EventChannels subscribe(
return subscribeMultithreaded(channelInterface, subscriber, 1);
}

public <T extends ChannelInterface> EventChannelSubscriber<T> createSubscriber(
final Class<T> channelInterface) {
return createSubscriberMultithreaded(channelInterface, 1);
}

/**
* Adds a subscriber to this channel where events are handled by multiple threads concurrently.
*
Expand All @@ -99,10 +104,16 @@ public <T extends ChannelInterface> EventChannels subscribe(
*/
public <T extends ChannelInterface> EventChannels subscribeMultithreaded(
final Class<T> channelInterface, final T subscriber, final int requestedParallelism) {
getChannel(channelInterface).subscribeMultithreaded(subscriber, requestedParallelism);
createSubscriberMultithreaded(channelInterface, requestedParallelism).subscribe(subscriber);
return this;
}

public <T extends ChannelInterface> EventChannelSubscriber<T> createSubscriberMultithreaded(
final Class<T> channelInterface, final int requestedParallelism) {
return listener ->
getChannel(channelInterface).subscribeMultithreaded(listener, requestedParallelism);
}

@SuppressWarnings("unchecked")
private <T extends ChannelInterface> EventChannel<T> getChannel(final Class<T> channelInterface) {
return (EventChannel<T>) channels.computeIfAbsent(channelInterface, eventChannelFactory);
Expand Down
11 changes: 11 additions & 0 deletions services/beaconchain/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ dependencies {
implementation project(':validator:api')
implementation project(':validator:client')

implementation 'com.google.dagger:dagger:2.51.1'
annotationProcessor 'com.google.dagger:dagger-compiler:2.51.1'

testImplementation testFixtures(project(':storage'))
testImplementation testFixtures(project(':ethereum:spec'))
testImplementation testFixtures(project(':ethereum:statetransition'))
Expand All @@ -43,4 +46,12 @@ dependencies {
testImplementation testFixtures(project(':infrastructure:metrics'))

implementation 'io.libp2p:jvm-libp2p'
}

tasks.withType(JavaCompile) {
options.compilerArgs += [
'-Adagger.formatGeneratedSource=enabled',
'-Adagger.fullBindingGraphValidation=ERROR',
'-Adagger.ignoreProvisionKeyWildcards=ENABLED'
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import tech.pegasys.teku.infrastructure.async.AsyncRunnerFactory;
import tech.pegasys.teku.infrastructure.time.TimeProvider;
import tech.pegasys.teku.networking.eth2.Eth2P2PNetwork;
import tech.pegasys.teku.service.serviceutils.ServiceFacade;
import tech.pegasys.teku.spec.Spec;
import tech.pegasys.teku.statetransition.forkchoice.ForkChoice;
import tech.pegasys.teku.statetransition.validation.signatures.SignatureVerificationService;
Expand All @@ -29,7 +30,7 @@
* CAUTION: this API is unstable and primarily intended for debugging and testing purposes this API
* might be changed in any version in backward incompatible way
*/
public interface BeaconChainControllerFacade {
public interface BeaconChainControllerFacade extends ServiceFacade {

Spec getSpec();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,26 @@
package tech.pegasys.teku.services.beaconchain;

import tech.pegasys.teku.service.serviceutils.ServiceConfig;
import tech.pegasys.teku.services.beaconchain.init.DaggerBeaconChainControllerComponent;
import tech.pegasys.teku.services.beaconchain.init.ExternalDependenciesModule;

/**
* CAUTION: this API is unstable and primarily intended for debugging and testing purposes this API
* might be changed in any version in backward incompatible way
*/
public interface BeaconChainControllerFactory {

BeaconChainControllerFactory DEFAULT = BeaconChainController::new;
BeaconChainControllerFactory DEFAULT =
LateInitDelegateBeaconChainController.createLateInitFactory(
(serviceConfig, beaconConfig) ->
DaggerBeaconChainControllerComponent.builder()
.externalDependenciesModule(
new ExternalDependenciesModule(serviceConfig, beaconConfig))
.build()
.beaconChainController());

BeaconChainController create(
BeaconChainControllerFactory OLD = BeaconChainControllerOld::new;

BeaconChainControllerFacade create(
final ServiceConfig serviceConfig, final BeaconChainConfiguration beaconConfig);
}
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@
* initialization behavior (see {@link BeaconChainControllerFactory}} however this class may change
* in a backward incompatible manner and either break compilation or runtime behavior
*/
public class BeaconChainController extends Service implements BeaconChainControllerFacade {
public class BeaconChainControllerOld extends Service implements BeaconChainControllerFacade {

private static final Logger LOG = LogManager.getLogger();

Expand Down Expand Up @@ -292,7 +292,7 @@ public class BeaconChainController extends Service implements BeaconChainControl
protected IntSupplier rejectedExecutionCountSupplier;
protected DebugDataDumper debugDataDumper;

public BeaconChainController(
public BeaconChainControllerOld(
final ServiceConfig serviceConfig, final BeaconChainConfiguration beaconConfig) {
final Eth2NetworkConfiguration eth2NetworkConfig = beaconConfig.eth2NetworkConfig();
final DataDirLayout dataDirLayout = serviceConfig.getDataDirLayout();
Expand Down Expand Up @@ -406,11 +406,13 @@ protected SafeFuture<?> doStop() {
}

protected SafeFuture<?> initialize() {

timerService = new TimerService(this::onTick);

final StoreConfig storeConfig = beaconConfig.storeConfig();
coalescingChainHeadChannel =
new CoalescingChainHeadChannel(
eventChannels.getPublisher(ChainHeadChannel.class), EVENT_LOG);
timerService = new TimerService(this::onTick);

final CombinedStorageChannel combinedStorageChannel =
eventChannels.getPublisher(CombinedStorageChannel.class, beaconAsyncRunner);
Expand Down Expand Up @@ -889,7 +891,8 @@ protected void initSubnetSubscriber() {
public void initExecutionLayerBlockProductionManager() {
LOG.debug("BeaconChainController.initExecutionLayerBlockProductionManager()");
this.executionLayerBlockProductionManager =
ExecutionLayerBlockManagerFactory.create(executionLayer, eventChannels);
ExecutionLayerBlockManagerFactory.create(
executionLayer, eventChannels.createSubscriber(SlotEventsChannel.class));
}

public void initRewardCalculator() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

public class BeaconChainService extends Service implements BeaconChainServiceFacade {

private final BeaconChainController controller;
private final BeaconChainControllerFacade controller;

public BeaconChainService(
final ServiceConfig serviceConfig, final BeaconChainConfiguration beaconConfig) {
Expand All @@ -38,7 +38,7 @@ protected SafeFuture<?> doStop() {
}

@Override
public BeaconChainController getBeaconChainController() {
public BeaconChainControllerFacade getBeaconChainController() {
return controller;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright Consensys Software Inc., 2022
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/

package tech.pegasys.teku.services.beaconchain;

import java.util.Optional;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import tech.pegasys.teku.beacon.sync.SyncService;
import tech.pegasys.teku.beaconrestapi.BeaconRestApi;
import tech.pegasys.teku.infrastructure.async.AsyncRunnerFactory;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
import tech.pegasys.teku.infrastructure.time.TimeProvider;
import tech.pegasys.teku.networking.eth2.Eth2P2PNetwork;
import tech.pegasys.teku.service.serviceutils.Service;
import tech.pegasys.teku.service.serviceutils.ServiceConfig;
import tech.pegasys.teku.spec.Spec;
import tech.pegasys.teku.statetransition.forkchoice.ForkChoice;
import tech.pegasys.teku.statetransition.validation.signatures.SignatureVerificationService;
import tech.pegasys.teku.storage.client.CombinedChainDataClient;
import tech.pegasys.teku.storage.client.RecentChainData;

public class LateInitDelegateBeaconChainController extends Service
implements BeaconChainControllerFacade {

public static BeaconChainControllerFactory createLateInitFactory(
final BeaconChainControllerFactory delegateFactory) {
return (serviceConfig, beaconConfig) ->
new LateInitDelegateBeaconChainController(serviceConfig, beaconConfig, delegateFactory);
}

private static final Logger LOG = LogManager.getLogger();

private final ServiceConfig serviceConfig;
private final BeaconChainConfiguration beaconConfig;
private final BeaconChainControllerFactory delegateFactory;

private volatile BeaconChainControllerFacade delegate;

public LateInitDelegateBeaconChainController(
final ServiceConfig serviceConfig,
final BeaconChainConfiguration beaconConfig,
final BeaconChainControllerFactory delegateFactory) {
this.serviceConfig = serviceConfig;
this.beaconConfig = beaconConfig;
this.delegateFactory = delegateFactory;
}

@Override
protected SafeFuture<?> doStart() {
LOG.info("Starting BeaconChainController...");
this.delegate = delegateFactory.create(serviceConfig, beaconConfig);

SafeFuture<?> startFuture = this.delegate.start();
LOG.info("BeaconChainController start complete");

return startFuture;
}

@Override
protected SafeFuture<?> doStop() {
return this.delegate.stop();
}

@Override
public Spec getSpec() {
return delegate.getSpec();
}

@Override
public TimeProvider getTimeProvider() {
return delegate.getTimeProvider();
}

@Override
public AsyncRunnerFactory getAsyncRunnerFactory() {
return delegate.getAsyncRunnerFactory();
}

@Override
public SignatureVerificationService getSignatureVerificationService() {
return delegate.getSignatureVerificationService();
}

@Override
public RecentChainData getRecentChainData() {
return delegate.getRecentChainData();
}

@Override
public CombinedChainDataClient getCombinedChainDataClient() {
return delegate.getCombinedChainDataClient();
}

@Override
public Eth2P2PNetwork getP2pNetwork() {
return delegate.getP2pNetwork();
}

@Override
public Optional<BeaconRestApi> getBeaconRestAPI() {
return delegate.getBeaconRestAPI();
}

@Override
public SyncService getSyncService() {
return delegate.getSyncService();
}

@Override
public ForkChoice getForkChoice() {
return delegate.getForkChoice();
}
}
Loading