From d469002a84079bf6ece2923b907d9873a9da6f85 Mon Sep 17 00:00:00 2001 From: Hristiyan Mitov <67628947+hMitov@users.noreply.github.com> Date: Thu, 6 Mar 2025 16:28:04 +0200 Subject: [PATCH] feat: Implemented fetching and storing of disabled authority for set. (#813) # Description Implemented fetching and storing of disabled authority for set. Fixes #774 --------- Co-authored-by: Hristiyan Mitov --- .../com/limechain/beefy/BeefyService.java | 30 ++++++++++++++ .../com/limechain/beefy/state/BeefyState.java | 39 +++++++++++++------ .../com/limechain/storage/DBConstants.java | 1 + .../java/com/limechain/storage/StateUtil.java | 4 ++ 4 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/limechain/beefy/BeefyService.java b/src/main/java/com/limechain/beefy/BeefyService.java index 50589232d..144f7d6b2 100644 --- a/src/main/java/com/limechain/beefy/BeefyService.java +++ b/src/main/java/com/limechain/beefy/BeefyService.java @@ -3,6 +3,7 @@ import com.limechain.beefy.dto.BeefyPayloadId; import com.limechain.beefy.dto.Commitment; import com.limechain.beefy.dto.PayloadElement; +import com.limechain.beefy.dto.ValidatorSet; import com.limechain.exception.storage.BlockStorageGenericException; import com.limechain.network.protocol.beefy.messages.consensus.BeefyConsensusMessage; import com.limechain.network.protocol.warp.DigestHelper; @@ -15,6 +16,7 @@ import java.math.BigInteger; import java.util.Collections; +import java.util.Objects; import java.util.Optional; @Log @@ -22,8 +24,36 @@ @RequiredArgsConstructor public class BeefyService { + private static final BigInteger THRESHOLD_DENOMINATOR = BigInteger.valueOf(3); + private final StateManager stateManager; + /** + * The threshold is determined as the numOfValidators - (numOfValidators - 1) / 3 + * + * @return minimum required validators for finality. + */ + private BigInteger getThreshold() { + ValidatorSet validatorSet = stateManager.getBeefyState().getValidatorSet(); + + if (Objects.isNull(validatorSet)) { + log.warning("getThreshold: No validatorSet in BeefyState."); + return BigInteger.ZERO; + } + + var validatorSize = validatorSet.getValidators().size(); + + if (validatorSize == 0) { + log.warning("getThreshold: Validator set is empty."); + return BigInteger.ZERO; + } + + var numOfValidators = BigInteger.valueOf(validatorSize); + var faulty = (numOfValidators.subtract(BigInteger.ONE)).divide(THRESHOLD_DENOMINATOR); + + return numOfValidators.subtract(faulty); + } + private Commitment getCommitment(BigInteger blockNumber, BigInteger setId) { BlockState blockState = stateManager.getBlockState(); BlockHeader blockHeader = null; diff --git a/src/main/java/com/limechain/beefy/state/BeefyState.java b/src/main/java/com/limechain/beefy/state/BeefyState.java index 41bd4ee16..9a636bfd8 100644 --- a/src/main/java/com/limechain/beefy/state/BeefyState.java +++ b/src/main/java/com/limechain/beefy/state/BeefyState.java @@ -4,6 +4,7 @@ import com.limechain.beefy.dto.SignedCommitment; import com.limechain.beefy.dto.ValidatorSet; import com.limechain.beefy.dto.VoteMessage; +import com.limechain.network.protocol.beefy.messages.consensus.BeefyConsensusMessage; import com.limechain.runtime.Runtime; import com.limechain.state.AbstractState; import com.limechain.storage.DBConstants; @@ -133,19 +134,17 @@ private Pair detectValidatorSetChange(BigInteger maxBl } /** - * The threshold is determined as the numOfValidators - (numOfValidators - 1) / 3 - * - * @return minimum required validators for finality. + * It checks for mandatory blocks by detecting set changes in all blocks + * between the last BEEFY finalized and GRANDPA finalized blocks. */ - public BigInteger getThreshold() { - var validatorSize = validatorSet.getValidators().size(); - if (validatorSize == 0) { - return BigInteger.ZERO; - } - var numOfValidators = BigInteger.valueOf(validatorSize); - var faulty = (numOfValidators.subtract(BigInteger.ONE)).divide(THRESHOLD_DENOMINATOR); + private void handleBeefyAuthorityConsensusMessage(BeefyConsensusMessage consensusMessage, BigInteger currentBlockNumber) { + switch (consensusMessage.getFormat()) { + case BEEFY_CHANGED_AUTHORITIES -> { + //Todo implement handle BEEFY_CHANGED_AUTHORITIES logic. - return numOfValidators.subtract(faulty); + } + case BEEFY_ON_DISABLED -> disabledAuthority = consensusMessage.getDisabledAuthority(); + } } public void vote() { @@ -228,6 +227,24 @@ private void persistBeefyValidators() { ); } + private BigInteger fetchDisabledAuthority(BigInteger setId) { + return repository.find( + StateUtil.generateBeefyDisabledAuthorityKey( + DBConstants.BEEFY_DISABLED_AUTHORITY, setId + ), + BigInteger.ZERO + ); + } + + private void persistDisabledAuthority() { + repository.save( + StateUtil.generateBeefyDisabledAuthorityKey( + DBConstants.BEEFY_DISABLED_AUTHORITY, validatorSet.getSetId() + ), + disabledAuthority + ); + } + private BigInteger fetchBeefyFinalized() { return repository.find(DBConstants.BEEFY_FINALIZED, BigInteger.ZERO); } diff --git a/src/main/java/com/limechain/storage/DBConstants.java b/src/main/java/com/limechain/storage/DBConstants.java index f1a278bda..8d712ba9d 100644 --- a/src/main/java/com/limechain/storage/DBConstants.java +++ b/src/main/java/com/limechain/storage/DBConstants.java @@ -44,6 +44,7 @@ public class DBConstants { //BeefyState keys public static final String BEEFY_AUTHORITY_SET = "gs::beefyAuthoritySet"; public static final String BEEFY_SET_ID = "gs::beefySetId"; + public static final String BEEFY_DISABLED_AUTHORITY = "bs:beefyDisabledAuthority"; public static final String BEEFY_FINALIZED = "bs:beefyFinalized"; public static final String BEEFY_ROUND = "bs:beefyRound"; public static final String BEEFY_JUSTIFICATION = "bs:justification"; diff --git a/src/main/java/com/limechain/storage/StateUtil.java b/src/main/java/com/limechain/storage/StateUtil.java index aaf4e2356..5ec20e88f 100644 --- a/src/main/java/com/limechain/storage/StateUtil.java +++ b/src/main/java/com/limechain/storage/StateUtil.java @@ -40,4 +40,8 @@ public String generatePreCommitsKey(String preCommitsKey, BigInteger roundNumber public String generateBeefyJustificationKey(String justificationKey, BigInteger blockNumber) { return prepareKey(justificationKey, blockNumber.toString()); } + + public String generateBeefyDisabledAuthorityKey(String disabledAuthorityKey, BigInteger setId) { + return prepareKey(disabledAuthorityKey, setId.toString()); + } }