Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package com.hedera.node.app.hapi.utils;

import static com.hedera.node.app.hapi.utils.ByteStringUtils.unwrapUnsafelyIfPossible;
import static com.hedera.pbj.runtime.Codec.DEFAULT_MAX_DEPTH;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.*;
import static java.util.Objects.requireNonNull;

Expand Down Expand Up @@ -47,6 +48,8 @@
import java.util.List;

public class CommonPbjConverters {
public static final int MAX_PBJ_RECORD_SIZE = 33554432;

public static @NonNull com.hederahashgraph.api.proto.java.Query fromPbj(@NonNull Query query) {
requireNonNull(query);
try {
Expand Down Expand Up @@ -427,7 +430,8 @@ public static Timestamp toPbj(@NonNull com.hederahashgraph.api.proto.java.Timest
requireNonNull(txBody);
try {
final var bytes = txBody.toByteArray();
return TransactionBody.PROTOBUF.parse(BufferedData.wrap(bytes));
return TransactionBody.PROTOBUF.parse(
BufferedData.wrap(bytes), false, false, DEFAULT_MAX_DEPTH, MAX_PBJ_RECORD_SIZE);
} catch (ParseException e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: Apache-2.0
package com.hedera.node.app.hapi.utils.blocks;

import static com.hedera.node.app.hapi.utils.CommonPbjConverters.MAX_PBJ_RECORD_SIZE;
import static com.hedera.node.app.hapi.utils.exports.recordstreaming.RecordStreamingUtils.SIDECAR_ONLY_TOKEN;
import static com.hedera.pbj.runtime.Codec.DEFAULT_MAX_DEPTH;
import static java.util.Comparator.comparing;

import com.hedera.hapi.block.stream.Block;
Expand Down Expand Up @@ -159,10 +161,20 @@
try {
if (fileName.endsWith(".gz")) {
try (final GZIPInputStream in = new GZIPInputStream(Files.newInputStream(path))) {
return Block.PROTOBUF.parse(Bytes.wrap(in.readAllBytes()));
return Block.PROTOBUF.parse(
Bytes.wrap(in.readAllBytes()).toReadableSequentialData(),
false,
false,
DEFAULT_MAX_DEPTH,
MAX_PBJ_RECORD_SIZE);
}
} else {
return Block.PROTOBUF.parse(Bytes.wrap(Files.readAllBytes(path)));
return Block.PROTOBUF.parse(
Bytes.wrap(Files.readAllBytes(path)).toReadableSequentialData(),

Check warning on line 173 in hedera-node/hapi-utils/src/main/java/com/hedera/node/app/hapi/utils/blocks/BlockStreamAccess.java

View check run for this annotation

Codecov / codecov/patch

hedera-node/hapi-utils/src/main/java/com/hedera/node/app/hapi/utils/blocks/BlockStreamAccess.java#L172-L173

Added lines #L172 - L173 were not covered by tests
false,
false,
DEFAULT_MAX_DEPTH,
MAX_PBJ_RECORD_SIZE);
}
} catch (IOException | ParseException e) {
throw new RuntimeException("Failed reading block @ " + path, e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ public interface HistoryLibrary {
*/
Bytes EMPTY_PUBLIC_KEY = Bytes.wrap(new byte[32]);

/**
* A placeholder metadata for the genesis WRAPS proof.
*/
byte[] GENESIS_WRAPS_METADATA = new byte[1280];

/**
* An address book for use in the history library.
* @param weights the weights of the nodes in the address book
Expand Down Expand Up @@ -252,4 +257,9 @@ Proof constructIncrementalWrapsProof(
* @return true if the proof is valid; false otherwise
*/
boolean isValidWraps(byte[] compressedProof);

/**
* Returns whether the library is ready to be used.
*/
boolean wrapsProverReady();
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import com.hedera.node.app.spi.workflows.PreHandleContext;
import com.hedera.node.app.spi.workflows.PureChecksContext;
import com.hedera.node.app.spi.workflows.TransactionHandler;
import com.hedera.node.config.data.TssConfig;
import edu.umd.cs.findbugs.annotations.NonNull;
import javax.inject.Inject;
import javax.inject.Singleton;
Expand Down Expand Up @@ -63,8 +62,7 @@ public void handle(@NonNull final HandleContext context) throws HandleException
controllers.getAnyInProgress().ifPresent(controller -> {
final var publication =
new WrapsMessagePublication(nodeId, message, op.phase(), context.consensusNow());
if (controller.addWrapsMessagePublication(
publication, historyStore, context.configuration().getConfigData(TssConfig.class))) {
if (controller.addWrapsMessagePublication(publication, historyStore)) {
historyStore.addWrapsMessage(controller.constructionId(), publication);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
* Default implementation of the {@link HistoryLibrary}.
*/
public class HistoryLibraryImpl implements HistoryLibrary {
private static final byte[] DUMMY_HINTS_KEY = new byte[1280];
public static final SplittableRandom RANDOM = new SplittableRandom();
public static final WRAPSLibraryBridge WRAPS = WRAPSLibraryBridge.getInstance();

Expand Down Expand Up @@ -131,7 +130,7 @@ public Proof constructGenesisWrapsProof(
addressBook.publicKeys(),
addressBook.weights(),
null,
DUMMY_HINTS_KEY,
GENESIS_WRAPS_METADATA,
aggregatedSignature,
addressBook.signersMask(signers));
}
Expand Down Expand Up @@ -169,4 +168,9 @@ public boolean isValidWraps(@NonNull final byte[] compressedProof) {
requireNonNull(compressedProof);
return WRAPS.verifyCompressedProof(compressedProof);
}

@Override
public boolean wrapsProverReady() {
return WRAPSLibraryBridge.isProofSupported();
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// SPDX-License-Identifier: Apache-2.0
package com.hedera.node.app.history.impl;

import static java.util.Objects.requireNonNull;

import com.hedera.hapi.node.state.history.HistoryProof;
import com.hedera.hapi.node.state.history.HistoryProofConstruction;
import com.hedera.hapi.node.state.history.HistoryProofVote;
import com.hedera.hapi.node.state.history.ProofKey;
import com.hedera.node.app.history.HistoryLibrary;
import com.hedera.node.app.history.ReadableHistoryStore.WrapsMessagePublication;
Expand All @@ -31,7 +30,7 @@
* </ul>
* <p>
* Implementations are allowed to be completely asynchronous internally, and most implementations will likely converge
* to an outcome by submitting votes via {@link HistorySubmissions#submitProofVote(long, HistoryProof)}. However, a
* to an outcome by submitting votes via {@link HistorySubmissions#submitExplicitProofVote(long, HistoryProof)}. However, a
* simple implementation could also return a completed proof from a synchronous call to {@link #advance}.
* <p>
* Since implementations are expected to also be stateful, a {@link ProofController} will have a {@link HistoryProver}
Expand All @@ -44,6 +43,7 @@ public interface HistoryProver {
interface Factory {
HistoryProver create(
long selfId,
@NonNull TssConfig tssConfig,
@NonNull SchnorrKeyPair schnorrKeyPair,
@Nullable HistoryProof sourceProof,
@NonNull RosterTransitionWeights weights,
Expand Down Expand Up @@ -119,24 +119,28 @@ Outcome advance(
* @param constructionId the construction ID
* @param publication the WRAPS message publication
* @param writableHistoryStore the writable history store
* @param tssConfig the TSS configuration
* @return true if the publication was needed by this prover, false otherwise
*/
boolean addWrapsSigningMessage(
long constructionId,
@NonNull WrapsMessagePublication publication,
@NonNull WritableHistoryStore writableHistoryStore,
@NonNull TssConfig tssConfig);
@NonNull WritableHistoryStore writableHistoryStore);

/**
* Replays a WRAPS message publication that previously reached consensus.
* @param constructionId the construction ID
* @param publication the WRAPS message publication
*/
default void replayWrapsSigningMessage(
final long constructionId, @NonNull final WrapsMessagePublication publication) {
requireNonNull(publication);
}
void replayWrapsSigningMessage(long constructionId, @NonNull WrapsMessagePublication publication);

/**
* Observes a proof vote.
*
* @param nodeId the node ID
* @param vote the vote
* @param proofFinalized whether this vote finalized the proof
*/
void observeProofVote(long nodeId, @NonNull HistoryProofVote vote, boolean proofFinalized);

/**
* Returns a list of proof keys from the given map.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ public void reconcile(
construction,
historyStore,
activeHintsConstruction,
historyStore.getActiveConstruction());
historyStore.getActiveConstruction(),
tssConfig);
controller.advanceConstruction(now, metadata, historyStore, isActive, tssConfig);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,26 @@
* @param proof history proof to vote for
* @return a future that completes with the submission
*/
public CompletableFuture<Void> submitProofVote(final long constructionId, @NonNull final HistoryProof proof) {
public CompletableFuture<Void> submitExplicitProofVote(
final long constructionId, @NonNull final HistoryProof proof) {
requireNonNull(proof);
logger.info("Submitting proof vote for construction #{}", constructionId);
final var vote = HistoryProofVote.newBuilder().proof(proof).build();
return submitIfActive(
b -> b.historyProofVote(new HistoryProofVoteTransactionBody(constructionId, vote)), onFailure);
}

/**
* Submits a history proof vote to the network.
* @param constructionId the construction id to vote on
* @param congruentNodeId the node id that has already voted for the same proof
* @return a future that completes with the submission
*/
public CompletableFuture<Void> submitCongruentProofVote(final long constructionId, final long congruentNodeId) {
logger.info("Submitting proof vote congruent to node{} for construction #{}", congruentNodeId, constructionId);

Check warning on line 95 in hedera-node/hedera-app/src/main/java/com/hedera/node/app/history/impl/HistorySubmissions.java

View check run for this annotation

Codecov / codecov/patch

hedera-node/hedera-app/src/main/java/com/hedera/node/app/history/impl/HistorySubmissions.java#L95

Added line #L95 was not covered by tests
final var vote =
HistoryProofVote.newBuilder().congruentNodeId(congruentNodeId).build();
return submitIfActive(
b -> b.historyProofVote(new HistoryProofVoteTransactionBody(constructionId, vote)), onFailure);

Check warning on line 99 in hedera-node/hedera-app/src/main/java/com/hedera/node/app/history/impl/HistorySubmissions.java

View check run for this annotation

Codecov / codecov/patch

hedera-node/hedera-app/src/main/java/com/hedera/node/app/history/impl/HistorySubmissions.java#L97-L99

Added lines #L97 - L99 were not covered by tests
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,9 @@ public void addProofVote(
@Override
public boolean addWrapsMessagePublication(
@NonNull final WrapsMessagePublication publication,
@NonNull final WritableHistoryStore writableHistoryStore,
@NonNull final TssConfig tssConfig) {
@NonNull final WritableHistoryStore writableHistoryStore) {
requireNonNull(publication);
requireNonNull(writableHistoryStore);
requireNonNull(tssConfig);
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,9 @@ void advanceConstruction(
*
* @param publication the proof key publication
* @param writableHistoryStore the writable history store
* @param tssConfig the TSS configuration
*/
boolean addWrapsMessagePublication(
@NonNull WrapsMessagePublication publication,
@NonNull WritableHistoryStore writableHistoryStore,
@NonNull TssConfig tssConfig);
@NonNull WrapsMessagePublication publication, @NonNull WritableHistoryStore writableHistoryStore);

/**
* If this controller's construction is not already complete, considers updating its state with this history
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,17 @@ public ProofControllerImpl(
@NonNull final RosterTransitionWeights weights,
@NonNull final Executor executor,
@NonNull final HistorySubmissions submissions,
@NonNull final WrapsMpcStateMachine machine,
@NonNull final List<ProofKeyPublication> keyPublications,
@NonNull final List<WrapsMessagePublication> wrapsMessagePublications,
@NonNull final Map<Long, HistoryProofVote> votes,
@NonNull final HistoryService historyService,
@NonNull final HistoryLibrary historyLibrary,
@NonNull final HistoryProver.Factory proverFactory,
@Nullable final HistoryProof sourceProof) {
@Nullable final HistoryProof sourceProof,
@NonNull final TssConfig tssConfig) {
requireNonNull(machine);
requireNonNull(tssConfig);
this.selfId = selfId;
this.executor = requireNonNull(executor);
this.submissions = requireNonNull(submissions);
Expand All @@ -107,6 +111,7 @@ public ProofControllerImpl(
: sourceProof.targetProofKeys().stream().collect(toMap(ProofKey::nodeId, ProofKey::key));
this.prover = proverFactory.create(
selfId,
tssConfig,
schnorrKeyPair,
sourceProof,
weights,
Expand Down Expand Up @@ -149,7 +154,6 @@ public void advanceConstruction(
if (isActive) {
ensureProofKeyPublished();
}
log.info("Construction #{} still waiting for hinTS verification key", construction.constructionId());
return;
}
// Have the hinTS verification key, but not yet assembling the history or computing the WRAPS proof
Expand Down Expand Up @@ -192,16 +196,13 @@ public void addProofKeyPublication(@NonNull final ProofKeyPublication publicatio
@Override
public boolean addWrapsMessagePublication(
@NonNull final WrapsMessagePublication publication,
@NonNull final WritableHistoryStore writableHistoryStore,
@NonNull final TssConfig tssConfig) {
@NonNull final WritableHistoryStore writableHistoryStore) {
requireNonNull(publication);
requireNonNull(writableHistoryStore);
requireNonNull(tssConfig);
if (construction.hasTargetProof()) {
return false;
}
return requireNonNull(prover)
.addWrapsSigningMessage(constructionId(), publication, writableHistoryStore, tssConfig);
return requireNonNull(prover).addWrapsSigningMessage(constructionId(), publication, writableHistoryStore);
}

@Override
Expand Down Expand Up @@ -230,6 +231,8 @@ public void addProofVote(
.map(Map.Entry::getKey)
.findFirst();
maybeWinningProof.ifPresent(proof -> finishProof(historyStore, proof));
// Let our prover know about the vote to optimize its choice of explicit or congruent voting
requireNonNull(prover).observeProofVote(nodeId, vote, maybeWinningProof.isPresent());
}

@Override
Expand Down
Loading
Loading