Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Implement RekeyScenarioOp #16407

Merged
merged 22 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
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 Down
Loading
Loading