Skip to content

Commit

Permalink
chore: Add missing javadocs to Schedule Service (#13623)
Browse files Browse the repository at this point in the history
Signed-off-by: Thomas Moran <152873392+thomas-swirlds-labs@users.noreply.github.com>
Co-authored-by: Matt Hess <matt.hess@swirldslabs.com>
  • Loading branch information
thomas-swirlds-labs and mhess-swl authored Jun 5, 2024
1 parent ca3995e commit c5088ce
Show file tree
Hide file tree
Showing 12 changed files with 292 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,45 @@
import com.hedera.node.app.service.schedule.impl.handlers.ScheduleSignHandler;
import dagger.Module;

/**
* Schedule service injection interface. Used to inject the schedule service handlers into the
* implementation class using Dagger dependency injection
*/
@Module
public interface ScheduleServiceInjectionModule {

/**
* Schedule create handler
*
* @return the schedule create handler
*/
ScheduleCreateHandler scheduleCreateHandler();

/**
* Schedule delete handler
*
* @return the schedule delete handler
*/
ScheduleDeleteHandler scheduleDeleteHandler();

/**
* Schedule get info handler
*
* @return the schedule get info handler
*/
ScheduleGetInfoHandler scheduleGetInfoHandler();

/**
* Schedule sign handler
*
* @return the schedule sign handler
*/
ScheduleSignHandler scheduleSignHandler();

/**
* Schedule handlers
*
* @return the schedule handlers
*/
ScheduleHandlers scheduleHandlers();
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,20 @@
import java.util.Collections;
import java.util.Objects;

/**
* Provides utility methods for the schedule store.
* Used to calculate the hash of a schedule which is then used to store the schedule in the schedule store.
* */
public final class ScheduleStoreUtility {
private ScheduleStoreUtility() {}

// @todo('7773') This requires rebuilding the equality virtual map on migration,
// because it's different from ScheduleVirtualValue (and must be, due to PBJ shift)
/**
* Calculate bytes hash of a schedule based on the schedule's memo, admin key, scheduled transaction, expiration
* time, and wait for expiry flag.
*
* @param scheduleToHash the schedule to hash
* @return the bytes
*/
@SuppressWarnings("UnstableApiUsage")
public static Bytes calculateBytesHash(@NonNull final Schedule scheduleToHash) {
Objects.requireNonNull(scheduleToHash);
Expand Down Expand Up @@ -77,6 +86,22 @@ private static boolean isScheduleInList(final ScheduleID scheduleId, final Sched
.anyMatch(s -> s.scheduleIdOrThrow().equals(scheduleId));
}

/**
* Adds a {@link Schedule} to a {@link ScheduleList}, replacing it if it already exists.
*
* <p>This method checks if the provided {@code Schedule} is already present in the {@code ScheduleList}.
* If it is, the existing {@code Schedule} is replaced with the new one. If it isn't, the {@code Schedule}
* is added to the list. This allows for updating entries within a {@code ScheduleList} without needing to
* manually manage duplicates or replacements.
*
* @param schedule The {@link Schedule} to add or replace in the {@code ScheduleList}. Must not be {@code null},
* unless the {@code ScheduleList} is also {@code null}.
* @param scheduleList The {@link ScheduleList} to which the {@code Schedule} will be added or replaced. May be
* {@code null}, in which case a new {@link ScheduleList} containing only the provided
* {@code Schedule} is returned.
* @return A new {@link ScheduleList} containing the {@code Schedule} either added or replacing an existing one.
* Never returns {@code null}.
*/
static ScheduleList addOrReplace(final Schedule schedule, @Nullable final ScheduleList scheduleList) {
if (scheduleList == null) {
return new ScheduleList(Collections.singletonList(schedule));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,24 @@
import java.util.Objects;
import java.util.Optional;

/**
* Utility class used for conversion of schedule virtual values to schedules.
* @deprecated Since there should not be anymore ScheduleVirtualValue objects in state,
* this class should no longer be required and will be removed in a future release
*/
@Deprecated(forRemoval = true)
public final class ScheduleServiceStateTranslator {
private static final int ED25519_KEY_LENGTH = 32;

private ScheduleServiceStateTranslator() {}

/**
* Convert schedule virtual value to schedule.
*
* @param virtualValue the virtual value
* @return the schedule
* @throws ParseException if there is an error parsing the TransactionBody message
*/
public static Schedule convertScheduleVirtualValueToSchedule(
@NonNull final com.hedera.node.app.service.mono.state.virtual.schedule.ScheduleVirtualValue virtualValue)
throws ParseException {
Expand Down Expand Up @@ -142,6 +155,14 @@ private static Timestamp getResolutionTime(@NonNull final ScheduleVirtualValue v
else return null;
}

/**
* Migrates the state of the schedule service from the scheduleId to the schedule virtual value
* using the readableStore and the ScheduleId.
*
* @param scheduleID the schedule id
* @param readableScheduleStore the readable schedule store
* @return the schedule virtual value
*/
@NonNull
public static com.hedera.node.app.service.mono.state.virtual.schedule.ScheduleVirtualValue pbjToState(
@NonNull final ScheduleID scheduleID, @NonNull final ReadableScheduleStore readableScheduleStore) {
Expand All @@ -154,6 +175,12 @@ public static com.hedera.node.app.service.mono.state.virtual.schedule.ScheduleVi
return pbjToState(optionalSchedule);
}

/**
* Converts a {@link Schedule} object to a {@link ScheduleVirtualValue}
* *
* @param schedule the schedule
* @return the schedule virtual value
*/
@NonNull
public static com.hedera.node.app.service.mono.state.virtual.schedule.ScheduleVirtualValue pbjToState(
@NonNull final Schedule schedule) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,22 @@ abstract class AbstractScheduleHandler {

/**
* A simple record to return both "deemed valid" signatories and remaining primitive keys that must sign.
*
* @param updatedSignatories a Set of "deemed valid" signatories, possibly updated with new entries
* @param remainingRequiredKeys A Set of Key entries that have not yet signed the scheduled transaction, but
* must sign that transaction before it can be executed.
*/
protected static record ScheduleKeysResult(Set<Key> updatedSignatories, Set<Key> remainingRequiredKeys) {}

/**
* Gets the set of all the keys required to sign a transaction.
*
* @param scheduleInState the schedule in state
* @param context the Prehandle context
* @return the set of keys required to sign the transaction
* @throws PreCheckException if the transaction cannot be handled successfully due to a validation failure of the
* dispatcher related to signer requirements or other pre-validation criteria.
*/
@NonNull
protected Set<Key> allKeysForTransaction(
@NonNull final Schedule scheduleInState, @NonNull final PreHandleContext context) throws PreCheckException {
Expand All @@ -78,6 +88,14 @@ protected Set<Key> allKeysForTransaction(
return getKeySetFromTransactionKeys(keyStructure);
}

/**
* Get the schedule keys result to sign the transaction
*
* @param scheduleInState the schedule in state
* @param context the Prehandle context
* @return the schedule keys result containing the updated signatories and the remaining required keys
* @throws HandleException if any validation check fails when getting the keys for the transaction
*/
@NonNull
protected ScheduleKeysResult allKeysForTransaction(
@NonNull final Schedule scheduleInState, @NonNull final HandleContext context) throws HandleException {
Expand Down Expand Up @@ -144,6 +162,13 @@ protected void verifyHasNewSignatures(
throw new HandleException(ResponseCodeEnum.NO_NEW_VALID_SIGNATURES);
}

/**
* Gets key for account.
*
* @param context the handle context
* @param accountToQuery the account to query
* @return the key for account
*/
@Nullable
protected Key getKeyForAccount(@NonNull final HandleContext context, @NonNull final AccountID accountToQuery) {
final ReadableAccountStore accountStore = context.readableStore(ReadableAccountStore.class);
Expand Down Expand Up @@ -276,6 +301,18 @@ protected void checkValidTransactionId(@Nullable final TransactionID currentId)
if (validStart == null) throw new PreCheckException(ResponseCodeEnum.INVALID_TRANSACTION_START);
}

/**
* Try to execute a schedule. Will attempt to execute a schedule if the remaining signatories are empty
* and the schedule is not waiting for expiration.
*
* @param context the context
* @param scheduleToExecute the schedule to execute
* @param remainingSignatories the remaining signatories
* @param validSignatories the valid signatories
* @param validationResult the validation result
* @param isLongTermEnabled the is long term enabled
* @return boolean indicating if the schedule was executed
*/
protected boolean tryToExecuteSchedule(
@NonNull final HandleContext context,
@NonNull final Schedule scheduleToExecute,
Expand Down Expand Up @@ -314,6 +351,12 @@ protected boolean tryToExecuteSchedule(
}
}

/**
* Checks if the validation is OK, SUCCESS, or SCHEDULE_PENDING_EXPIRATION.
*
* @param validationResult the validation result
* @return boolean indicating status of the validation
*/
protected boolean validationOk(final ResponseCodeEnum validationResult) {
return validationResult == ResponseCodeEnum.OK
|| validationResult == ResponseCodeEnum.SUCCESS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@
public final class HandlerUtility {
private HandlerUtility() {}

/**
* Return child as ordinary transaction body.
*
* @param scheduleInState the schedule in state to convert to transaction body
* @return the transaction body
*/
@NonNull
public static TransactionBody childAsOrdinary(@NonNull final Schedule scheduleInState) {
final TransactionID scheduledTransactionId = transactionIdForScheduled(scheduleInState);
Expand Down Expand Up @@ -109,6 +115,11 @@ public static TransactionBody childAsOrdinary(@NonNull final Schedule scheduleIn
return ordinary.build();
}

/**
* Given a Transaction of one type, return the corresponding HederaFunctionality.
* @param transactionType the transaction type
* @return the hedera functionality
*/
static HederaFunctionality functionalityForType(final DataOneOfType transactionType) {
return switch (transactionType) {
case CONSENSUS_CREATE_TOPIC -> HederaFunctionality.CONSENSUS_CREATE_TOPIC;
Expand Down Expand Up @@ -170,11 +181,27 @@ static Schedule markExecuted(@NonNull final Schedule schedule, @NonNull final In
.build();
}

/**
* Replace the signatories of a schedule with a new set of signatories.
* The schedule is not modified in place.
*
* @param schedule the schedule
* @param newSignatories the new signatories
* @return the schedule
*/
@NonNull
static Schedule replaceSignatories(@NonNull final Schedule schedule, @NonNull final Set<Key> newSignatories) {
return schedule.copyBuilder().signatories(List.copyOf(newSignatories)).build();
}

/**
* Replace signatories and mark executed schedule.
*
* @param schedule the schedule
* @param newSignatories the new signatories
* @param consensusTime the consensus time
* @return the schedule
*/
@NonNull
static Schedule replaceSignatoriesAndMarkExecuted(
@NonNull final Schedule schedule,
Expand Down Expand Up @@ -230,6 +257,16 @@ static Schedule createProvisionalSchedule(
return builder.build();
}

/**
* Complete the processing of a provisional schedule, which was created during a ScheduleCreate transaction.
* The schedule is completed by adding a schedule ID and signatories.
*
* @param provisionalSchedule the provisional schedule
* @param newEntityNumber the new entity number
* @param finalSignatories the final signatories for the schedule
* @return the schedule
* @throws HandleException if the transaction is not handled successfully.
*/
@NonNull
static Schedule completeProvisionalSchedule(
@NonNull final Schedule provisionalSchedule,
Expand All @@ -247,6 +284,15 @@ static Schedule completeProvisionalSchedule(
return build.build();
}

/**
* Gets next schedule id for a given parent transaction id and new schedule number.
* The schedule ID is created using the shard and realm numbers from the parent transaction ID,
* and the new schedule number.
*
* @param parentTransactionId the parent transaction id
* @param newScheduleNumber the new schedule number
* @return the next schedule id
*/
@NonNull
static ScheduleID getNextScheduleID(
@NonNull final TransactionID parentTransactionId, final long newScheduleNumber) {
Expand All @@ -257,6 +303,12 @@ static ScheduleID getNextScheduleID(
return builder.scheduleNum(newScheduleNumber).build();
}

/**
* Transaction id for scheduled transaction id.
*
* @param valueInState the value in state
* @return the transaction id
*/
@NonNull
static TransactionID transactionIdForScheduled(@NonNull Schedule valueInState) {
// original create transaction and its transaction ID will never be null, but Sonar...
Expand Down Expand Up @@ -287,6 +339,13 @@ private static long calculateExpiration(
}
}

/**
* Filters the signatories to only those that are required.
* The required signatories are those that are present in the incoming signatories set.
*
* @param signatories the signatories
* @param required the required
*/
static void filterSignatoriesToRequired(Set<Key> signatories, Set<Key> required) {
final Set<Key> incomingSignatories = Set.copyOf(signatories);
signatories.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@
public class ScheduleGetInfoHandler extends PaidQueryHandler {
private final ScheduleOpsUsage legacyUsage;

/**
* Constructor is used by the Dagger dependency injection framework to provide the necessary dependencies to the handler.
* The handler is responsible for handling the {@link HederaFunctionality#SCHEDULE_GET_INFO} query.
*
* @param legacyUsage the legacy usage
*/
@Inject
public ScheduleGetInfoHandler(ScheduleOpsUsage legacyUsage) {
this.legacyUsage = legacyUsage;
Expand Down
Loading

0 comments on commit c5088ce

Please sign in to comment.