Skip to content

Commit

Permalink
feat: some integration and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ablax committed Nov 15, 2023
1 parent 00d07ab commit 00d07ab
Show file tree
Hide file tree
Showing 7 changed files with 433 additions and 25 deletions.
30 changes: 17 additions & 13 deletions src/main/java/com/limechain/storage/block/BlockState.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,27 @@ public class BlockState {
@Getter
private final byte[] genesisHash;
@Getter
private byte[] lastfinalized;
private byte[] lastFinalized;

/**
* Creates a new BlockState instance from genesis
* @param repository the kvrepository used to store the block state
* @param header the genesis block header
*/
public BlockState(KVRepository<String, Object> repository, BlockHeader header) {
this.blockTree = new BlockTree(header);
this.db = repository;
this.unfinalizedBlocks = new HashMap<>();
this.genesisHash = header.getHash();
this.lastfinalized = header.getHash();
this.lastFinalized = header.getHash();

setArrivalTime(header.getHash(), Instant.now());
setHeader(header);
db.save(helper.headerHashKey(header.getBlockNumber()), header.getHash());
setBlockBody(header.getHash(), new BlockBody(new ArrayList<>()));

//set the latest finalized head to the genesis header
setfinalizedHash(genesisHash, BigInteger.ZERO, BigInteger.ZERO);
setFinalizedHash(genesisHash, BigInteger.ZERO, BigInteger.ZERO);
}

/**
Expand Down Expand Up @@ -690,13 +695,12 @@ public Block deleteUnfinalizedBlock(final byte[] blockHash) {
}

/* Block finalization */

public void setfinalizedHash(byte[] hash, BigInteger round, BigInteger setId) {
public void setFinalizedHash(byte[] hash, BigInteger round, BigInteger setId) {
if (!hasHeader(hash)) {
throw new RuntimeException("Cannot finalise unknown block " + new Hash256(hash));
}

handlefinalizedBlock(hash);
handleFinalizedBlock(hash);
db.save(helper.finalizedHashKey(round, setId), hash);
setHighestRoundAndSetID(round, setId);

Expand All @@ -714,17 +718,17 @@ public void setfinalizedHash(byte[] hash, BigInteger round, BigInteger setId) {

// if nothing was previously finalized, set the first slot of the network to the
// slot number of block 1, which is now being set as final
if (Arrays.equals(this.lastfinalized, this.genesisHash) && Arrays.equals(hash, this.genesisHash)) {
if (Arrays.equals(this.lastFinalized, this.genesisHash) && Arrays.equals(hash, this.genesisHash)) {
// setFirstSlotOnFinalisation();
//TODO: Implement when BABE is implemented
}

if (this.lastfinalized != hash) {
if (this.lastFinalized != hash) {
//Delete from trie last finalized
//TODO: implement when the Trie is ready
}

this.lastfinalized = hash;
this.lastFinalized = hash;
}

public void setHighestRoundAndSetID(BigInteger round, BigInteger setId) {
Expand All @@ -749,12 +753,12 @@ public Pair<BigInteger, BigInteger> getHighestRoundAndSetID() {
return helper.bytesToRoundAndSetId(data);
}

public void handlefinalizedBlock(byte[] currentFinalizedHash) {
if (currentFinalizedHash == this.lastfinalized) {
public void handleFinalizedBlock(byte[] currentFinalizedHash) {
if (currentFinalizedHash == this.lastFinalized) {
return;
}

List<byte[]> subchain = rangeInMemory(lastfinalized, currentFinalizedHash);
List<byte[]> subchain = rangeInMemory(lastFinalized, currentFinalizedHash);

List<byte[]> subchainExcludingLatestFinalized = subchain.subList(1, subchain.size());

Expand Down Expand Up @@ -785,7 +789,7 @@ public void handlefinalizedBlock(byte[] currentFinalizedHash) {

// prune all the subchain hashes state tries from memory
// but keep the state trie from the current finalized block
if (!currentFinalizedHash.equals(subchainHash)) {
if (!Arrays.equals(currentFinalizedHash, subchainHash)) {
//TODO: tries.delete(tempBlock.getHeader().getStateRoot());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import io.emeraldpay.polkaj.scale.ScaleCodecWriter;
import io.emeraldpay.polkaj.scale.reader.UInt64Reader;
import io.emeraldpay.polkaj.scale.writer.UInt64Writer;
import lombok.NoArgsConstructor;
import org.javatuples.Pair;
import org.jetbrains.annotations.NotNull;

Expand All @@ -18,7 +17,6 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

@NoArgsConstructor
public final class BlockStateHelper {
private final UInt64Writer uint64Writer = new UInt64Writer();
private final UInt64Reader uint64Reader = new UInt64Reader();
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/com/limechain/storage/block/tree/BlockTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.limechain.storage.block.exception.LowerThanRootException;
import com.limechain.storage.block.map.HashToRuntime;
import io.emeraldpay.polkaj.types.Hash256;
import lombok.Getter;

import java.time.Instant;
import java.util.ArrayList;
Expand All @@ -21,7 +22,9 @@
public class BlockTree {

private final HashToRuntime runtimes;
@Getter
private Node root;
@Getter
private LeafMap leaves;

/**
Expand Down Expand Up @@ -159,7 +162,7 @@ public List<byte[]> rangeInMemory(byte[] startHash, byte[] endHash) {
return accumulateHashesInDescendingOrder(endNode, startNode);
}

private List<byte[]> accumulateHashesInDescendingOrder(Node endNode, Node startNode) {
public List<byte[]> accumulateHashesInDescendingOrder(Node endNode, Node startNode) {
if (startNode.getNumber() > endNode.getNumber()) {
throw new RuntimeException("Start is greater than end");
}
Expand Down Expand Up @@ -187,7 +190,7 @@ private List<byte[]> accumulateHashesInDescendingOrder(Node endNode, Node startN
* @param hash Hash of the node to find
* @return Node with the given hash
*/
private Node getNode(byte[] hash) {
public Node getNode(byte[] hash) {
if (Arrays.equals(root.getHash(), hash)) {
return root;
}
Expand Down Expand Up @@ -342,7 +345,7 @@ public byte[] lowestCommonAncestor(byte[] a, byte[] b) {
* @param nodeB Node of block b to check
* @return the hash of the lowest common ancestor
*/
private byte[] lowestCommonAncestor(Node nodeA, Node nodeB) {
public byte[] lowestCommonAncestor(Node nodeA, Node nodeB) {
Node higherNode = nodeB;
Node lowerNode = nodeA;
if (nodeA.getNumber() > nodeB.getNumber()) {
Expand Down
6 changes: 1 addition & 5 deletions src/main/java/com/limechain/storage/block/tree/LeafMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,7 @@ public void store(byte[] key, Node value) {
* @throws RuntimeException if the leaf is not found
*/
public Node load(byte[] key) {
Node node = syncMap.get(key);
if (node == null) {
throw new RuntimeException("Key not found: " + key);
}
return node;
return syncMap.get(key);
}

/**
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/com/limechain/storage/block/tree/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
Expand All @@ -22,6 +23,13 @@ public class Node {
private Instant arrivalTime; // Time of arrival of the block
private boolean isPrimary; // whether the block was authored in a primary slot or not

public Node(byte[] hash, Node parent, long number) {
this.hash = hash;
this.parent = parent;
this.number = number;
arrivalTime = Instant.now();
}

/**
* Adds a child to the node
* @param node child to be added node
Expand All @@ -44,7 +52,7 @@ public String toString() {
* @return node with the given hash
*/
public Node getNode(final byte[] hash) {
if (this.hash.equals(hash)) {
if (Arrays.equals(this.hash, hash)) {
return this;
}
for (Node child : this.children) {
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/com/limechain/sync/warpsync/SyncedState.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
import com.limechain.network.protocol.warp.dto.Justification;
import com.limechain.network.protocol.warp.scale.BlockHeaderReader;
import com.limechain.network.protocol.warp.scale.JustificationReader;
import com.limechain.network.protocol.warp.dto.Block;
import com.limechain.rpc.server.AppBean;
import com.limechain.runtime.Runtime;
import com.limechain.runtime.RuntimeBuilder;
import com.limechain.storage.DBConstants;
import com.limechain.storage.KVRepository;
import com.limechain.storage.block.BlockState;
import com.limechain.sync.JustificationVerifier;
import com.limechain.sync.warpsync.dto.AuthoritySetChange;
import com.limechain.sync.warpsync.dto.GrandpaDigestMessageType;
Expand Down Expand Up @@ -86,6 +88,7 @@ public static SyncedState getInstance() {
private KVRepository<String, Object> repository;
private Network network;
private RuntimeBuilder runtimeBuilder = new RuntimeBuilder();
private BlockState blockState;

private final PriorityQueue<Pair<BigInteger, Authority[]>> scheduledAuthorityChanges =
new PriorityQueue<>(Comparator.comparing(Pair::getValue0));
Expand Down Expand Up @@ -186,8 +189,14 @@ private void updateState(CommitMessage commitMessage) {
if (commitMessage.getVote().getBlockNumber().compareTo(lastFinalizedBlockNumber) < 1) {
return;
}
final Hash256 blockHash = commitMessage.getVote().getBlockHash();
Block block = blockState.deleteUnfinalizedBlock(blockHash.getBytes());
if (block != null) {
blockState.setHeader(block.getHeader());
}

latestRound = commitMessage.getRoundNumber();
lastFinalizedBlockHash = commitMessage.getVote().getBlockHash();
lastFinalizedBlockHash = blockHash;
lastFinalizedBlockNumber = commitMessage.getVote().getBlockNumber();
log.log(Level.INFO, "Reached block #" + lastFinalizedBlockNumber);
if (warpSyncFinished && scheduledRuntimeUpdateBlocks.contains(lastFinalizedBlockNumber)) {
Expand Down Expand Up @@ -430,4 +439,5 @@ public boolean loadState() {
}
return false;
}

}
Loading

0 comments on commit 00d07ab

Please sign in to comment.