Skip to content

Commit

Permalink
Cleanup Radix node bootstrapper of Olympia stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasGasior1 committed Oct 3, 2023
1 parent 7343e0a commit e4139ce
Show file tree
Hide file tree
Showing 39 changed files with 87 additions and 5,183 deletions.
32 changes: 0 additions & 32 deletions .run/Run Single Validator Olympia Genesis.run.xml

This file was deleted.

13 changes: 2 additions & 11 deletions cli-tools/src/main/java/com/radixdlt/shell/RadixShell.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,11 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.TypeToken;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import com.radixdlt.addressing.Addressing;
import com.radixdlt.bootstrap.RadixNodeBootstrapper;
import com.radixdlt.bootstrap.RadixNodeBootstrapperModule;
import com.radixdlt.consensus.bft.Self;
import com.radixdlt.crypto.ECKeyPair;
import com.radixdlt.crypto.RadixKeyStore;
Expand Down Expand Up @@ -209,15 +207,8 @@ public Node build() throws Exception {
properties.set("network.genesis_data", genesisDataBase64);
}

final var bootstrapperInjector =
Guice.createInjector(new RadixNodeBootstrapperModule(properties));
final var unstartedRadixNode =
bootstrapperInjector
.getInstance(RadixNodeBootstrapper.class)
.bootstrapRadixNode()
.radixNodeFuture()
.get();
final var node = new Node(unstartedRadixNode.instantiateRadixNodeModule());
final var radixNode = RadixNodeBootstrapper.runNewNode(properties);
final var node = new Node(radixNode.injector());

moduleRunnersBuilder.build().forEach(node::startRunner);

Expand Down
13 changes: 0 additions & 13 deletions core/olympia-genesis.config

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -64,42 +64,52 @@

package com.radixdlt;

