diff --git a/ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/manager/EthPeers.java b/ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/manager/EthPeers.java index 557a32e627..4992004a88 100644 --- a/ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/manager/EthPeers.java +++ b/ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/manager/EthPeers.java @@ -33,6 +33,9 @@ public class EthPeers { public static final Comparator CHAIN_HEIGHT = Comparator.comparing(((final EthPeer p) -> p.chainState().getEstimatedHeight())); + private static final Comparator HIGHEST_TOTAL_DIFFICULTY_PEER = + TOTAL_DIFFICULTY.thenComparing(CHAIN_HEIGHT); + public static final Comparator BEST_CHAIN = CHAIN_HEIGHT.thenComparing(TOTAL_DIFFICULTY); public static final Comparator LEAST_TO_MOST_BUSY = @@ -93,6 +96,10 @@ public Optional bestPeer() { return availablePeers().max(BEST_CHAIN); } + public Optional highestTotalDifficultyPeer() { + return availablePeers().max(HIGHEST_TOTAL_DIFFICULTY_PEER); + } + public Optional idlePeer() { return idlePeers().min(LEAST_TO_MOST_BUSY); } diff --git a/ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/sync/fastsync/FastSyncActions.java b/ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/sync/fastsync/FastSyncActions.java index 6582816584..0ce9d2b9ce 100644 --- a/ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/sync/fastsync/FastSyncActions.java +++ b/ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/sync/fastsync/FastSyncActions.java @@ -119,7 +119,7 @@ public CompletableFuture selectPivotBlock(final FastSyncState fas private CompletableFuture selectPivotBlockFromPeers() { return ethContext .getEthPeers() - .bestPeer() + .highestTotalDifficultyPeer() .filter(peer -> peer.chainState().hasEstimatedHeight()) .map( peer -> { diff --git a/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/sync/fastsync/FastSyncActionsTest.java b/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/sync/fastsync/FastSyncActionsTest.java index 9c32065ab2..ce82a30efa 100644 --- a/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/sync/fastsync/FastSyncActionsTest.java +++ b/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/sync/fastsync/FastSyncActionsTest.java @@ -39,6 +39,7 @@ import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule; import tech.pegasys.pantheon.metrics.LabelledMetric; import tech.pegasys.pantheon.metrics.OperationTimer; +import tech.pegasys.pantheon.util.uint.UInt256; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicInteger; @@ -150,6 +151,17 @@ public void selectPivotBlockShouldSelectBlockPivotDistanceFromBestPeer() { assertThat(result).isCompletedWithValue(expected); } + @Test + public void selectPivotBlockShouldConsiderTotalDifficultyWhenSelectingBestPeer() { + EthProtocolManagerTestUtil.createPeer(ethProtocolManager, UInt256.of(1000), 5500); + EthProtocolManagerTestUtil.createPeer(ethProtocolManager, UInt256.of(2000), 4000); + + final CompletableFuture result = + fastSyncActions.selectPivotBlock(EMPTY_SYNC_STATE); + final FastSyncState expected = new FastSyncState(3000); + assertThat(result).isCompletedWithValue(expected); + } + @Test public void selectPivotBlockShouldWaitAndRetryIfNoPeersAreAvailable() { final CompletableFuture result =