forked from Qortal/qortal
Split Synchronizer.applyNewBlocks() into two methods.
If fast syncing is enabled in the settings (by default it's disabled) AND the peer is running at least v1.5.0, then it will route through to a new method which fetches multiple blocks at a time, in a very similar way to Synchronizer.syncToPeerChain(). If fast syncing is disabled in the settings, or we are communicating with a peer on an older version, it will continue to sync blocks individually.
This commit is contained in:
parent
8c3753326f
commit
3e0ff7f43f
@ -572,8 +572,103 @@ public class Synchronizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SynchronizationResult applyNewBlocks(Repository repository, BlockData commonBlockData, int ourInitialHeight,
|
private SynchronizationResult applyNewBlocks(Repository repository, BlockData commonBlockData, int ourInitialHeight,
|
||||||
|
Peer peer, int peerHeight, List<BlockSummaryData> peerBlockSummaries) throws InterruptedException, DataException {
|
||||||
|
|
||||||
|
if (Settings.getInstance().isFastSyncEnabled() && peer.getPeersVersion() >= PEER_VERSION_150)
|
||||||
|
// This peer supports syncing multiple blocks at once via GetBlocksMessage, and it is enabled in the settings
|
||||||
|
return this.applyNewBlocksUsingFastSync(repository, commonBlockData, ourInitialHeight, peer, peerHeight, peerBlockSummaries);
|
||||||
|
else
|
||||||
|
// Older peer version, or fast sync is disabled in the settings - use slow sync
|
||||||
|
return this.applyNewBlocksUsingSlowSync(repository, commonBlockData, ourInitialHeight, peer, peerHeight, peerBlockSummaries);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private SynchronizationResult applyNewBlocksUsingFastSync(Repository repository, BlockData commonBlockData, int ourInitialHeight,
|
||||||
|
Peer peer, int peerHeight, List<BlockSummaryData> peerBlockSummaries) throws InterruptedException, DataException {
|
||||||
|
LOGGER.debug(String.format("Fetching new blocks from peer %s using fast sync", peer));
|
||||||
|
|
||||||
|
final int commonBlockHeight = commonBlockData.getHeight();
|
||||||
|
final byte[] commonBlockSig = commonBlockData.getSignature();
|
||||||
|
byte[] latestPeerSignature = commonBlockSig;
|
||||||
|
|
||||||
|
int ourHeight = ourInitialHeight;
|
||||||
|
|
||||||
|
// Fetch, and apply, blocks from peer
|
||||||
|
int maxBatchHeight = commonBlockHeight + SYNC_BATCH_SIZE;
|
||||||
|
|
||||||
|
while (ourHeight < peerHeight && ourHeight < maxBatchHeight) {
|
||||||
|
if (Controller.isStopping())
|
||||||
|
return SynchronizationResult.SHUTTING_DOWN;
|
||||||
|
|
||||||
|
int numberRequested = Math.min(maxBatchHeight - ourHeight, MAXIMUM_REQUEST_SIZE);
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (blocks == null || blocks.isEmpty()) {
|
||||||
|
LOGGER.info(String.format("Peer %s failed to respond with more blocks after height %d, sig %.8s", peer,
|
||||||
|
ourHeight, Base58.encode(latestPeerSignature)));
|
||||||
|
}
|
||||||
|
LOGGER.trace(String.format("Received %d blocks after height %d, sig %.8s from %s", blocks.size(), ourHeight, Base58.encode(latestPeerSignature), peer));
|
||||||
|
|
||||||
|
for (Block newBlock : blocks) {
|
||||||
|
++ourHeight;
|
||||||
|
|
||||||
|
if (Controller.isStopping())
|
||||||
|
return SynchronizationResult.SHUTTING_DOWN;
|
||||||
|
|
||||||
|
if (newBlock == null) {
|
||||||
|
LOGGER.info(String.format("Peer %s failed to respond with block for height %d, sig %.8s", peer,
|
||||||
|
ourHeight, Base58.encode(latestPeerSignature)));
|
||||||
|
return SynchronizationResult.NO_REPLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!newBlock.isSignatureValid()) {
|
||||||
|
LOGGER.info(String.format("Peer %s sent block with invalid signature for height %d, sig %.8s", peer,
|
||||||
|
ourHeight, Base58.encode(latestPeerSignature)));
|
||||||
|
return SynchronizationResult.INVALID_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the repository, because we couldn't do that when originally constructing the Block
|
||||||
|
newBlock.setRepository(repository);
|
||||||
|
|
||||||
|
// Transactions are transmitted without approval status so determine that now
|
||||||
|
for (Transaction transaction : newBlock.getTransactions()) {
|
||||||
|
transaction.setInitialApprovalStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
ValidationResult blockResult = newBlock.isValid();
|
||||||
|
if (blockResult != ValidationResult.OK) {
|
||||||
|
LOGGER.info(String.format("Peer %s sent invalid block for height %d, sig %.8s: %s", peer,
|
||||||
|
ourHeight, Base58.encode(latestPeerSignature), blockResult.name()));
|
||||||
|
return SynchronizationResult.INVALID_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save transactions attached to this block
|
||||||
|
for (Transaction transaction : newBlock.getTransactions()) {
|
||||||
|
TransactionData transactionData = transaction.getTransactionData();
|
||||||
|
repository.getTransactionRepository().save(transactionData);
|
||||||
|
}
|
||||||
|
|
||||||
|
newBlock.process();
|
||||||
|
|
||||||
|
LOGGER.trace(String.format("Processed block height %d, sig %.8s", newBlock.getBlockData().getHeight(), Base58.encode(newBlock.getBlockData().getSignature())));
|
||||||
|
|
||||||
|
repository.saveChanges();
|
||||||
|
|
||||||
|
Controller.getInstance().onNewBlock(newBlock.getBlockData());
|
||||||
|
|
||||||
|
// Update latestPeerSignature so that subsequent batches start requesting from the correct block
|
||||||
|
latestPeerSignature = newBlock.getSignature();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return SynchronizationResult.OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SynchronizationResult applyNewBlocksUsingSlowSync(Repository repository, BlockData commonBlockData, int ourInitialHeight,
|
||||||
Peer peer, int peerHeight, List<BlockSummaryData> peerBlockSummaries) throws InterruptedException, DataException {
|
Peer peer, int peerHeight, List<BlockSummaryData> peerBlockSummaries) throws InterruptedException, DataException {
|
||||||
LOGGER.debug(String.format("Fetching new blocks from peer %s", peer));
|
LOGGER.debug(String.format("Fetching new blocks from peer %s using slow sync", peer));
|
||||||
|
|
||||||
final int commonBlockHeight = commonBlockData.getHeight();
|
final int commonBlockHeight = commonBlockData.getHeight();
|
||||||
final byte[] commonBlockSig = commonBlockData.getSignature();
|
final byte[] commonBlockSig = commonBlockData.getSignature();
|
||||||
|
Loading…
Reference in New Issue
Block a user