Skip to content

Commit

Permalink
chore: Add placeholder HintsService, HistoryService, integrate wi…
Browse files Browse the repository at this point in the history
…th app infrastructure (#17222)

Signed-off-by: Michael Tinker <michael.tinker@swirldslabs.com>
Co-authored-by: Neeharika Sompalli <52669918+Neeharika-Sompalli@users.noreply.github.com>
  • Loading branch information
tinker-michaelj and Neeharika-Sompalli authored Jan 15, 2025
1 parent 46446f1 commit 418e6d3
Show file tree
Hide file tree
Showing 45 changed files with 2,424 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
import com.hedera.node.app.config.BootstrapConfigProviderImpl;
import com.hedera.node.app.config.ConfigProviderImpl;
import com.hedera.node.app.fees.FeeService;
import com.hedera.node.app.hints.HintsService;
import com.hedera.node.app.history.HistoryService;
import com.hedera.node.app.ids.EntityIdService;
import com.hedera.node.app.info.CurrentPlatformStatusImpl;
import com.hedera.node.app.info.GenesisNetworkInfo;
Expand Down Expand Up @@ -268,6 +270,18 @@ public final class Hedera
*/
private final BlockStreamService blockStreamService;

/**
* The hinTS service singleton, kept as a field here to avoid constructing twice
* (once in constructor to register schemas, again inside Dagger component).
*/
private final HintsService hintsService;

/**
* The history service singleton, kept as a field here to avoid constructing twice
* (once in constructor to register schemas, again inside Dagger component).
*/
private final HistoryService historyService;

/**
* The block hash signer factory.
*/
Expand Down Expand Up @@ -366,10 +380,25 @@ public interface StartupNetworksFactory {
StartupNetworks apply(@NonNull ConfigProvider configProvider);
}

@FunctionalInterface
public interface HintsServiceFactory {
@NonNull
HintsService apply(@NonNull AppContext appContext);
}

@FunctionalInterface
public interface HistoryServiceFactory {
@NonNull
HistoryService apply(@NonNull AppContext appContext);
}

@FunctionalInterface
public interface BlockHashSignerFactory {
@NonNull
BlockHashSigner apply();
BlockHashSigner apply(
@NonNull HintsService hintsService,
@NonNull HistoryService historyService,
@NonNull ConfigProvider configProvider);
}

/*==================================================================================================================
Expand All @@ -390,6 +419,8 @@ public interface BlockHashSignerFactory {
* @param migrator the migrator to use with the services
* @param startupNetworksFactory the factory for the startup networks
* @param blockHashSignerFactory the factory for the block hash signer
* @param hintsServiceFactory the factory for the hints service
* @param historyServiceFactory the factory for the history service
* @param metrics the metrics object to use for reporting
*/
public Hedera(
Expand All @@ -399,6 +430,8 @@ public Hedera(
@NonNull final InstantSource instantSource,
@NonNull final StartupNetworksFactory startupNetworksFactory,
@NonNull final BlockHashSignerFactory blockHashSignerFactory,
@NonNull final HintsServiceFactory hintsServiceFactory,
@NonNull final HistoryServiceFactory historyServiceFactory,
@NonNull final Metrics metrics) {
requireNonNull(registryFactory);
requireNonNull(constructableRegistry);
Expand Down Expand Up @@ -444,6 +477,8 @@ public Hedera(
() -> daggerApp.workingStateAccessor().getState(),
() -> daggerApp.throttleServiceManager().activeThrottleDefinitionsOrThrow(),
ThrottleAccumulator::new));
hintsService = hintsServiceFactory.apply(appContext);
historyService = historyServiceFactory.apply(appContext);
contractServiceImpl = new ContractServiceImpl(appContext);
scheduleServiceImpl = new ScheduleServiceImpl();
blockStreamService = new BlockStreamService();
Expand All @@ -454,6 +489,8 @@ public Hedera(
contractServiceImpl,
fileServiceImpl,
new TssBaseServiceImpl(),
hintsService,
historyService,
new FreezeServiceImpl(),
scheduleServiceImpl,
new TokenServiceImpl(),
Expand Down Expand Up @@ -1066,6 +1103,7 @@ private void initializeDagger(@NonNull final State state, @NonNull final InitTri

final var networkInfo =
new StateNetworkInfo(platform.getSelfId().id(), state, platform.getRoster(), configProvider);
final var blockHashSigner = blockHashSignerFactory.apply(hintsService, historyService, configProvider);
// Fully qualified so as to not confuse javadoc
daggerApp = com.hedera.node.app.DaggerHederaInjectionComponent.builder()
.configProviderImpl(configProvider)
Expand All @@ -1090,8 +1128,9 @@ private void initializeDagger(@NonNull final State state, @NonNull final InitTri
.initialStateHash(initialStateHash)
.networkInfo(networkInfo)
.startupNetworks(startupNetworks)
// (FUTURE) Pass the HintsService and HistoryService to this factory
.blockHashSigner(blockHashSignerFactory.apply())
.hintsService(hintsService)
.historyService(historyService)
.blockHashSigner(blockHashSigner)
.build();
// Initialize infrastructure for fees, exchange rates, and throttles from the working state
daggerApp.initializer().accept(state);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import com.hedera.node.app.fees.FeeManager;
import com.hedera.node.app.grpc.GrpcInjectionModule;
import com.hedera.node.app.grpc.GrpcServerManager;
import com.hedera.node.app.hints.HintsService;
import com.hedera.node.app.history.HistoryService;
import com.hedera.node.app.info.CurrentPlatformStatus;
import com.hedera.node.app.info.InfoInjectionModule;
import com.hedera.node.app.metrics.MetricsInjectionModule;
Expand Down Expand Up @@ -190,6 +192,12 @@ interface Builder {
@BindsInstance
Builder blockHashSigner(BlockHashSigner blockHashSigner);

@BindsInstance
Builder hintsService(HintsService hintsService);

@BindsInstance
Builder historyService(HistoryService historyService);

@BindsInstance
Builder instantSource(InstantSource instantSource);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
import static java.util.Objects.requireNonNull;

import com.google.common.annotations.VisibleForTesting;
import com.hedera.node.app.hints.impl.HintsServiceImpl;
import com.hedera.node.app.history.impl.HistoryServiceImpl;
import com.hedera.node.app.info.DiskStartupNetworks;
import com.hedera.node.app.roster.RosterService;
import com.hedera.node.app.service.addressbook.AddressBookService;
Expand Down Expand Up @@ -410,6 +412,8 @@ public static Hedera newHedera(@NonNull final Metrics metrics) {
InstantSource.system(),
DiskStartupNetworks::new,
TssBlockHashSigner::new,
HintsServiceImpl::new,
HistoryServiceImpl::new,
metrics);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
* Copyright (C) 2024-2025 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.hedera.node.app.hints;

import com.hedera.node.app.hints.impl.HintsLibraryCodec;
import com.hedera.pbj.runtime.io.buffer.Bytes;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.util.Map;

/**
* The cryptographic operations required by the {@link HintsService}. The relationship between the hinTS algorithms
* and these operations are as follows:
* <ul>
* <li><b>Key generation</b> ({@code KGen}) - Implemented by {@link HintsLibrary#newBlsKeyPair()}.</li>
* <li><b>Hint generation</b> ({@code HintGen}) - Implemented by {@link HintsLibrary#computeHints(Bytes, int, int)}.</li>
* <li><b>Preprocessing</b> ({@code Preprocess}) - Implemented by using {@link HintsLibrary#preprocess(Map, Map, int)}
* to select the hinTS keys to use as input to {@link HintsLibrary#preprocess(Map, Map, int)}.</li>
* <li><b>Partial signatures</b> ({@code Sign}) - Implemented by {@link HintsLibrary#signBls(Bytes, Bytes)}.</li>
* <li><b>Verifying partial signatures</b> ({@code PartialVerify}) - Implemented by using
* {@link HintsLibrary#verifyBls(Bytes, Bytes, Bytes)} with public keys extracted from the
* aggregation key in the active hinTS scheme via {@link HintsLibraryCodec#extractPublicKey(Bytes, int)}.</li>
* <li><b>Signature aggregation</b> ({@code SignAggr}) - Implemented by {@link HintsLibrary#aggregateSignatures(Bytes, Bytes, Map)}
* with partial signatures verified as above with weights extracted from the aggregation key in the active hinTS
* scheme via {@link HintsLibraryCodec#extractWeight(Bytes, int)} and {@link HintsLibraryCodec#extractTotalWeight(Bytes)}.</li>
* <li><b>Verifying aggregate signatures</b> ({@code Verify}) - Implemented by
* {@link HintsLibrary#verifyAggregate(Bytes, Bytes, Bytes, long, long)}.</li>
* </ul>
*/
public interface HintsLibrary {
/**
* Generates a new BLS key pair.
* @return the key pair
*/
Bytes newBlsKeyPair();

/**
* Computes the hints for the given public key and number of parties.
*
* @param blsPrivateKey the private key
* @param partyId the party id
* @param n the number of parties
* @return the hints
*/
Bytes computeHints(@NonNull Bytes blsPrivateKey, int partyId, int n);

/**
* Validates the hinTS public key for the given number of parties.
*
* @param hintsKey the hinTS key
* @param partyId the party id
* @param n the number of parties
* @return true if the hints are valid; false otherwise
*/
boolean validateHintsKey(@NonNull Bytes hintsKey, int partyId, int n);

/**
* Runs the hinTS preprocessing algorithm on the given validated hint keys and party weights for the given number
* of parties. The output includes,
* <ol>
* <li>The linear size aggregation key to use in combining partial signatures on a message with a provably
* well-formed aggregate public key.</li>
* <li>The succinct verification key to use when verifying an aggregate signature.</li>
* </ol>
* Both maps given must have the same key set; in particular, a subset of {@code [0, n)}.
* @param hintsKeys the valid hinTS keys by party id
* @param weights the weights by party id
* @param n the number of parties
* @return the preprocessed keys
*/
Bytes preprocess(@NonNull Map<Integer, Bytes> hintsKeys, @NonNull Map<Integer, Long> weights, int n);

/**
* Signs a message with a BLS private key.
*
* @param message the message
* @param privateKey the private key
* @return the signature
*/
Bytes signBls(@NonNull Bytes message, @NonNull Bytes privateKey);

/**
* Checks that a signature on a message verifies under a BLS public key.
*
* @param signature the signature
* @param message the message
* @param publicKey the public key
* @return true if the signature is valid; false otherwise
*/
boolean verifyBls(@NonNull Bytes signature, @NonNull Bytes message, @NonNull Bytes publicKey);

/**
* Aggregates the signatures for party ids using hinTS aggregation and verification keys.
*
* @param aggregationKey the aggregation key
* @param verificationKey the verification key
* @param partialSignatures the partial signatures by party id
* @return the aggregated signature
*/
Bytes aggregateSignatures(
@NonNull Bytes aggregationKey,
@NonNull Bytes verificationKey,
@NonNull Map<Integer, Bytes> partialSignatures);

/**
* Checks an aggregate signature on a message verifies under a hinTS verification key, where
* this is only true if the aggregate signature has weight exceeding the specified threshold
* or total weight stipulated in the verification key.
*
* @param signature the aggregate signature
* @param message the message
* @param verificationKey the verification key
* @param thresholdNumerator the numerator of a fraction of total weight the signature must have
* @param thresholdDenominator the denominator of a fraction of total weight the signature must have
* @return true if the signature is valid; false otherwise
*/
boolean verifyAggregate(
@NonNull Bytes signature,
@NonNull Bytes message,
@NonNull Bytes verificationKey,
long thresholdNumerator,
long thresholdDenominator);
}
Loading

0 comments on commit 418e6d3

Please sign in to comment.