Skip to content

Commit

Permalink
chore: Implement RekeyScenarioOp (#16407)
Browse files Browse the repository at this point in the history
Signed-off-by: Neeharika-Sompalli <neeharika.sompalli@swirldslabs.com>
Signed-off-by: Michael Tinker <michael.tinker@swirldslabs.com>
Co-authored-by: Neeharika-Sompalli <neeharika.sompalli@swirldslabs.com>
  • Loading branch information
tinker-michaelj and Neeharika-Sompalli authored Nov 5, 2024
1 parent 828edeb commit 774f08a
Show file tree
Hide file tree
Showing 49 changed files with 1,423 additions and 697 deletions.
1 change: 1 addition & 0 deletions hapi/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
exports com.hedera.hapi.block.protoc;
exports com.hedera.hapi.block.stream.protoc;
exports com.hedera.hapi.block;
exports com.hedera.hapi.services.auxiliary.tss.legacy;

requires transitive com.google.common;
requires transitive com.google.protobuf;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public ReadableNodeStoreImpl(@NonNull final ReadableStates states) {
}

@Override
public Roster newRosterFromNodes() {
public Roster snapshotOfFutureRoster() {
return constructFromNodesState(nodesState());
}

Expand Down Expand Up @@ -103,7 +103,6 @@ private Roster constructFromNodesState(@NonNull final ReadableKVState<EntityNumb
rosterEntries.add(entry);
}
}

rosterEntries.sort(Comparator.comparingLong(RosterEntry::nodeId));
return Roster.newBuilder().rosterEntries(rosterEntries).build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ void keysWorks() {

@Test
@DisplayName("Constructing a new roster includes all of the latest nodes defined in state")
void newRosterFromNodesIncludesAllUndeletedDefinitions() {
void snapshotOfFutureRosterIncludesAllUndeletedDefinitions() {
final ReadableKVState<EntityNumber, Node> nodesState = emptyReadableNodeStateBuilder()
.value(EntityNumber.newBuilder().number(1).build(), NODE_1)
.value(EntityNumber.newBuilder().number(2).build(), NODE_2)
Expand All @@ -126,7 +126,7 @@ void newRosterFromNodesIncludesAllUndeletedDefinitions() {
given(readableStates.<EntityNumber, Node>get(anyString())).willReturn(nodesState);

subject = new ReadableNodeStoreImpl(readableStates);
final var result = subject.newRosterFromNodes();
final var result = subject.snapshotOfFutureRoster();
org.assertj.core.api.Assertions.assertThat(result.rosterEntries())
.containsExactlyInAnyOrder(ROSTER_NODE_1, ROSTER_NODE_2, ROSTER_NODE_3);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public interface ReadableNodeStore {
*
* @return a new roster, representing the most current node configurations available
*/
Roster newRosterFromNodes();
Roster snapshotOfFutureRoster();

/**
* Returns the node needed. If the node doesn't exist returns failureReason. If the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.hedera.node.app.info;

import static com.hedera.node.app.service.token.impl.handlers.BaseCryptoHandler.asAccount;
import static java.util.Objects.requireNonNull;

import com.hedera.hapi.node.state.roster.Roster;
import com.hedera.hapi.node.state.roster.RosterEntry;
Expand All @@ -29,28 +30,25 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Singleton;

/**
* Provides information about the network, including the ledger ID. This is constructed from the
* roster provided.
* Provides information about the network based on the given roster and ledger ID.
*/
@Singleton
public class GenesisNetworkInfo implements NetworkInfo {
private final Map<Long, NodeInfo> nodeInfos;
private final Bytes ledgerId;
private final Roster genesisRoster;
private final Map<Long, NodeInfo> nodeInfos;

/**
* Constructs a new {@link GenesisNetworkInfo} instance.
*
* @param genesisRoster The genesis roster
* @param ledgerId The ledger ID
*/
public GenesisNetworkInfo(final Roster genesisRoster, final Bytes ledgerId) {
public GenesisNetworkInfo(@NonNull final Roster genesisRoster, @NonNull final Bytes ledgerId) {
this.ledgerId = requireNonNull(ledgerId);
this.genesisRoster = requireNonNull(genesisRoster);
this.nodeInfos = buildNodeInfoMap(genesisRoster);
this.ledgerId = ledgerId;
this.genesisRoster = genesisRoster;
}

/**
Expand Down Expand Up @@ -107,23 +105,6 @@ public Roster roster() {
return genesisRoster;
}

/**
* Builds a node info from a roster entry from the given roster.
* Since this is only used in the genesis case, the account ID is generated from the node ID
* by adding 3 to it, as a default case.
*
* @param entry The roster entry
* @return The node info
*/
private NodeInfo fromRosterEntry(RosterEntry entry) {
return new NodeInfoImpl(
entry.nodeId(),
asAccount(entry.nodeId() + 3),
entry.weight(),
entry.gossipEndpoint(),
entry.gossipCaCertificate());
}

/**
* Builds a map of node information from the given roster. The map is keyed by node ID.
* The node information is retrieved from the roster entry.
Expand All @@ -132,12 +113,29 @@ private NodeInfo fromRosterEntry(RosterEntry entry) {
* @param roster The roster to retrieve the node information from
* @return A map of node information
*/
private Map<Long, NodeInfo> buildNodeInfoMap(final Roster roster) {
private Map<Long, NodeInfo> buildNodeInfoMap(@NonNull final Roster roster) {
final var nodeInfos = new LinkedHashMap<Long, NodeInfo>();
final var rosterEntries = roster.rosterEntries();
for (final var rosterEntry : rosterEntries) {
nodeInfos.put(rosterEntry.nodeId(), fromRosterEntry(rosterEntry));
}
return nodeInfos;
}

/**
* Builds a node info from a roster entry from the given roster.
* Since this is only used in the genesis case, the account ID is generated from the node ID
* by adding 3 to it, as a default case.
*
* @param entry The roster entry
* @return The node info
*/
private NodeInfo fromRosterEntry(@NonNull final RosterEntry entry) {
return new NodeInfoImpl(
entry.nodeId(),
asAccount(entry.nodeId() + 3),
entry.weight(),
entry.gossipEndpoint(),
entry.gossipCaCertificate());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@
*/
@Singleton
public class StateNetworkInfo implements NetworkInfo {
private final Bytes ledgerId;
private final Map<Long, NodeInfo> nodeInfos;
private final long selfId;
private final ConfigProvider configProvider;
private final Bytes ledgerId;
private Roster activeRoster;
private final ConfigProvider configProvider;
private final Map<Long, NodeInfo> nodeInfos;

/**
* Constructs a new network information provider from the given state, roster, selfID, and configuration provider.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.swirlds.metrics.api.Metrics;
import dagger.BindsInstance;
import dagger.Component;
import java.time.InstantSource;
import java.util.concurrent.Executor;
import javax.inject.Singleton;

Expand All @@ -34,6 +35,7 @@ public interface TssBaseServiceComponent {
interface Factory {
TssBaseServiceComponent create(
@BindsInstance TssLibrary tssLibrary,
@BindsInstance InstantSource instantSource,
@BindsInstance AppContext.Gossip gossip,
@BindsInstance Executor submissionExecutor,
@BindsInstance @TssLibraryExecutor Executor libraryExecutor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,13 @@ public TssBaseServiceImpl(
this.signingExecutor = requireNonNull(signingExecutor);
this.tssLibraryExecutor = requireNonNull(tssLibraryExecutor);
final var component = DaggerTssBaseServiceComponent.factory()
.create(tssLibrary, appContext.gossip(), submissionExecutor, tssLibraryExecutor, metrics);
.create(
tssLibrary,
appContext.instantSource(),
appContext.gossip(),
submissionExecutor,
tssLibraryExecutor,
metrics);
this.tssMetrics = component.tssMetrics();
this.tssHandlers = new TssHandlers(component.tssMessageHandler(), component.tssVoteHandler());
this.tssSubmissions = component.tssSubmissions();
Expand Down Expand Up @@ -157,15 +163,15 @@ public void setCandidateRoster(@NonNull final Roster candidateRoster, @NonNull f
context.configuration().getConfigData(TssConfig.class).maxSharesPerNode();
final var selfId = (int) context.networkInfo().selfNodeInfo().nodeId();

final var activeRoster =
storeFactory.readableStore(ReadableRosterStore.class).getActiveRoster();
final var activeRosterHash = RosterUtils.hash(activeRoster).getBytes();
final var activeRoster = requireNonNull(
storeFactory.readableStore(ReadableRosterStore.class).getActiveRoster());

final var activeDirectory = computeParticipantDirectory(activeRoster, maxSharesPerNode, selfId);
final var candidateDirectory = computeParticipantDirectory(candidateRoster, maxSharesPerNode, selfId);
final var candidateRosterHash = RosterUtils.hash(candidateRoster).getBytes();

final var activeRosterHash = RosterUtils.hash(activeRoster).getBytes();
final var tssPrivateShares = getTssPrivateShares(activeDirectory, tssStore, activeRosterHash);
final var candidateRosterHash = RosterUtils.hash(candidateRoster).getBytes();
// FUTURE - instead of an arbitrary counter here, use the share index from the private share
final var shareIndex = new AtomicInteger(0);
for (final var tssPrivateShare : tssPrivateShares) {
Expand All @@ -188,6 +194,9 @@ public void setCandidateRoster(@NonNull final Roster candidateRoster, @NonNull f
}
}

// FUTURE - add a singleton PrivateSharesAccessor to the TSS component that can be used to
// access a cached copy of the private shares; this will also be useful for BaseServiceImpl
// to access the private shares for signing block hashes
@NonNull
private List<TssPrivateShare> getTssPrivateShares(
@NonNull final TssParticipantDirectory activeRosterParticipantDirectory,
Expand Down
Loading

0 comments on commit 774f08a

Please sign in to comment.