Align blocks difficulty - #647
Conversation
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
8a6b781 to
d6ffdc2
Compare
ccdce64 to
ef63db9
Compare
90a1cc7 to
d15fc2b
Compare
ef63db9 to
6d0f650
Compare
6d0f650 to
19ec163
Compare
There was a problem hiding this comment.
Pull request overview
Updates PowHSM advance-blockchain bookkeeping so block difficulty accounting matches what can actually be delivered to the HSM (i.e., only counting uncles that can be sent as “brothers”), and modernizes a small piece of stream collection code.
Changes:
- Update confirmed-block selection to use a new
getBlockTotalDifficulty(block, hsmBestBlockHeight)that ignores uncles at/below the HSM best block height. - Refactor
getConfirmedBlocksinternals to track “blocks in window” + proof blocks more explicitly. - Replace
Collectors.toList()withStream.toList()inAdvanceBlockchainMessage.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/main/java/co/rsk/federate/signing/hsm/advanceblockchain/ConfirmedBlocksProvider.java |
Computes per-block “total difficulty” (block + eligible uncles) and uses it to choose confirmed blocks and proof blocks to send to the HSM. |
src/test/java/co/rsk/federate/signing/hsm/advanceblockchain/ConfirmedBlocksProviderTest.java |
Adjusts existing difficulty test to call the new API and adds coverage for ignoring uncles at/below the HSM best block height. |
src/main/java/co/rsk/federate/signing/hsm/message/AdvanceBlockchainMessage.java |
Uses Stream.toList() for parsed headers/brothers lists. |
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
src/main/java/co/rsk/federate/signing/hsm/advanceblockchain/ConfirmedBlocksProvider.java:75
- In getConfirmedBlocks(), you already select the first element with blocksInWindow.get(0) and then remove it via remove(confirmedBlock). Removing by index is clearer and avoids relying on Block.equals() semantics.
Block confirmedBlock = blocksInWindow.get(0);
confirmedBlocks.add(confirmedBlock);
BigInteger confirmedBlockTotalDifficulty = getBlockTotalDifficulty(confirmedBlock, initialBlockNumber);
accumulatedDifficulty = accumulatedDifficulty.subtract(confirmedBlockTotalDifficulty);
blocksInWindow.remove(confirmedBlock);
src/main/java/co/rsk/federate/signing/hsm/message/AdvanceBlockchainMessage.java:50
- groupBrothersByParentHash() uses confirmedBlocks.stream().skip(1) to drop the oldest block, but this relies on the caller providing the list in chronological order. Since parseHeadersAndBrothers() sorts internally, it’s safer to also sort here before skipping so the “oldest” block is unambiguous and brothers grouping doesn’t depend on input ordering.
private Map<Keccak256, List<BlockHeader>> groupBrothersByParentHash(List<Block> confirmedBlocks) {
return confirmedBlocks.stream()
.skip(1) // Skip the oldest block (index 0) because its uncles doesn't belong to this set of blocks
.flatMap(block -> block.getUncleList().stream())
.collect(Collectors.groupingBy(BlockHeader::getParentHash));
src/main/java/co/rsk/federate/signing/hsm/advanceblockchain/ConfirmedBlocksProvider.java:106
- getBlockTotalDifficulty() is a misleading name: it returns the capped difficulty of the block plus the capped difficulty of eligible uncles, not the chain/ledger “total difficulty” concept. This can lead to incorrect reuse elsewhere; consider renaming to something like getDifficultyToConsider/getCappedDifficultyIncludingEligibleUncles and update the trace message accordingly.
protected BigInteger getBlockTotalDifficulty(Block block, long uncleHeightThreshold) {
logger.trace(
"[getBlockTotalDifficulty] Get total difficulty for block {} at height {}",
block.getHash(),
block.getNumber()
);
BigInteger blockDifficulty = difficultyCap.min(block.getDifficulty().asBigInteger());



No description provided.