Skip to content

Commit

Permalink
chore: create a state signer component (#10411)
Browse files Browse the repository at this point in the history
Signed-off-by: Lazar Petrovic <lpetrovic05@gmail.com>
  • Loading branch information
lpetrovic05 authored Dec 13, 2023
1 parent eba77e8 commit c7dd6e7
Show file tree
Hide file tree
Showing 13 changed files with 237 additions and 293 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType;
import com.swirlds.config.api.ConfigData;
import com.swirlds.config.api.ConfigProperty;
import edu.umd.cs.findbugs.annotations.NonNull;

/**
* Contains configuration values for the platform schedulers.
Expand All @@ -46,103 +45,27 @@
* @param signedStateFileManagerSchedulerType the signed state file manager scheduler type
* @param signedStateFileManagerUnhandledCapacity number of unhandled tasks allowed in the signed state file manager
* scheduler
* @param stateSignerSchedulerType the state signer scheduler type
* @param stateSignerUnhandledCapacity number of unhandled tasks allowed in the state signer scheduler,
* default is -1 (unlimited)
*/
@ConfigData("platformSchedulers")
public record PlatformSchedulersConfig(
@ConfigProperty(defaultValue = "SEQUENTIAL") String internalEventValidatorSchedulerType,
@ConfigProperty(defaultValue = "SEQUENTIAL") TaskSchedulerType internalEventValidatorSchedulerType,
@ConfigProperty(defaultValue = "500") int internalEventValidatorUnhandledCapacity,
@ConfigProperty(defaultValue = "SEQUENTIAL") String eventDeduplicatorSchedulerType,
@ConfigProperty(defaultValue = "SEQUENTIAL") TaskSchedulerType eventDeduplicatorSchedulerType,
@ConfigProperty(defaultValue = "500") int eventDeduplicatorUnhandledCapacity,
@ConfigProperty(defaultValue = "SEQUENTIAL") String eventSignatureValidatorSchedulerType,
@ConfigProperty(defaultValue = "SEQUENTIAL") TaskSchedulerType eventSignatureValidatorSchedulerType,
@ConfigProperty(defaultValue = "500") int eventSignatureValidatorUnhandledCapacity,
@ConfigProperty(defaultValue = "SEQUENTIAL") String orphanBufferSchedulerType,
@ConfigProperty(defaultValue = "SEQUENTIAL") TaskSchedulerType orphanBufferSchedulerType,
@ConfigProperty(defaultValue = "500") int orphanBufferUnhandledCapacity,
@ConfigProperty(defaultValue = "SEQUENTIAL") String inOrderLinkerSchedulerType,
@ConfigProperty(defaultValue = "SEQUENTIAL") TaskSchedulerType inOrderLinkerSchedulerType,
@ConfigProperty(defaultValue = "500") int inOrderLinkerUnhandledCapacity,
@ConfigProperty(defaultValue = "SEQUENTIAL") String linkedEventIntakeSchedulerType,
@ConfigProperty(defaultValue = "SEQUENTIAL") TaskSchedulerType linkedEventIntakeSchedulerType,
@ConfigProperty(defaultValue = "500") int linkedEventIntakeUnhandledCapacity,
@ConfigProperty(defaultValue = "SEQUENTIAL") String eventCreationManagerSchedulerType,
@ConfigProperty(defaultValue = "SEQUENTIAL") TaskSchedulerType eventCreationManagerSchedulerType,
@ConfigProperty(defaultValue = "500") int eventCreationManagerUnhandledCapacity,
@ConfigProperty(defaultValue = "SEQUENTIAL_THREAD") String signedStateFileManagerSchedulerType,
@ConfigProperty(defaultValue = "20") int signedStateFileManagerUnhandledCapacity) {

/**
* Get the internal event validator scheduler type
*
* @return the internal event validator scheduler type
*/
@NonNull
public TaskSchedulerType getInternalEventValidatorSchedulerType() {
return TaskSchedulerType.valueOf(internalEventValidatorSchedulerType);
}

/**
* Get the event deduplicator scheduler type
*
* @return the event deduplicator scheduler type
*/
@NonNull
public TaskSchedulerType getEventDeduplicatorSchedulerType() {
return TaskSchedulerType.valueOf(eventDeduplicatorSchedulerType);
}

/**
* Get the event signature validator scheduler type
*
* @return the event signature validator scheduler type
*/
@NonNull
public TaskSchedulerType getEventSignatureValidatorSchedulerType() {
return TaskSchedulerType.valueOf(eventSignatureValidatorSchedulerType);
}

/**
* Get the orphan buffer scheduler type
*
* @return the orphan buffer scheduler type
*/
@NonNull
public TaskSchedulerType getOrphanBufferSchedulerType() {
return TaskSchedulerType.valueOf(orphanBufferSchedulerType);
}

/**
* Get the in-order linker scheduler type
*
* @return the in-order linker scheduler type
*/
@NonNull
public TaskSchedulerType getInOrderLinkerSchedulerType() {
return TaskSchedulerType.valueOf(inOrderLinkerSchedulerType);
}

/**
* Get the linked event intake scheduler type
*
* @return the linked event intake scheduler type
*/
@NonNull
public TaskSchedulerType getLinkedEventIntakeSchedulerType() {
return TaskSchedulerType.valueOf(linkedEventIntakeSchedulerType);
}

/**
* Get the event creation manager scheduler type
*
* @return the event creation manager scheduler type
*/
@NonNull
public TaskSchedulerType getEventCreationManagerSchedulerType() {
return TaskSchedulerType.valueOf(eventCreationManagerSchedulerType);
}

/**
* Get the signed state file manager scheduler type
*
* @return the signed state file manager scheduler type
*/
@NonNull
public TaskSchedulerType getSignedStateFileManagerSchedulerType() {
return TaskSchedulerType.valueOf(signedStateFileManagerSchedulerType);
}
}
@ConfigProperty(defaultValue = "SEQUENTIAL_THREAD") TaskSchedulerType signedStateFileManagerSchedulerType,
@ConfigProperty(defaultValue = "20") int signedStateFileManagerUnhandledCapacity,
@ConfigProperty(defaultValue = "SEQUENTIAL_THREAD") TaskSchedulerType stateSignerSchedulerType,
@ConfigProperty(defaultValue = "-1") int stateSignerUnhandledCapacity) {}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
import java.util.Objects;

