From dcafafb3a4bc8e39abf820f14b17b2007376b030 Mon Sep 17 00:00:00 2001 From: Grigorov-Georgi Date: Fri, 24 Jan 2025 17:53:46 +0200 Subject: [PATCH 1/5] feat: initial setup and refactor of keyStore.getKey() method; --- .../java/com/limechain/babe/Authorship.java | 7 ++++++- .../java/com/limechain/babe/BabeService.java | 4 +++- .../com/limechain/client/AbstractNode.java | 2 +- .../com/limechain/client/NodeRoleManager.java | 20 +++++++++++++++++++ .../limechain/storage/crypto/KeyStore.java | 14 ++++++++----- 5 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/limechain/client/NodeRoleManager.java diff --git a/src/main/java/com/limechain/babe/Authorship.java b/src/main/java/com/limechain/babe/Authorship.java index a85faa253..84f3b0744 100644 --- a/src/main/java/com/limechain/babe/Authorship.java +++ b/src/main/java/com/limechain/babe/Authorship.java @@ -241,7 +241,12 @@ private static Map getOwnedKeyPairsFromAuthoritySet Map indexKeyPairMap = new LinkedMap<>(); authorities.forEach(a -> keyStore.getKeyPair(KeyType.BABE, a.getPublicKey()) - .ifPresent(keyPair -> indexKeyPairMap.put(authorities.indexOf(a), keyPair))); + .ifPresent(keyPair -> { + indexKeyPairMap.put( + authorities.indexOf(a), + keyStore.convertToSchnorrKeypair(keyPair)); + } + )); return indexKeyPairMap; } diff --git a/src/main/java/com/limechain/babe/BabeService.java b/src/main/java/com/limechain/babe/BabeService.java index 354331366..4f32053cf 100644 --- a/src/main/java/com/limechain/babe/BabeService.java +++ b/src/main/java/com/limechain/babe/BabeService.java @@ -20,7 +20,6 @@ import com.limechain.network.protocol.warp.dto.ConsensusEngine; import com.limechain.network.protocol.warp.dto.DigestType; import com.limechain.network.protocol.warp.dto.HeaderDigest; -import com.limechain.rpc.server.AppBean; import com.limechain.runtime.Runtime; import com.limechain.runtime.RuntimeBuilder; import com.limechain.storage.block.BlockHandler; @@ -161,8 +160,11 @@ private HeaderDigest[] produceDigests(BlockHeader header, BabePreDigest digest) Authority auth = epochState.getCurrentEpochData().getAuthorities() .get((int) digest.getAuthorityIndex()); + Schnorrkel.KeyPair keyPair = keyStore.getKeyPair(KeyType.BABE, auth.getPublicKey()) + .map(keyStore::convertToSchnorrKeypair) .orElseThrow(() -> new KeyStoreException("No KeyPair found for provided pub key.")); + newDigests[length + 2] = DigestHelper.buildSealHeaderDigest(header, keyPair); return newDigests; diff --git a/src/main/java/com/limechain/client/AbstractNode.java b/src/main/java/com/limechain/client/AbstractNode.java index f8c05c81b..8e246af2b 100644 --- a/src/main/java/com/limechain/client/AbstractNode.java +++ b/src/main/java/com/limechain/client/AbstractNode.java @@ -19,7 +19,7 @@ import java.util.logging.Level; @Log -public abstract class AbstractNode implements HostNode{ +public abstract class AbstractNode implements HostNode { /** * Starts the light client by instantiating all dependencies and services diff --git a/src/main/java/com/limechain/client/NodeRoleManager.java b/src/main/java/com/limechain/client/NodeRoleManager.java new file mode 100644 index 000000000..7d82c0ee5 --- /dev/null +++ b/src/main/java/com/limechain/client/NodeRoleManager.java @@ -0,0 +1,20 @@ +package com.limechain.client; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.javatuples.Pair; +import org.springframework.stereotype.Component; + +@Component +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class NodeRoleManager { + + private boolean isAuthority; + private Pair grandpaKeyPair; +} diff --git a/src/main/java/com/limechain/storage/crypto/KeyStore.java b/src/main/java/com/limechain/storage/crypto/KeyStore.java index fd2df3bb0..213b5cccb 100644 --- a/src/main/java/com/limechain/storage/crypto/KeyStore.java +++ b/src/main/java/com/limechain/storage/crypto/KeyStore.java @@ -3,6 +3,7 @@ import com.limechain.storage.KVRepository; import io.emeraldpay.polkaj.schnorrkel.Schnorrkel; import lombok.extern.java.Log; +import org.javatuples.Pair; import org.springframework.stereotype.Component; import java.util.Arrays; @@ -50,19 +51,22 @@ public List getPublicKeysByKeyType(KeyType keyType) { * * @param type the algorithm type that the key is used for. * @param publicKey the pubKey used as a key to retrieve a privKey from the store. - * @return the {@link io.emeraldpay.polkaj.schnorrkel.Schnorrkel.KeyPair}. + * @return Pair of (privateKey, publicKey) */ - public Optional getKeyPair(KeyType type, byte[] publicKey) { + public Optional> getKeyPair(KeyType type, byte[] publicKey) { var privateKey = get(type, publicKey); if (privateKey != null) { - Schnorrkel.PublicKey schnorrkelPubKey = new Schnorrkel.PublicKey(publicKey); - Schnorrkel.KeyPair keyPair = new Schnorrkel.KeyPair(schnorrkelPubKey, privateKey); - return Optional.of(keyPair); + return Optional.of(new Pair<>(privateKey, publicKey)); } return Optional.empty(); } + public Schnorrkel.KeyPair convertToSchnorrKeypair(Pair pair) { + Schnorrkel.PublicKey pubKey = new Schnorrkel.PublicKey(pair.getValue1()); + return new Schnorrkel.KeyPair(pubKey, pair.getValue0()); + } + private byte[] removeKeyTypeFromKey(byte[] key) { return Arrays.copyOfRange(key, KeyType.KEY_TYPE_LEN, key.length); } From b4c16e0f8fb94cf37c08ea706db1181251ec3766 Mon Sep 17 00:00:00 2001 From: Grigorov-Georgi Date: Mon, 27 Jan 2025 09:49:15 +0200 Subject: [PATCH 2/5] chore: rename field in NodeRoleManeger --- src/main/java/com/limechain/client/NodeRoleManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/limechain/client/NodeRoleManager.java b/src/main/java/com/limechain/client/NodeRoleManager.java index 7d82c0ee5..093b69ce7 100644 --- a/src/main/java/com/limechain/client/NodeRoleManager.java +++ b/src/main/java/com/limechain/client/NodeRoleManager.java @@ -15,6 +15,6 @@ @NoArgsConstructor(access = AccessLevel.PRIVATE) public class NodeRoleManager { - private boolean isAuthority; + private boolean isInAuthoritySet; private Pair grandpaKeyPair; } From 47023870806677e32f50b1e345b592454eeccf1a Mon Sep 17 00:00:00 2001 From: Grigorov-Georgi Date: Mon, 27 Jan 2025 13:54:06 +0200 Subject: [PATCH 3/5] feat: add authority status fields to abstractState --- .../com/limechain/client/NodeRoleManager.java | 20 ------------------- .../grandpa/state/GrandpaSetState.java | 15 +++++++++++--- .../com/limechain/state/AbstractState.java | 18 ++++++++++++++++- .../sync/warpsync/WarpSyncState.java | 3 ++- 4 files changed, 31 insertions(+), 25 deletions(-) delete mode 100644 src/main/java/com/limechain/client/NodeRoleManager.java diff --git a/src/main/java/com/limechain/client/NodeRoleManager.java b/src/main/java/com/limechain/client/NodeRoleManager.java deleted file mode 100644 index 093b69ce7..000000000 --- a/src/main/java/com/limechain/client/NodeRoleManager.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.limechain.client; - -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import org.javatuples.Pair; -import org.springframework.stereotype.Component; - -@Component -@Getter -@Setter -@AllArgsConstructor -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class NodeRoleManager { - - private boolean isInAuthoritySet; - private Pair grandpaKeyPair; -} diff --git a/src/main/java/com/limechain/grandpa/state/GrandpaSetState.java b/src/main/java/com/limechain/grandpa/state/GrandpaSetState.java index 84600eda0..1061e4336 100644 --- a/src/main/java/com/limechain/grandpa/state/GrandpaSetState.java +++ b/src/main/java/com/limechain/grandpa/state/GrandpaSetState.java @@ -27,6 +27,7 @@ import lombok.RequiredArgsConstructor; import lombok.Setter; import lombok.extern.java.Log; +import org.javatuples.Pair; import org.springframework.stereotype.Component; import java.math.BigInteger; @@ -34,6 +35,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.PriorityQueue; import java.util.logging.Level; @@ -176,6 +178,8 @@ public void startNewSet(List authorities) { roundCache.addRound(setId, grandpaRound); + updateAuthorityStatus(); + log.log(Level.INFO, "Successfully transitioned to authority set id: " + setId); } @@ -259,8 +263,13 @@ public void handleVoteMessage(VoteMessage voteMessage) { } } - public boolean participatesAsVoter() { - return authorities.stream() - .anyMatch(a -> keyStore.getKeyPair(KeyType.GRANDPA, a.getPublicKey()).isPresent()); + private void updateAuthorityStatus() { + Optional> keyPair = authorities.stream() + .map(a -> keyStore.getKeyPair(KeyType.GRANDPA, a.getPublicKey())) + .filter(Optional::isPresent) + .map(Optional::get) + .findFirst(); + + keyPair.ifPresentOrElse(AbstractState::setAuthorityStatus, AbstractState::unsetAuthorityStatus); } } \ No newline at end of file diff --git a/src/main/java/com/limechain/state/AbstractState.java b/src/main/java/com/limechain/state/AbstractState.java index f937ceb98..1886eefad 100644 --- a/src/main/java/com/limechain/state/AbstractState.java +++ b/src/main/java/com/limechain/state/AbstractState.java @@ -3,13 +3,19 @@ import com.limechain.ServiceState; import com.limechain.sync.SyncMode; import lombok.Getter; +import org.javatuples.Pair; public abstract class AbstractState implements ServiceState { + @Getter + protected boolean initialized; + @Getter private static SyncMode syncMode; @Getter - protected boolean initialized; + private static boolean isActiveAuthority = false; + @Getter + private static Pair grandpaKeyPair = null; public static void setSyncMode(SyncMode mode) { if (syncMode != null && syncMode.ordinal() > mode.ordinal()) { @@ -19,6 +25,16 @@ public static void setSyncMode(SyncMode mode) { syncMode = mode; } + public static void setAuthorityStatus(Pair keyPair) { + isActiveAuthority = true; + grandpaKeyPair = keyPair; + } + + public static void unsetAuthorityStatus() { + isActiveAuthority = false; + grandpaKeyPair = null; + } + @Override public void initialize() { initialized = true; diff --git a/src/main/java/com/limechain/sync/warpsync/WarpSyncState.java b/src/main/java/com/limechain/sync/warpsync/WarpSyncState.java index be171ac8e..568c8b0af 100644 --- a/src/main/java/com/limechain/sync/warpsync/WarpSyncState.java +++ b/src/main/java/com/limechain/sync/warpsync/WarpSyncState.java @@ -20,6 +20,7 @@ import com.limechain.network.protocol.warp.scale.reader.JustificationReader; import com.limechain.runtime.Runtime; import com.limechain.runtime.RuntimeBuilder; +import com.limechain.state.AbstractState; import com.limechain.state.StateManager; import com.limechain.storage.DBConstants; import com.limechain.storage.KVRepository; @@ -148,7 +149,7 @@ public synchronized void syncCommit(CommitMessage commitMessage, PeerId peerId) .getRound(commitMessage.getSetId(), commitMessage.getRoundNumber()) .addCommitMessageToArchive(commitMessage); - if (warpSyncFinished && !grandpaSetState.participatesAsVoter()) { + if (warpSyncFinished && !AbstractState.isActiveAuthority()) { updateState(commitMessage); } } From f3167371536e279094d46b1165d2c3945b03adc1 Mon Sep 17 00:00:00 2001 From: Grigorov-Georgi Date: Mon, 27 Jan 2025 14:01:16 +0200 Subject: [PATCH 4/5] chore: refactor --- src/main/java/com/limechain/babe/Authorship.java | 7 ++----- src/main/java/com/limechain/storage/crypto/KeyStore.java | 8 ++++---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/limechain/babe/Authorship.java b/src/main/java/com/limechain/babe/Authorship.java index 84f3b0744..6fe4bc4d3 100644 --- a/src/main/java/com/limechain/babe/Authorship.java +++ b/src/main/java/com/limechain/babe/Authorship.java @@ -242,11 +242,8 @@ private static Map getOwnedKeyPairsFromAuthoritySet authorities.forEach(a -> keyStore.getKeyPair(KeyType.BABE, a.getPublicKey()) .ifPresent(keyPair -> { - indexKeyPairMap.put( - authorities.indexOf(a), - keyStore.convertToSchnorrKeypair(keyPair)); - } - )); + indexKeyPairMap.put(authorities.indexOf(a), keyStore.convertToSchnorrKeypair(keyPair)); + })); return indexKeyPairMap; } diff --git a/src/main/java/com/limechain/storage/crypto/KeyStore.java b/src/main/java/com/limechain/storage/crypto/KeyStore.java index 213b5cccb..6a04067e7 100644 --- a/src/main/java/com/limechain/storage/crypto/KeyStore.java +++ b/src/main/java/com/limechain/storage/crypto/KeyStore.java @@ -51,20 +51,20 @@ public List getPublicKeysByKeyType(KeyType keyType) { * * @param type the algorithm type that the key is used for. * @param publicKey the pubKey used as a key to retrieve a privKey from the store. - * @return Pair of (privateKey, publicKey) + * @return Pair of (publicKey, privateKey) */ public Optional> getKeyPair(KeyType type, byte[] publicKey) { var privateKey = get(type, publicKey); if (privateKey != null) { - return Optional.of(new Pair<>(privateKey, publicKey)); + return Optional.of(new Pair<>(publicKey, privateKey)); } return Optional.empty(); } public Schnorrkel.KeyPair convertToSchnorrKeypair(Pair pair) { - Schnorrkel.PublicKey pubKey = new Schnorrkel.PublicKey(pair.getValue1()); - return new Schnorrkel.KeyPair(pubKey, pair.getValue0()); + Schnorrkel.PublicKey pubKey = new Schnorrkel.PublicKey(pair.getValue0()); + return new Schnorrkel.KeyPair(pubKey, pair.getValue1()); } private byte[] removeKeyTypeFromKey(byte[] key) { From 8e73a158e74aeaa5e708407882389693c3a4c2ae Mon Sep 17 00:00:00 2001 From: Grigorov-Georgi Date: Mon, 27 Jan 2025 15:39:23 +0200 Subject: [PATCH 5/5] chore: refactor --- src/main/java/com/limechain/grandpa/state/GrandpaSetState.java | 2 +- src/main/java/com/limechain/state/AbstractState.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/limechain/grandpa/state/GrandpaSetState.java b/src/main/java/com/limechain/grandpa/state/GrandpaSetState.java index 1061e4336..7ae335a0f 100644 --- a/src/main/java/com/limechain/grandpa/state/GrandpaSetState.java +++ b/src/main/java/com/limechain/grandpa/state/GrandpaSetState.java @@ -270,6 +270,6 @@ private void updateAuthorityStatus() { .map(Optional::get) .findFirst(); - keyPair.ifPresentOrElse(AbstractState::setAuthorityStatus, AbstractState::unsetAuthorityStatus); + keyPair.ifPresentOrElse(AbstractState::setAuthorityStatus, AbstractState::clearAuthorityStatus); } } \ No newline at end of file diff --git a/src/main/java/com/limechain/state/AbstractState.java b/src/main/java/com/limechain/state/AbstractState.java index 1886eefad..f8fb9efd0 100644 --- a/src/main/java/com/limechain/state/AbstractState.java +++ b/src/main/java/com/limechain/state/AbstractState.java @@ -30,7 +30,7 @@ public static void setAuthorityStatus(Pair keyPair) { grandpaKeyPair = keyPair; } - public static void unsetAuthorityStatus() { + public static void clearAuthorityStatus() { isActiveAuthority = false; grandpaKeyPair = null; }