Browse Source

Added new settings "maxBlocksPerRequest" and "maxBlocksPerResponse", to control the number of blocks requested and returned by nodes when using GetBlocksMessage and BlocksMessage.

sync-multiple-blocks
CalDescent 4 years ago
parent
commit
08f3d653cc
  1. 8
      src/main/java/org/qortal/controller/Controller.java
  2. 14
      src/main/java/org/qortal/controller/Synchronizer.java
  3. 1
      src/main/java/org/qortal/network/Network.java
  4. 1
      src/main/java/org/qortal/network/message/BlocksMessage.java
  5. 8
      src/main/java/org/qortal/settings/Settings.java

8
src/main/java/org/qortal/controller/Controller.java

@ -1245,6 +1245,10 @@ public class Controller extends Thread {
return;
}
// Ensure that we don't serve more blocks than the amount specified in the settings
// Serializing multiple blocks is very slow, so by default we are using a low limit
int blockLimitPerRequest = Settings.getInstance().getMaxBlocksPerResponse();
List<BlockData> blockDataList = new ArrayList<>();
// Attempt to serve from our cache of latest blocks
@ -1256,7 +1260,7 @@ public class Controller extends Thread {
}
if (blockDataList.isEmpty()) {
int numberRequested = Math.min(Network.MAX_BLOCKS_PER_REPLY, getBlocksMessage.getNumberRequested());
int numberRequested = Math.min(blockLimitPerRequest, getBlocksMessage.getNumberRequested());
BlockData blockData = repository.getBlockRepository().fromReference(parentSignature);
@ -1274,9 +1278,11 @@ public class Controller extends Thread {
List<Block> blocks = new ArrayList<>();
for (BlockData blockData : blockDataList) {
if (blocks.size() < blockLimitPerRequest) {
Block block = new Block(repository, blockData);
blocks.add(block);
}
}
Message blocksMessage = new BlocksMessage(blocks);
blocksMessage.setId(message.getId());

14
src/main/java/org/qortal/controller/Synchronizer.java

@ -56,9 +56,6 @@ public class Synchronizer {
/** Maximum number of block signatures we ask from peer in one go */
private static final int MAXIMUM_REQUEST_SIZE = 200; // XXX move to Settings?
/** Maximum number of blocks we ask from peer in one go */
private static final int MAXIMUM_BLOCKS_REQUEST_SIZE = 1; // XXX move to Settings?
/** Number of retry attempts if a peer fails to respond with the requested data */
private static final int MAXIMUM_RETRIES = 1; // XXX move to Settings?
@ -380,13 +377,17 @@ public class Synchronizer {
if (Settings.getInstance().isFastSyncEnabledWhenResolvingFork() && peer.getPeersVersion() >= PEER_VERSION_150) {
// This peer supports syncing multiple blocks at once via GetBlocksMessage, and it is enabled in the settings
int numberBlocksRequired = additionalPeerBlocksAfterCommonBlock - peerBlocks.size();
// Ensure that we don't request more blocks than specified in the settings
int maxBlocksPerRequest = Settings.getInstance().getMaxBlocksPerRequest();
while (numberBlocksRequired > 0) {
if (Controller.isStopping())
return SynchronizationResult.SHUTTING_DOWN;
byte[] latestPeerSignature = peerBlocks.isEmpty() ? commonBlockSig : peerBlocks.get(peerBlocks.size() - 1).getSignature();
int lastPeerHeight = commonBlockHeight + peerBlocks.size();
int numberOfBlocksToRequest = Math.min(numberBlocksRequired, MAXIMUM_BLOCKS_REQUEST_SIZE);
int numberOfBlocksToRequest = Math.min(numberBlocksRequired, maxBlocksPerRequest);
LOGGER.trace(String.format("Requesting %d block%s after height %d, sig %.8s",
numberOfBlocksToRequest, (numberOfBlocksToRequest != 1 ? "s" : ""), lastPeerHeight, Base58.encode(latestPeerSignature)));
@ -600,11 +601,14 @@ public class Synchronizer {
// Fetch, and apply, blocks from peer
int maxBatchHeight = commonBlockHeight + SYNC_BATCH_SIZE;
// Ensure that we don't request more blocks than specified in the settings
int maxBlocksPerRequest = Settings.getInstance().getMaxBlocksPerRequest();
while (ourHeight < peerHeight && ourHeight < maxBatchHeight) {
if (Controller.isStopping())
return SynchronizationResult.SHUTTING_DOWN;
int numberRequested = Math.min(maxBatchHeight - ourHeight, MAXIMUM_BLOCKS_REQUEST_SIZE);
int numberRequested = Math.min(maxBatchHeight - ourHeight, maxBlocksPerRequest);
LOGGER.trace(String.format("Fetching %d blocks after height %d, sig %.8s from %s", numberRequested, ourHeight, Base58.encode(latestPeerSignature), peer));
List<Block> blocks = this.fetchBlocks(repository, peer, latestPeerSignature, numberRequested);

1
src/main/java/org/qortal/network/Network.java

@ -89,7 +89,6 @@ public class Network {
public static final int MAX_SIGNATURES_PER_REPLY = 500;
public static final int MAX_BLOCK_SUMMARIES_PER_REPLY = 500;
public static final int MAX_BLOCKS_PER_REPLY = 500;
// Generate our node keys / ID
private final Ed25519PrivateKeyParameters edPrivateKeyParams = new Ed25519PrivateKeyParameters(new SecureRandom());

1
src/main/java/org/qortal/network/message/BlocksMessage.java

@ -78,6 +78,7 @@ public class BlocksMessage extends Message {
bytes.write(Ints.toByteArray(block.getBlockData().getHeight()));
bytes.write(BlockTransformer.toBytes(block));
}
LOGGER.trace(String.format("Total length of %d blocks is %d bytes", this.blocks.size(), bytes.size()));
return bytes.toByteArray();
} catch (IOException e) {

8
src/main/java/org/qortal/settings/Settings.java

@ -127,6 +127,10 @@ public class Settings {
private boolean fastSyncEnabled = false;
/** Whether to sync multiple blocks at once when the peer has a different chain */
private boolean fastSyncEnabledWhenResolvingFork = true;
/** Maximum number of blocks to request at once */
private int maxBlocksPerRequest = 1;
/** Maximum number of blocks this node will serve in a single response */
private int maxBlocksPerResponse = 5;
// Which blockchains this node is running
private String blockchainConfig = null; // use default from resources
@ -449,6 +453,10 @@ public class Settings {
return this.fastSyncEnabledWhenResolvingFork;
}
public int getMaxBlocksPerRequest() { return this.maxBlocksPerRequest; }
public int getMaxBlocksPerResponse() { return this.maxBlocksPerResponse; }
public boolean isAutoUpdateEnabled() {
return this.autoUpdateEnabled;
}

Loading…
Cancel
Save