class ConverterService implements ConfigLifecycle {

private final Map<Class<?>, ConfigConverter<?>> converters;

private boolean initialized = false;
Expand Down Expand Up @@ -116,7 +115,7 @@ private <T, C extends ConfigConverter<T>> Class<T> getConverterType(@NonNull fin
.orElseGet(() -> getConverterType((Class<C>) converterClass.getSuperclass()));
}

@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
@Nullable
<T> T convert(@Nullable final String value, @NonNull final Class<T> targetClass) {
throwIfNotInitialized();
Expand All @@ -128,6 +127,20 @@ <T> T convert(@Nullable final String value, @NonNull final Class<T> targetClass)
return (T) value;
}
final ConfigConverter<T> converter = (ConfigConverter<T>) converters.get(targetClass);

if (converter == null && targetClass.isEnum()) {
// FUTURE WORK: once logging is added to this module, log a warning here
// ("No converter defined for type '" + targetClass + "'. Converting using backup enum converter.");
try {
return (T) Enum.valueOf((Class<Enum>) targetClass, value);
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException(
"Can not convert value '%s' of Enum '%s' by default. Please add a custom config converter."
.formatted(value, targetClass),
e);
}
}

if (converter == null) {
throw new IllegalArgumentException("No converter defined for type '" + targetClass + "'");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (C) 2023 Hedera Hashgraph, LLC
*
* 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 com.swirlds.platform;

import com.swirlds.common.crypto.Hash;
import com.swirlds.common.crypto.Signature;
import com.swirlds.common.stream.HashSigner;
import com.swirlds.platform.state.signed.ReservedSignedState;
import com.swirlds.platform.system.status.PlatformStatus;
import com.swirlds.platform.system.status.PlatformStatusGetter;
import com.swirlds.platform.system.transaction.StateSignatureTransaction;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.util.Objects;

/**
* This class is responsible for signing states and producing {@link StateSignatureTransaction}s.
*/
public class StateSigner {
/** An object responsible for signing states with this node's key. */
private final HashSigner signer;
/** provides the current platform status */
private final PlatformStatusGetter platformStatusGetter;

/**
* Create a new {@link StateSigner} instance.
*
* @param signer an object responsible for signing states with this node's key
* @param platformStatusGetter provides the current platform status
*/
public StateSigner(@NonNull final HashSigner signer, @NonNull final PlatformStatusGetter platformStatusGetter) {
this.signer = Objects.requireNonNull(signer);
this.platformStatusGetter = Objects.requireNonNull(platformStatusGetter);
}

/**
* Sign the given state and produce a {@link StateSignatureTransaction} containing the signature. This method
* assumes that the given {@link ReservedSignedState} is reserved by the caller and will release the state when
* done.
*
* @param reservedSignedState the state to sign
* @return a {@link StateSignatureTransaction} containing the signature, or null if the state should not be signed
*/
public @Nullable StateSignatureTransaction signState(@NonNull final ReservedSignedState reservedSignedState) {
try (reservedSignedState) {
if (platformStatusGetter.getCurrentStatus() == PlatformStatus.REPLAYING_EVENTS) {
// the only time we don't want to submit signatures is during PCES replay
return null;
}

final Hash stateHash =
Objects.requireNonNull(reservedSignedState.get().getState().getHash());
final Signature signature = signer.sign(stateHash);
Objects.requireNonNull(signature);

return new StateSignatureTransaction(reservedSignedState.get().getRound(), signature, stateHash);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@
import com.swirlds.platform.system.status.actions.StartedReplayingEventsAction;
import com.swirlds.platform.system.transaction.StateSignatureTransaction;
import com.swirlds.platform.system.transaction.SwirldTransaction;
import com.swirlds.platform.system.transaction.SystemTransaction;
import com.swirlds.platform.threading.PauseAndLoad;
import com.swirlds.platform.util.PlatformComponents;
import com.swirlds.platform.wiring.PlatformWiring;
Expand Down Expand Up @@ -503,15 +502,19 @@ public class SwirldsPlatform implements Platform {
actualMainClassName,
selfId,
swirldName);

transactionPool = new TransactionPool(platformContext);

// FUTURE WORK: at some point this should be part of the unified platform wiring
final WiringModel model = WiringModel.create(platformContext, Time.getCurrent());
components.add(model);

platformWiring = components.add(new PlatformWiring(platformContext, time));
platformWiring.wireExternalComponents(
preconsensusEventWriter, platformStatusManager, appCommunicationComponent);
preconsensusEventWriter, platformStatusManager, appCommunicationComponent, transactionPool);

platformWiring.bind(signedStateFileManager);
final StateSigner stateSigner = new StateSigner(new PlatformSigner(keysAndCerts), platformStatusManager);
platformWiring.bind(signedStateFileManager, stateSigner);

final LatestCompleteStateNexus latestCompleteState =
new LatestCompleteStateNexus(stateConfig, platformContext.getMetrics());
Expand All @@ -529,13 +532,11 @@ public class SwirldsPlatform implements Platform {
platformContext,
threadManager,
dispatchBuilder,
new PlatformSigner(keysAndCerts),
txn -> this.createSystemTransaction(txn, true),
newLatestCompleteStateConsumer,
this::handleFatalError,
platformStatusManager,
savedStateController,
platformWiring.getDumpStateToDiskInput()::put);
platformWiring.getDumpStateToDiskInput()::put,
platformWiring.getSignStateInput()::put);

// Load the minimum generation into the pre-consensus event writer
final List<SavedStateInfo> savedStates = getSavedStateFiles(actualMainClassName, selfId, swirldName);
Expand Down Expand Up @@ -596,8 +597,6 @@ public class SwirldsPlatform implements Platform {
final TransactionConfig transactionConfig =
platformContext.getConfiguration().getConfigData(TransactionConfig.class);

transactionPool = new TransactionPool(platformContext);

// This object makes a copy of the state. After this point, initialState becomes immutable.
swirldStateManager = new SwirldStateManager(
platformContext,
Expand Down Expand Up @@ -925,18 +924,6 @@ public NodeId getSelfId() {
return selfId;
}

/**
* Stores a new system transaction that will be added to an event in the future.
*
* @param systemTransaction the new system transaction to be included in a future event
* @return {@code true} if successful, {@code false} otherwise
*/
private boolean createSystemTransaction(
@NonNull final SystemTransaction systemTransaction, final boolean priority) {
Objects.requireNonNull(systemTransaction);
return transactionPool.submitTransaction(systemTransaction, priority);
}

/**
* Initialize the state.
*
Expand Down

This file was deleted.

Loading

0 comments on commit c7dd6e7

Please sign in to comment.