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
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Redesign BeaconChainController creation
Nashatyrev committed Jun 26, 2024
commit a8958fb35e447ae8d4890cc3fdccbe90c1881685
Original file line number Diff line number Diff line change
@@ -14,6 +14,8 @@
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
@@ -22,8 +24,15 @@
public interface BeaconChainControllerFactory {

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

BeaconChainControllerFactory OLD = BeaconChainControllerOld::new;

BeaconChainControllerFacade create(
final ServiceConfig serviceConfig, final BeaconChainConfiguration beaconConfig);
Original file line number Diff line number Diff line change
@@ -14,7 +14,6 @@
package tech.pegasys.teku.services.beaconchain;

import java.util.Optional;
import java.util.function.Supplier;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import tech.pegasys.teku.beacon.sync.SyncService;
@@ -25,127 +24,101 @@
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.services.beaconchain.init.BeaconChainControllerComponent;
import tech.pegasys.teku.services.beaconchain.init.DaggerBeaconChainControllerComponent;
import tech.pegasys.teku.services.beaconchain.init.ExternalDependenciesModule;
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;

/**
* The central class which assembles together and initializes Beacon Chain components
*
* <p>CAUTION: This class can be overridden by custom implementation to tweak creation and
* 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 LateInitDelegateBeaconChainController extends Service
implements BeaconChainControllerFacade {

public static BeaconChainControllerFactory createLateInitFactory(
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;

private Spec spec;
private TimeProvider timeProvider;
private AsyncRunnerFactory asyncRunnerFactory;
private ForkChoice forkChoice;
private RecentChainData recentChainData;
private Eth2P2PNetwork p2pNetwork;
private Optional<BeaconRestApi> beaconRestAPI;
private SyncService syncService;
private SignatureVerificationService signatureVerificationService;
private CombinedChainDataClient combinedChainDataClient;

private Supplier<SafeFuture<?>> starter;
private Supplier<SafeFuture<?>> stopper;

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

@Override
protected SafeFuture<?> doStart() {
LOG.info("Starting BeaconChainController...");
BeaconChainControllerComponent component =
DaggerBeaconChainControllerComponent.builder()
.externalDependenciesModule(new ExternalDependenciesModule(serviceConfig, beaconConfig))
.build();

this.spec = component.getSpec();
this.timeProvider = component.getTimeProvider();
this.asyncRunnerFactory = component.getAsyncRunnerFactory();
this.forkChoice = component.getForkChoice();
this.recentChainData = component.getRecentChainData();
this.p2pNetwork = component.getP2pNetwork();
this.beaconRestAPI = component.getBeaconRestAPI();
this.syncService = component.getSyncService();
this.signatureVerificationService = component.getSignatureVerificationService();
this.combinedChainDataClient = component.getCombinedChainDataClient();
this.starter = () -> component.starter().start();
this.stopper = () -> component.stopper().stop();

SafeFuture<?> startFuture = this.starter.get();
this.delegate = delegateFactory.create(serviceConfig, beaconConfig);

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

return startFuture;
}

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

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

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

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

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

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

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

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

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

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

@Override
public ForkChoice getForkChoice() {
return forkChoice;
return delegate.getForkChoice();
}
}
Original file line number Diff line number Diff line change
@@ -14,18 +14,8 @@
package tech.pegasys.teku.services.beaconchain.init;

import dagger.Component;
import java.util.Optional;
import javax.inject.Singleton;
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.time.TimeProvider;
import tech.pegasys.teku.networking.eth2.Eth2P2PNetwork;
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;
import tech.pegasys.teku.services.beaconchain.BeaconChainControllerFacade;

@Singleton
@Component(
@@ -56,27 +46,5 @@
})
public interface BeaconChainControllerComponent {

MainModule.ServiceStarter starter();

MainModule.ServiceStopper stopper();

Spec getSpec();

TimeProvider getTimeProvider();

AsyncRunnerFactory getAsyncRunnerFactory();

SignatureVerificationService getSignatureVerificationService();

RecentChainData getRecentChainData();

CombinedChainDataClient getCombinedChainDataClient();

Eth2P2PNetwork getP2pNetwork();

Optional<BeaconRestApi> getBeaconRestAPI();

SyncService getSyncService();

ForkChoice getForkChoice();
BeaconChainControllerFacade beaconChainController();
}
Original file line number Diff line number Diff line change
@@ -20,7 +20,6 @@
import org.apache.logging.log4j.Logger;
import tech.pegasys.teku.infrastructure.logging.EventLogger;
import tech.pegasys.teku.infrastructure.logging.StatusLogger;
import tech.pegasys.teku.services.beaconchain.BeaconChainController;

@Module
public interface LoggingModule {
@@ -43,6 +42,6 @@ static EventLogger eventLogger() {
@Provides
@Singleton
static InitLogger initLogger() {
return new InitLogger(LogManager.getLogger(BeaconChainController.class));
return new InitLogger(LogManager.getLogger("BeaconChainController"));
}
}
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@

package tech.pegasys.teku.services.beaconchain.init;

import dagger.Binds;
import dagger.Lazy;
import dagger.Module;
import dagger.Provides;
@@ -28,6 +29,7 @@
import tech.pegasys.teku.infrastructure.async.eventthread.AsyncRunnerEventThread;
import tech.pegasys.teku.infrastructure.logging.StatusLogger;
import tech.pegasys.teku.networking.eth2.Eth2P2PNetwork;
import tech.pegasys.teku.services.beaconchain.BeaconChainControllerFacade;
import tech.pegasys.teku.services.beaconchain.init.AsyncRunnerModule.ForkChoiceExecutor;
import tech.pegasys.teku.services.beaconchain.init.AsyncRunnerModule.ForkChoiceNotifierExecutor;
import tech.pegasys.teku.services.beaconchain.init.LoggingModule.InitLogger;
@@ -63,6 +65,10 @@ interface ServiceStopper {
SafeFuture<Void> stop();
}

@Binds
@Singleton
BeaconChainControllerFacade beaconChainController(SimpleBeaconChainController impl);

@Provides
@IntoSet
static VoidInitializer initSlashingEventsSubscriptions(
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* 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.services.beaconchain.init;

import java.util.Optional;
import javax.inject.Inject;
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.services.beaconchain.BeaconChainControllerFacade;
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 SimpleBeaconChainController implements BeaconChainControllerFacade {
@Inject MainModule.ServiceStarter starter;
@Inject MainModule.ServiceStopper stopper;
@Inject Spec spec;
@Inject TimeProvider timeProvider;
@Inject AsyncRunnerFactory asyncRunnerFactory;
@Inject SignatureVerificationService signatureVerificationService;
@Inject RecentChainData recentChainData;
@Inject CombinedChainDataClient combinedChainDataClient;
@Inject Eth2P2PNetwork p2pNetwork;
@Inject Optional<BeaconRestApi> beaconRestApi;
@Inject SyncService syncService;
@Inject ForkChoice forkChoice;

@Inject
public SimpleBeaconChainController() {}

@Override
public SafeFuture<?> start() {
return starter.start();
}

@Override
public SafeFuture<?> stop() {
return stopper.stop();
}

@Override
public boolean isRunning() {
throw new UnsupportedOperationException();
}

@Override
public Spec getSpec() {
return spec;
}

@Override
public TimeProvider getTimeProvider() {
return timeProvider;
}

@Override
public AsyncRunnerFactory getAsyncRunnerFactory() {
return asyncRunnerFactory;
}

@Override
public SignatureVerificationService getSignatureVerificationService() {
return signatureVerificationService;
}

@Override
public RecentChainData getRecentChainData() {
return recentChainData;
}

@Override
public CombinedChainDataClient getCombinedChainDataClient() {
return combinedChainDataClient;
}

@Override
public Eth2P2PNetwork getP2pNetwork() {
return p2pNetwork;
}

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

@Override
public SyncService getSyncService() {
return syncService;
}

@Override
public ForkChoice getForkChoice() {
return forkChoice;
}
}