Skip to content

Commit

Permalink
feat: improve syncing startegies (LimeChain#447)
Browse files Browse the repository at this point in the history
# Description

- What does this PR do?
'Get rid' of the old SyncedState class.
Create a new class (SyncState) that holds only relevant information
about the current sync state and keeps it in the database. Automatically
switch to full sync after warp sync. (Currently starts from the first
block, but after trie version 1 implementation will update it to start
from the latest warp sync block).

Fixes LimeChain#335

## Checklist:
- [x] I have read the [contributing guidelines](../CONTRIBUTING.md).
- [x] My PR title matches the [Conventional Commits
spec](https://www.conventionalcommits.org/).
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [ ] I have added tests to cover my changes.
- [x] All new and existing tests passed.
  • Loading branch information
ablax authored Jun 6, 2024
1 parent 59fdbc9 commit 9ba3005
Show file tree
Hide file tree
Showing 58 changed files with 724 additions and 590 deletions.
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ including:*
Fixes #<issue number, if applicable>

## Checklist:
- [ ] I have read the [contributing guidelines](../CONTRIBUTING.md).
- [ ] I have read the [contributing guidelines](https://github.com/LimeChain/Fruzhin/blob/dev/CONTRIBUTING.md).
- [ ] My PR title matches the [Conventional Commits spec](https://www.conventionalcommits.org/).
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
Expand Down
1 change: 1 addition & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ updates:
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
8 changes: 1 addition & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,7 @@ cd Fruzhin

### Java Version

Fruzhin only works
with [Java 21 Coretto](https://docs.aws.amazon.com/corretto/latest/corretto-21-ug/downloads-list.html). Using any other
version may cause "cannot calculate secret" errors when running the node:

```
org.bouncycastle.tls.crypto.TlsCryptoException: cannot calculate secret
```
Fruzhin only works with Java 21.

If you have multiple java version installed please make sure you're using 21:

Expand Down
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
plugins {
id("java")
id("io.freefair.lombok") version "8.6"
id("org.springframework.boot") version "3.2.5"
id("org.springframework.boot") version "3.2.6"
id("io.spring.dependency-management") version "1.1.5"
id("application")
}
Expand Down Expand Up @@ -63,7 +63,7 @@ dependencies {

// Nabu
// implementation("com.github.LimeChain:nabu:master-SNAPSHOT") // Uncomment for "most-recent on the master branch"
implementation("com.github.LimeChain:nabu:32f159f413")
implementation("com.github.LimeChain:nabu:0.7.8")

//JSON-RPC
implementation("com.github.LimeChain:jsonrpc4j:1.7.0")
Expand Down
2 changes: 1 addition & 1 deletion docs/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ git clone https://github.com/LimeChain/Fruzhin.git
cd Fruzhin
```

#### Install java 21 corretto (if you don't already have it)
#### Install java 21 (if you don't already have it)
Setup guide:
- [Windows](https://docs.aws.amazon.com/corretto/latest/corretto-21-ug/windows-install.html)
- [Linux](https://docs.aws.amazon.com/corretto/latest/corretto-21-ug/generic-linux-install.html)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.limechain.chain.lightsyncstate;

import io.emeraldpay.polkaj.types.Hash256;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.io.Serializable;
import java.math.BigInteger;

@Getter
@AllArgsConstructor
public class Authority {
private final Hash256 publicKey;
public class Authority implements Serializable {
private final byte[] publicKey;
private final BigInteger weight;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
import io.emeraldpay.polkaj.scale.ScaleCodecReader;
import io.emeraldpay.polkaj.scale.ScaleReader;
import io.emeraldpay.polkaj.scale.reader.UInt64Reader;
import io.emeraldpay.polkaj.types.Hash256;

public class AuthorityReader implements ScaleReader<Authority> {
@Override
public Authority read(ScaleCodecReader reader) {
return new Authority(new Hash256(reader.readUint256()), new UInt64Reader().read(reader));
return new Authority(reader.readUint256(), new UInt64Reader().read(reader));
}
}
10 changes: 8 additions & 2 deletions src/main/java/com/limechain/client/FullNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,15 @@ public void start() {
log.log(Level.INFO, "Node successfully connected to a peer! Sync can start!");

CliArguments args = AppBean.getBean(CliArguments.class);
WarpSyncMachine warpSyncMachine = AppBean.getBean(WarpSyncMachine.class);
FullSyncMachine fullSyncMachine = AppBean.getBean(FullSyncMachine.class);

switch (args.syncMode()) {
case FULL -> AppBean.getBean(FullSyncMachine.class).start();
case WARP -> AppBean.getBean(WarpSyncMachine.class).start();
case FULL -> fullSyncMachine.start();
case WARP -> {
warpSyncMachine.onFinish(() -> fullSyncMachine.start());
warpSyncMachine.start();
}
default -> throw new IllegalStateException("Unexpected value: " + args.syncMode());
}
}
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/com/limechain/config/SystemInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

import com.limechain.chain.Chain;
import com.limechain.network.Network;
import com.limechain.sync.warpsync.SyncedState;
import com.limechain.storage.block.SyncState;
import lombok.Getter;
import lombok.extern.java.Log;
import org.springframework.beans.factory.annotation.Value;

import java.math.BigInteger;
import java.nio.file.FileSystems;
import java.util.logging.Level;

Expand All @@ -24,12 +25,14 @@ public class SystemInfo {
private String hostName;
@Value("${host.version}")
private String hostVersion;
private final BigInteger highestBlock;

public SystemInfo(HostConfig hostConfig, Network network) {
public SystemInfo(HostConfig hostConfig, Network network, SyncState syncState) {
this.role = network.getNodeRole().name();
this.chain = hostConfig.getChain();
this.dbPath = hostConfig.getRocksDbPath();
this.hostIdentity = network.getHost().getPeerId().toString();
this.highestBlock = syncState.getLastFinalizedBlockNumber();
}

/**
Expand All @@ -53,6 +56,6 @@ public void logSystemInfo() {
log.log(Level.INFO, "Local node identity is: " + hostIdentity);
log.log(Level.INFO, "Operating System: " + System.getProperty("os.name"));
log.log(Level.INFO, "CPU architecture: " + System.getProperty("os.arch"));
log.log(Level.INFO, "Highest known block at #" + SyncedState.getInstance().getLastFinalizedBlockNumber());
log.log(Level.INFO, "Highest known block at #" + highestBlock);
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/limechain/network/ConnectionManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import com.limechain.network.dto.PeerInfo;
import com.limechain.network.dto.ProtocolStreamType;
import com.limechain.network.dto.ProtocolStreams;
import com.limechain.network.protocol.blockannounce.scale.BlockAnnounceHandshake;
import com.limechain.network.protocol.blockannounce.scale.BlockAnnounceMessage;
import com.limechain.network.protocol.blockannounce.messages.BlockAnnounceHandshake;
import com.limechain.network.protocol.blockannounce.messages.BlockAnnounceMessage;
import com.limechain.network.protocol.warp.dto.BlockHeader;
import io.libp2p.core.PeerId;
import io.libp2p.core.Stream;
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/com/limechain/network/Network.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
import com.limechain.network.protocol.transactions.TransactionsService;
import com.limechain.network.protocol.warp.WarpSyncService;
import com.limechain.network.protocol.warp.dto.WarpSyncResponse;
import com.limechain.rpc.server.AppBean;
import com.limechain.storage.DBConstants;
import com.limechain.storage.KVRepository;
import com.limechain.sync.warpsync.SyncedState;
import com.limechain.sync.warpsync.WarpSyncState;
import com.limechain.utils.Ed25519Utils;
import com.limechain.utils.StringUtils;
import io.ipfs.multiaddr.MultiAddress;
Expand Down Expand Up @@ -58,13 +59,11 @@ public class Network {
private static final int HOST_PORT = 30333;
private static final Random RANDOM = new Random();
@Getter
private static Network network;
@Getter
private final Chain chain;
@Getter
private final NodeRole nodeRole;
private final String[] bootNodes;
private final ConnectionManager connectionManager = ConnectionManager.getInstance();
private final ConnectionManager connectionManager;
private SyncService syncService;
private StateService stateService;
private LightMessagesService lightMessagesService;
Expand Down Expand Up @@ -99,6 +98,7 @@ public Network(ChainService chainService, HostConfig hostConfig, KVRepository<St
this.bootNodes = chainService.getChainSpec().getBootNodes();
this.chain = hostConfig.getChain();
this.nodeRole = hostConfig.getNodeRole();
this.connectionManager = ConnectionManager.getInstance();
this.initializeProtocols(chainService, genesisBlockHash, hostConfig, repository, cliArgs);
}

Expand Down Expand Up @@ -152,7 +152,7 @@ private void initializeProtocols(ChainService chainService, GenesisBlockHash gen
)
);

if (nodeRole == NodeRole.FULL) {
if (nodeRole == NodeRole.AUTHORING) {
hostBuilder.addProtocols(
List.of(
transactionsService.getProtocol()
Expand Down Expand Up @@ -361,7 +361,7 @@ private void sendGrandpaHandshake(PeerId peerId) {

@Scheduled(fixedRate = 5, initialDelay = 5, timeUnit = TimeUnit.MINUTES)
public void sendNeighbourMessages() {
if (!SyncedState.getInstance().isWarpSyncFinished()) {
if (!AppBean.getBean(WarpSyncState.class).isWarpSyncFinished()) {
return;
}
connectionManager.getPeerIds().forEach(peerId -> grandpaService.sendNeighbourMessage(this.host, peerId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,23 @@
import com.limechain.exception.scale.ScaleEncodingException;
import com.limechain.exception.storage.BlockNodeNotFoundException;
import com.limechain.network.ConnectionManager;
import com.limechain.network.protocol.blockannounce.scale.BlockAnnounceHandshake;
import com.limechain.network.protocol.blockannounce.messages.BlockAnnounceHandshake;
import com.limechain.network.protocol.blockannounce.messages.BlockAnnounceHandshakeBuilder;
import com.limechain.network.protocol.blockannounce.messages.BlockAnnounceMessage;
import com.limechain.network.protocol.blockannounce.scale.BlockAnnounceHandshakeScaleReader;
import com.limechain.network.protocol.blockannounce.scale.BlockAnnounceHandshakeScaleWriter;
import com.limechain.network.protocol.blockannounce.scale.BlockAnnounceMessage;
import com.limechain.network.protocol.blockannounce.scale.BlockAnnounceMessageScaleReader;
import com.limechain.network.protocol.warp.dto.Block;
import com.limechain.network.protocol.warp.dto.BlockBody;
import com.limechain.rpc.server.AppBean;
import com.limechain.storage.block.BlockState;
import com.limechain.sync.warpsync.SyncedState;
import com.limechain.sync.warpsync.WarpSyncState;
import io.emeraldpay.polkaj.scale.ScaleCodecReader;
import io.emeraldpay.polkaj.scale.ScaleCodecWriter;
import io.libp2p.core.PeerId;
import io.libp2p.core.Stream;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.extern.java.Log;

import java.io.ByteArrayOutputStream;
Expand All @@ -24,10 +28,18 @@
import java.util.logging.Level;

@Log
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class BlockAnnounceEngine {
public static final int HANDSHAKE_LENGTH = 69;
protected ConnectionManager connectionManager = ConnectionManager.getInstance();
protected SyncedState syncedState = SyncedState.getInstance();
protected ConnectionManager connectionManager;
protected WarpSyncState warpSyncState;
protected BlockAnnounceHandshakeBuilder handshakeBuilder;

public BlockAnnounceEngine() {
connectionManager = ConnectionManager.getInstance();
warpSyncState = AppBean.getBean(WarpSyncState.class);
handshakeBuilder = new BlockAnnounceHandshakeBuilder();
}

public void receiveRequest(byte[] msg, Stream stream) {
PeerId peerId = stream.remotePeerId();
Expand Down Expand Up @@ -71,7 +83,7 @@ private void handleBlockAnnounce(byte[] msg, PeerId peerId) {
ScaleCodecReader reader = new ScaleCodecReader(msg);
BlockAnnounceMessage announce = reader.read(new BlockAnnounceMessageScaleReader());
connectionManager.updatePeer(peerId, announce);
syncedState.syncBlockAnnounce(announce);
warpSyncState.syncBlockAnnounce(announce);
log.log(Level.FINE, "Received block announce for block #" + announce.getHeader().getBlockNumber() +
" from " + peerId +
" with hash:0x" + announce.getHeader().getHash() +
Expand All @@ -92,7 +104,7 @@ private void handleBlockAnnounce(byte[] msg, PeerId peerId) {
public void writeHandshakeToStream(Stream stream, PeerId peerId) {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
try (ScaleCodecWriter writer = new ScaleCodecWriter(buf)) {
writer.write(new BlockAnnounceHandshakeScaleWriter(), syncedState.getHandshake());
writer.write(new BlockAnnounceHandshakeScaleWriter(), handshakeBuilder.getBlockAnnounceHandshake());
} catch (IOException e) {
throw new ScaleEncodingException(e);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.limechain.network.protocol.blockannounce.scale;
package com.limechain.network.protocol.blockannounce.messages;

import io.emeraldpay.polkaj.types.Hash256;
import lombok.AllArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.limechain.network.protocol.blockannounce.messages;

import com.limechain.config.HostConfig;
import com.limechain.network.protocol.blockannounce.NodeRole;
import com.limechain.rpc.server.AppBean;
import com.limechain.storage.block.SyncState;
import io.emeraldpay.polkaj.types.Hash256;

import java.math.BigInteger;

public class BlockAnnounceHandshakeBuilder {

/**
* Creates a Block Announce handshake based on the latest finalized Host state
*
* @return our Block Announce handshake
*/
public BlockAnnounceHandshake getBlockAnnounceHandshake() {
SyncState syncState = AppBean.getBean(SyncState.class);
HostConfig hostConfig = AppBean.getBean(HostConfig.class);

Hash256 genesisBlockHash = syncState.getGenesisBlockHash();
Hash256 lastFinalizedBlockHash = syncState.getLastFinalizedBlockHash();
BigInteger lastFinalizedBlockNumber = syncState.getLastFinalizedBlockNumber();

NodeRole nodeRole = hostConfig.getNodeRole();

Hash256 blockHash = lastFinalizedBlockHash == null
? genesisBlockHash
: lastFinalizedBlockHash;
return new BlockAnnounceHandshake(
nodeRole.getValue(),
lastFinalizedBlockNumber,
blockHash,
genesisBlockHash
);
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.limechain.network.protocol.blockannounce.scale;
package com.limechain.network.protocol.blockannounce.messages;

import com.limechain.network.protocol.warp.dto.BlockHeader;
import lombok.Getter;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.limechain.network.protocol.blockannounce.scale;

import com.limechain.network.protocol.blockannounce.messages.BlockAnnounceHandshake;
import io.emeraldpay.polkaj.scale.ScaleCodecReader;
import io.emeraldpay.polkaj.scale.ScaleReader;
import io.emeraldpay.polkaj.types.Hash256;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.limechain.network.protocol.blockannounce.scale;

import com.limechain.network.protocol.blockannounce.messages.BlockAnnounceHandshake;
import io.emeraldpay.polkaj.scale.ScaleCodecWriter;
import io.emeraldpay.polkaj.scale.ScaleWriter;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.limechain.network.protocol.blockannounce.scale;

import com.limechain.network.protocol.blockannounce.messages.BlockAnnounceMessage;
import com.limechain.network.protocol.warp.scale.reader.BlockHeaderReader;
import io.emeraldpay.polkaj.scale.ScaleCodecReader;
import io.emeraldpay.polkaj.scale.ScaleReader;
Expand Down
Loading

0 comments on commit 9ba3005

Please sign in to comment.