From fa338e59a35d627717e1107a4ca7d8d1f0c065fb Mon Sep 17 00:00:00 2001 From: Hristiyan Mitov Date: Thu, 20 Feb 2025 13:42:05 +0200 Subject: [PATCH] feat: Added BeefyConsensusMessage and BeefyConsensusMessageFormat, implemented scale reading. Introduced beefy consensus message processing in addBlockToTree() method (without implementation of the handler). --- .../consensus/BeefyConsensusMessage.java | 16 +++++++ .../BeefyConsensusMessageFormat.java | 23 ++++++++++ .../BeefyConsensusMessageReader.java | 45 +++++++++++++++++++ .../network/protocol/warp/DigestHelper.java | 11 +++++ .../limechain/storage/block/BlockHandler.java | 6 +++ 5 files changed, 101 insertions(+) create mode 100644 src/main/java/com/limechain/network/protocol/beefy/messages/consensus/BeefyConsensusMessage.java create mode 100644 src/main/java/com/limechain/network/protocol/beefy/messages/consensus/BeefyConsensusMessageFormat.java create mode 100644 src/main/java/com/limechain/network/protocol/beefy/messages/consensus/BeefyConsensusMessageReader.java diff --git a/src/main/java/com/limechain/network/protocol/beefy/messages/consensus/BeefyConsensusMessage.java b/src/main/java/com/limechain/network/protocol/beefy/messages/consensus/BeefyConsensusMessage.java new file mode 100644 index 000000000..51b2b8f89 --- /dev/null +++ b/src/main/java/com/limechain/network/protocol/beefy/messages/consensus/BeefyConsensusMessage.java @@ -0,0 +1,16 @@ +package com.limechain.network.protocol.beefy.messages.consensus; + +import lombok.Data; + +import java.math.BigInteger; +import java.util.List; + +@Data +public class BeefyConsensusMessage { + private BeefyConsensusMessageFormat format; + private List authorityPublicKeys; + private BigInteger authoritySetId; + private BigInteger disabledAuthority; + // The 32-byte Merkle Mountain Range (MMR) root payload hash. + private byte[] mmrRootHash; +} diff --git a/src/main/java/com/limechain/network/protocol/beefy/messages/consensus/BeefyConsensusMessageFormat.java b/src/main/java/com/limechain/network/protocol/beefy/messages/consensus/BeefyConsensusMessageFormat.java new file mode 100644 index 000000000..efcb2d239 --- /dev/null +++ b/src/main/java/com/limechain/network/protocol/beefy/messages/consensus/BeefyConsensusMessageFormat.java @@ -0,0 +1,23 @@ +package com.limechain.network.protocol.beefy.messages.consensus; + +import lombok.Getter; + +@Getter +public enum BeefyConsensusMessageFormat { + BEEFY_CHANGED_AUTHORITIES(1), BEEFY_ON_DISABLED(2), BEEFY_MMR_ROOT(3); + + private final int format; + + BeefyConsensusMessageFormat(int format) { + this.format = format; + } + + public static BeefyConsensusMessageFormat fromFormat(byte format) { + for (BeefyConsensusMessageFormat messageFormat : values()) { + if (messageFormat.getFormat() == format) { + return messageFormat; + } + } + throw new IllegalArgumentException("Unknown beefy consensus message format: " + format); + } +} diff --git a/src/main/java/com/limechain/network/protocol/beefy/messages/consensus/BeefyConsensusMessageReader.java b/src/main/java/com/limechain/network/protocol/beefy/messages/consensus/BeefyConsensusMessageReader.java new file mode 100644 index 000000000..e96604c92 --- /dev/null +++ b/src/main/java/com/limechain/network/protocol/beefy/messages/consensus/BeefyConsensusMessageReader.java @@ -0,0 +1,45 @@ +package com.limechain.network.protocol.beefy.messages.consensus; + +import io.emeraldpay.polkaj.scale.ScaleCodecReader; +import io.emeraldpay.polkaj.scale.ScaleReader; +import io.emeraldpay.polkaj.scale.reader.ListReader; +import io.emeraldpay.polkaj.scale.reader.UInt64Reader; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +import java.util.List; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class BeefyConsensusMessageReader implements ScaleReader { + + private static final BeefyConsensusMessageReader INSTANCE = new BeefyConsensusMessageReader(); + + public static BeefyConsensusMessageReader getInstance() { + return INSTANCE; + } + + @Override + public BeefyConsensusMessage read(ScaleCodecReader reader) { + + BeefyConsensusMessage beefyConsensusMessage = new BeefyConsensusMessage(); + BeefyConsensusMessageFormat format = BeefyConsensusMessageFormat.fromFormat(reader.readByte()); + beefyConsensusMessage.setFormat(format); + + switch (format) { + case BEEFY_CHANGED_AUTHORITIES -> { + List authorityPublicKeys = new ListReader<>( + rdr -> rdr.readByteArray(33)).read(reader); + beefyConsensusMessage.setAuthorityPublicKeys(authorityPublicKeys); + beefyConsensusMessage.setAuthoritySetId(new UInt64Reader().read(reader)); + } + case BEEFY_ON_DISABLED -> { + beefyConsensusMessage.setDisabledAuthority(new UInt64Reader().read(reader)); + } + case BEEFY_MMR_ROOT -> { + beefyConsensusMessage.setMmrRootHash(reader.readUint256()); + } + } + + return beefyConsensusMessage; + } +} diff --git a/src/main/java/com/limechain/network/protocol/warp/DigestHelper.java b/src/main/java/com/limechain/network/protocol/warp/DigestHelper.java index 37eb1b1f5..fc3507330 100644 --- a/src/main/java/com/limechain/network/protocol/warp/DigestHelper.java +++ b/src/main/java/com/limechain/network/protocol/warp/DigestHelper.java @@ -4,6 +4,8 @@ import com.limechain.babe.consensus.scale.BabeConsensusMessageReader; import com.limechain.babe.predigest.BabePreDigest; import com.limechain.babe.predigest.scale.PreDigestReader; +import com.limechain.network.protocol.beefy.messages.consensus.BeefyConsensusMessage; +import com.limechain.network.protocol.beefy.messages.consensus.BeefyConsensusMessageReader; import com.limechain.network.protocol.grandpa.messages.consensus.GrandpaConsensusMessage; import com.limechain.network.protocol.grandpa.messages.consensus.GrandpaConsensusMessageReader; import com.limechain.network.protocol.warp.dto.BlockHeader; @@ -43,6 +45,15 @@ public static Optional getGrandpaConsensusMessage(Heade .map(message -> ScaleUtils.Decode.decode(message, GrandpaConsensusMessageReader.getInstance())); } + public static Optional getBeefyConsensusMessage(HeaderDigest[] headerDigests) { + return Arrays.stream(headerDigests) + .filter(headerDigest -> DigestType.CONSENSUS_MESSAGE.equals(headerDigest.getType()) && + ConsensusEngine.BEEFY.equals(headerDigest.getId())) + .findFirst() + .map(HeaderDigest::getMessage) + .map(message -> ScaleUtils.Decode.decode(message, BeefyConsensusMessageReader.getInstance())); + } + public static Optional getBabePreRuntimeDigest(HeaderDigest[] headerDigests) { return Arrays.stream(headerDigests) .filter(headerDigest -> DigestType.PRE_RUNTIME.equals(headerDigest.getType()) && diff --git a/src/main/java/com/limechain/storage/block/BlockHandler.java b/src/main/java/com/limechain/storage/block/BlockHandler.java index f4a18dacb..c4537bc0d 100644 --- a/src/main/java/com/limechain/storage/block/BlockHandler.java +++ b/src/main/java/com/limechain/storage/block/BlockHandler.java @@ -169,6 +169,12 @@ public void addBlockToTree(Block block, Instant arrivalTime) { )); grandpaSetState.handleAuthoritySetChange(header.getBlockNumber()); + + asyncExecutor.executeAndForget(() -> DigestHelper.getBeefyConsensusMessage(header.getDigest()) + .ifPresent(cm -> { + } + //Todo: handleBeefyConsensusMessage + )); } }