diff --git a/src/main/java/com/limechain/babe/Authorship.java b/src/main/java/com/limechain/babe/Authorship.java index a85faa253..6fe4bc4d3 100644 --- a/src/main/java/com/limechain/babe/Authorship.java +++ b/src/main/java/com/limechain/babe/Authorship.java @@ -241,7 +241,9 @@ 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 843c46304..51404fc88 100644 --- a/src/main/java/com/limechain/babe/BabeService.java +++ b/src/main/java/com/limechain/babe/BabeService.java @@ -161,8 +161,11 @@ private HeaderDigest[] produceDigests(BlockHeader header, BabePreDigest digest) Authority auth = stateManager.getEpochState().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/grandpa/state/GrandpaSetState.java b/src/main/java/com/limechain/grandpa/state/GrandpaSetState.java index 84600eda0..7ae335a0f 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::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 f937ceb98..f8fb9efd0 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 clearAuthorityStatus() { + isActiveAuthority = false; + grandpaKeyPair = null; + } + @Override public void initialize() { initialized = true; diff --git a/src/main/java/com/limechain/storage/crypto/KeyStore.java b/src/main/java/com/limechain/storage/crypto/KeyStore.java index fd2df3bb0..6a04067e7 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 (publicKey, privateKey) */ - 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<>(publicKey, privateKey)); } return Optional.empty(); } + public Schnorrkel.KeyPair convertToSchnorrKeypair(Pair pair) { + Schnorrkel.PublicKey pubKey = new Schnorrkel.PublicKey(pair.getValue0()); + return new Schnorrkel.KeyPair(pubKey, pair.getValue1()); + } + private byte[] removeKeyTypeFromKey(byte[] key) { return Arrays.copyOfRange(key, KeyType.KEY_TYPE_LEN, key.length); } 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); } }