Skip to content
This repository has been archived by the owner on Dec 5, 2024. It is now read-only.

Commit

Permalink
Fix race condition in updateBlockTotDifficulties
Browse files Browse the repository at this point in the history
A tricky and rare case when fork block is imported with fixed TD and
undeservedly became a canonical chain block.
When that has happened there is no chance to re-branch back to canonical chain.
  • Loading branch information
mkalinin committed May 17, 2018
1 parent e6a5dd6 commit 99e22a5
Showing 1 changed file with 29 additions and 0 deletions.
29 changes: 29 additions & 0 deletions ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -1092,8 +1092,37 @@ public void updateBlockTotDifficulties(long startFrom) {
while(true) {
synchronized (this) {
((IndexedBlockStore) blockStore).updateTotDifficulties(startFrom);

if (startFrom == bestBlock.getNumber()) {
totalDifficulty = blockStore.getTotalDifficultyForHash(bestBlock.getHash());
}

if (startFrom == blockStore.getMaxNumber()) {
Block bestStoredBlock = bestBlock;
BigInteger maxTD = totalDifficulty;

// traverse blocks toward max known number to get the best block
for (long num = bestBlock.getNumber() + 1; num <= blockStore.getMaxNumber(); num++) {
List<Block> blocks = ((IndexedBlockStore) blockStore).getBlocksByNumber(num);
for (Block block : blocks) {
BigInteger td = blockStore.getTotalDifficultyForHash(block.getHash());
if (maxTD.compareTo(td) < 0) {
maxTD = td;
bestStoredBlock = block;
}
}
}

if (totalDifficulty.compareTo(maxTD) < 0) {
blockStore.reBranch(bestStoredBlock);
bestBlock = bestStoredBlock;
totalDifficulty = maxTD;
repository = repository.getSnapshotTo(bestBlock.getStateRoot());

logger.info("totDifficulties update: re-branch to block {}, totalDifficulty {}",
bestBlock.getHeader().getShortDescr(), totalDifficulty);
}

break;
}
startFrom++;
Expand Down

0 comments on commit 99e22a5

Please sign in to comment.