import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import com.google.inject.*;
import com.google.inject.util.Modules;
import com.radixdlt.addressing.Addressing;
import com.radixdlt.api.CoreApiServer;
import com.radixdlt.api.prometheus.PrometheusApi;
import com.radixdlt.api.system.SystemApi;
import com.radixdlt.consensus.bft.SelfValidatorInfo;
import com.radixdlt.consensus.safety.PersistentSafetyStateStore;
import com.radixdlt.environment.NodeRustEnvironment;
import com.radixdlt.environment.Runners;
import com.radixdlt.genesis.GenesisProvider;
import com.radixdlt.modules.ModuleRunner;
import com.radixdlt.monitoring.MetricInstaller;
import com.radixdlt.monitoring.Metrics;
import com.radixdlt.networks.Network;
import com.radixdlt.p2p.addressbook.AddressBookPersistence;
import com.radixdlt.p2p.transport.PeerServerBootstrap;
import com.radixdlt.utils.properties.RuntimeProperties;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public final class RunningRadixNode {
public final class RadixNode {
private static final Logger log = LogManager.getLogger();

private final Injector injector;

private RunningRadixNode(Injector injector) {
private RadixNode(Injector injector) {
this.injector = injector;
}

public static RunningRadixNode run(UnstartedRadixNode unstartedRadixNode) {
log.info("Starting Radix node subsystems...");
log.info("Using a genesis of hash {}", unstartedRadixNode.genesisProvider().genesisDataHash());
public static RadixNode run(
RuntimeProperties properties, Network network, GenesisProvider genesisProvider) {
log.info("Using a genesis of hash {}", genesisProvider.genesisDataHash());

final var injector = unstartedRadixNode.instantiateRadixNodeModule();
final var runningNode = new RunningRadixNode(injector);
final var injector =
Guice.createInjector(
Modules.requireAtInjectOnConstructorsModule(),
Modules.disableCircularProxiesModule(),
new RadixNodeModule(properties, network, genesisProvider));

final var radixNode = new RadixNode(injector);

log.info("Radix node {} is starting...", radixNode.selfDetailedString());

final var metrics = injector.getInstance(Metrics.class);
injector.getInstance(MetricInstaller.class).installAt(metrics);
Expand Down Expand Up @@ -139,7 +149,16 @@ public static RunningRadixNode run(UnstartedRadixNode unstartedRadixNode) {
final var coreApiServer = injector.getInstance(CoreApiServer.class);
coreApiServer.start();

return runningNode;
return radixNode;
}

public Injector injector() {
return injector;
}

public String selfDetailedString() {
final var addressing = this.injector.getInstance(Addressing.class);
return self().toDetailedString(addressing);
}

public SelfValidatorInfo self() {
Expand All @@ -150,9 +169,9 @@ public void reportSelfStartupTime(Duration startupTimeMs) {
this.injector.getInstance(Metrics.class).misc().nodeStartup().observe(startupTimeMs);
}

public void onShutdown() {
public void shutdown() {
// using System.out.printf as logger no longer works reliably in a shutdown hook
System.out.printf("Node %s is shutting down...\n", this.self());
System.out.printf("Node %s is shutting down...\n", this.selfDetailedString());

injector
.getInstance(Key.get(new TypeLiteral<Map<String, ModuleRunner>>() {}))
Expand Down
56 changes: 9 additions & 47 deletions core/src/main/java/com/radixdlt/RadixNodeApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,7 @@
package com.radixdlt;

import com.google.common.base.Stopwatch;
import com.google.inject.Guice;
import com.google.inject.util.Modules;
import com.radixdlt.bootstrap.RadixNodeBootstrapper;
import com.radixdlt.bootstrap.RadixNodeBootstrapperModule;
import com.radixdlt.monitoring.ApplicationVersion;
import com.radixdlt.utils.MemoryLeakDetector;
import com.radixdlt.utils.properties.RuntimeProperties;
Expand All @@ -91,57 +88,22 @@ public static void main(String[] args) {
logVersion();
dumpExecutionLocation();
final var properties = RuntimeProperties.fromCommandLineArgs(args);
bootstrapRadixNode(properties);
final var nodeBootStopwatch = Stopwatch.createStarted();
final var radixNode = RadixNodeBootstrapper.runNewNode(properties);
final var startupTime = nodeBootStopwatch.elapsed();
log.info(
"Radix node {} started successfully in {} ms",
radixNode.selfDetailedString(),
startupTime.toMillis());
radixNode.reportSelfStartupTime(startupTime);
Runtime.getRuntime().addShutdownHook(new Thread(radixNode::shutdown, "Node-Shutdown"));
} catch (Exception ex) {
log.fatal("Unable to start", ex);
LogManager.shutdown(); // Flush any async logs
System.exit(-1);
}
}

private static void bootstrapRadixNode(RuntimeProperties properties) {
final var nodeBootStopwatch = Stopwatch.createStarted();
final var bootstrapperModule =
Guice.createInjector(
Modules.requireAtInjectOnConstructorsModule(),
Modules.disableCircularProxiesModule(),
new RadixNodeBootstrapperModule(properties));
final var bootstrapper = bootstrapperModule.getInstance(RadixNodeBootstrapper.class);
final var radixNodeBootstrapperHandle = bootstrapper.bootstrapRadixNode();
/* Note that because some modules obtain the resources at construction (ORAC paradigm), this
shutdown hook doesn't guarantee that these resources will be correctly freed up.
For example, when an error occurs while Guice is building its object graph,
we haven't yet received a reference (Injector) to the modules that have already been initialized,
and thus we can't clean them up.
TODO: consider refactoring the modules to follow a DNORAC (do NOT obtain resources at construction) paradigm
and then re-evaluate if the shutdown hook below (and/or the need for RadixNodeBootstrapperHandle which
provides the shutdown functionality) is still needed - for both happy (no errors during initialization)
and unhappy (errors during initialization) paths.
*/
Runtime.getRuntime()
.addShutdownHook(
new Thread(radixNodeBootstrapperHandle::onShutdown, "Bootstrapper-Shutdown"));
radixNodeBootstrapperHandle
.radixNodeFuture()
.thenAccept(
(unstartedRadixNode) -> {
final var startupTime = nodeBootStopwatch.elapsed();
final var runningNode = RunningRadixNode.run(unstartedRadixNode);
log.info(
"Radix node {} started successfully in {} ms",
runningNode.self(),
startupTime.toMillis());
runningNode.reportSelfStartupTime(startupTime);
Runtime.getRuntime()
.addShutdownHook(new Thread(runningNode::onShutdown, "Node-Shutdown"));
})
// Call .join() to block on the future completing, ensuring that errors during
// bootstrapping are not swallowed, and propagate to the "Unable to start" handler.
// In particular, errors can come from running genesis during guice initiation in
// RunningRadixNode.run(..);
.join();
}

private static void logVersion() {
log.always()
.log(
Expand Down
83 changes: 0 additions & 83 deletions core/src/main/java/com/radixdlt/UnstartedRadixNode.java

This file was deleted.

Loading

0 comments on commit e4139ce

Please sign in to comment.