Update SysTray for all synchronizing scenarios.

When synchronizing is forced via API call, the SysTray doesn't update
to reflect this.

We fix this by moving the SysTray updating code from
Controller.potentiallySynchronize() to the inner method
Controller.actuallySynchronize(), which is also the method called
directly by the API.
This commit is contained in:
catbref 2020-04-15 17:36:12 +01:00
parent e25d24964c
commit 1e9a7ac87d

View File

@ -528,103 +528,105 @@ public class Controller extends Thread {
int index = new SecureRandom().nextInt(peers.size()); int index = new SecureRandom().nextInt(peers.size());
Peer peer = peers.get(index); Peer peer = peers.get(index);
actuallySynchronize(peer, false);
}
public SynchronizationResult actuallySynchronize(Peer peer, boolean force) throws InterruptedException {
syncPercent = (this.chainTip.getHeight() * 100) / peer.getChainTipData().getLastHeight(); syncPercent = (this.chainTip.getHeight() * 100) / peer.getChainTipData().getLastHeight();
isSynchronizing = true; isSynchronizing = true;
updateSysTray(); updateSysTray();
actuallySynchronize(peer, false); BlockData priorChainTip = this.chainTip;
isSynchronizing = false; try {
requestSysTrayUpdate = true; SynchronizationResult syncResult = Synchronizer.getInstance().synchronize(peer, force);
} switch (syncResult) {
case GENESIS_ONLY:
case NO_COMMON_BLOCK:
case TOO_DIVERGENT:
case INVALID_DATA: {
// These are more serious results that warrant a cool-off
LOGGER.info(String.format("Failed to synchronize with peer %s (%s) - cooling off", peer, syncResult.name()));
public SynchronizationResult actuallySynchronize(Peer peer, boolean force) throws InterruptedException { // Don't use this peer again for a while
BlockData latestBlockData = getChainTip(); PeerData peerData = peer.getPeerData();
peerData.setLastMisbehaved(NTP.getTime());
SynchronizationResult syncResult = Synchronizer.getInstance().synchronize(peer, force); // Only save to repository if outbound peer
switch (syncResult) { if (peer.isOutbound())
case GENESIS_ONLY: try (final Repository repository = RepositoryManager.getRepository()) {
case NO_COMMON_BLOCK: repository.getNetworkRepository().save(peerData);
case TOO_DIVERGENT: repository.saveChanges();
case INVALID_DATA: { } catch (DataException e) {
// These are more serious results that warrant a cool-off LOGGER.warn("Repository issue while updating peer synchronization info", e);
LOGGER.info(String.format("Failed to synchronize with peer %s (%s) - cooling off", peer, syncResult.name())); }
break;
}
// Don't use this peer again for a while case INFERIOR_CHAIN: {
PeerData peerData = peer.getPeerData(); // Update our list of inferior chain tips
peerData.setLastMisbehaved(NTP.getTime()); ByteArray inferiorChainSignature = new ByteArray(peer.getChainTipData().getLastBlockSignature());
if (!inferiorChainSignatures.contains(inferiorChainSignature))
inferiorChainSignatures.add(inferiorChainSignature);
// Only save to repository if outbound peer // These are minor failure results so fine to try again
if (peer.isOutbound()) LOGGER.debug(() -> String.format("Refused to synchronize with peer %s (%s)", peer, syncResult.name()));
try (final Repository repository = RepositoryManager.getRepository()) {
repository.getNetworkRepository().save(peerData); // Notify peer of our superior chain
repository.saveChanges(); if (!peer.sendMessage(Network.getInstance().buildHeightMessage(peer, priorChainTip)))
} catch (DataException e) { peer.disconnect("failed to notify peer of our superior chain");
LOGGER.warn("Repository issue while updating peer synchronization info", e); break;
} }
break;
case NO_REPLY:
case NO_BLOCKCHAIN_LOCK:
case REPOSITORY_ISSUE:
// These are minor failure results so fine to try again
LOGGER.debug(() -> String.format("Failed to synchronize with peer %s (%s)", peer, syncResult.name()));
break;
case SHUTTING_DOWN:
// Just quietly exit
break;
case OK:
requestSysTrayUpdate = true;
// fall-through...
case NOTHING_TO_DO: {
// Update our list of inferior chain tips
ByteArray inferiorChainSignature = new ByteArray(peer.getChainTipData().getLastBlockSignature());
if (!inferiorChainSignatures.contains(inferiorChainSignature))
inferiorChainSignatures.add(inferiorChainSignature);
LOGGER.debug(() -> String.format("Synchronized with peer %s (%s)", peer, syncResult.name()));
break;
}
} }
case INFERIOR_CHAIN: { // Has our chain tip changed?
// Update our list of inferior chain tips BlockData newChainTip;
ByteArray inferiorChainSignature = new ByteArray(peer.getChainTipData().getLastBlockSignature());
if (!inferiorChainSignatures.contains(inferiorChainSignature))
inferiorChainSignatures.add(inferiorChainSignature);
// These are minor failure results so fine to try again try (final Repository repository = RepositoryManager.getRepository()) {
LOGGER.debug(() -> String.format("Refused to synchronize with peer %s (%s)", peer, syncResult.name())); newChainTip = repository.getBlockRepository().getLastBlock();
this.setChainTip(newChainTip);
// Notify peer of our superior chain } catch (DataException e) {
if (!peer.sendMessage(Network.getInstance().buildHeightMessage(peer, latestBlockData))) LOGGER.warn(String.format("Repository issue when trying to fetch post-synchronization chain tip: %s", e.getMessage()));
peer.disconnect("failed to notify peer of our superior chain"); return syncResult;
break;
} }
case NO_REPLY: if (!Arrays.equals(newChainTip.getSignature(), priorChainTip.getSignature())) {
case NO_BLOCKCHAIN_LOCK: // Broadcast our new chain tip
case REPOSITORY_ISSUE: Network.getInstance().broadcast(recipientPeer -> Network.getInstance().buildHeightMessage(recipientPeer, newChainTip));
// These are minor failure results so fine to try again
LOGGER.debug(() -> String.format("Failed to synchronize with peer %s (%s)", peer, syncResult.name()));
break;
case SHUTTING_DOWN: // Reset our cache of inferior chains
// Just quietly exit inferiorChainSignatures.clear();
break;
case OK:
requestSysTrayUpdate = true;
// fall-through...
case NOTHING_TO_DO: {
// Update our list of inferior chain tips
ByteArray inferiorChainSignature = new ByteArray(peer.getChainTipData().getLastBlockSignature());
if (!inferiorChainSignatures.contains(inferiorChainSignature))
inferiorChainSignatures.add(inferiorChainSignature);
LOGGER.debug(() -> String.format("Synchronized with peer %s (%s)", peer, syncResult.name()));
break;
} }
}
// Has our chain tip changed?
BlockData newLatestBlockData;
try (final Repository repository = RepositoryManager.getRepository()) {
newLatestBlockData = repository.getBlockRepository().getLastBlock();
this.setChainTip(newLatestBlockData);
} catch (DataException e) {
LOGGER.warn(String.format("Repository issue when trying to fetch post-synchronization chain tip: %s", e.getMessage()));
return syncResult; return syncResult;
} finally {
isSynchronizing = false;
requestSysTrayUpdate = true;
} }
if (!Arrays.equals(newLatestBlockData.getSignature(), latestBlockData.getSignature())) {
// Broadcast our new chain tip
Network.getInstance().broadcast(recipientPeer -> Network.getInstance().buildHeightMessage(recipientPeer, newLatestBlockData));
// Reset our cache of inferior chains
inferiorChainSignatures.clear();
}
return syncResult;
} }
private void updateSysTray() { private void updateSysTray() {