Coverage Summary for Class: SelectionRule (co.rsk.core.bc)
Class |
Class, %
|
Method, %
|
Line, %
|
SelectionRule |
100%
(1/1)
|
60%
(3/5)
|
50%
(13/26)
|
1 package co.rsk.core.bc;
2
3 import co.rsk.core.BlockDifficulty;
4 import co.rsk.core.Coin;
5 import co.rsk.remasc.Sibling;
6 import org.ethereum.core.Block;
7 import org.ethereum.core.BlockHeader;
8 import org.ethereum.util.FastByteComparisons;
9
10 import java.math.BigInteger;
11 import java.util.List;
12
13 public class SelectionRule {
14
15 private static final int BYTE_ARRAY_OFFSET = 0;
16 private static final int BYTE_ARRAY_LENGTH = 32;
17
18 private static final BigInteger PAID_FEES_MULTIPLIER_CRITERIA = BigInteger.valueOf(2);
19
20 public static boolean shouldWeAddThisBlock(
21 BlockDifficulty blockDifficulty,
22 BlockDifficulty currentDifficulty,
23 Block block,
24 Block currentBlock) {
25
26 int compareDifficulties = blockDifficulty.compareTo(currentDifficulty);
27
28 if (compareDifficulties > 0) {
29 return true;
30 }
31
32 if (compareDifficulties < 0) {
33 return false;
34 }
35
36 Coin pfm = currentBlock.getHeader().getPaidFees().multiply(PAID_FEES_MULTIPLIER_CRITERIA);
37 // fees over PAID_FEES_MULTIPLIER_CRITERIA times higher
38 if (block.getHeader().getPaidFees().compareTo(pfm) > 0) {
39 return true;
40 }
41
42 Coin blockFeesCriteria = block.getHeader().getPaidFees().multiply(PAID_FEES_MULTIPLIER_CRITERIA);
43
44 // As a last resort, choose the block with the lower hash. We ask that
45 // the fees are at least bigger than the half of current block.
46 return currentBlock.getHeader().getPaidFees().compareTo(blockFeesCriteria) < 0 &&
47 isThisBlockHashSmaller(block.getHash().getBytes(), currentBlock.getHash().getBytes());
48 }
49
50 public static boolean isBrokenSelectionRule(
51 BlockHeader processingBlockHeader, List<Sibling> siblings) {
52 int maxUncleCount = 0;
53 for (Sibling sibling : siblings) {
54 maxUncleCount = Math.max(maxUncleCount, sibling.getUncleCount());
55 Coin pfm = processingBlockHeader.getPaidFees().multiply(PAID_FEES_MULTIPLIER_CRITERIA);
56 if (sibling.getPaidFees().compareTo(pfm) > 0) {
57 return true;
58 }
59 Coin blockFeesCriteria = sibling.getPaidFees().multiply(PAID_FEES_MULTIPLIER_CRITERIA);
60 if (processingBlockHeader.getPaidFees().compareTo(blockFeesCriteria) < 0 &&
61 isThisBlockHashSmaller(sibling.getHash(), processingBlockHeader.getHash().getBytes())) {
62 return true;
63 }
64 }
65 return maxUncleCount > processingBlockHeader.getUncleCount();
66 }
67
68 public static boolean isThisBlockHashSmaller(byte[] thisBlockHash, byte[] compareBlockHash) {
69 return FastByteComparisons.compareTo(
70 thisBlockHash, BYTE_ARRAY_OFFSET, BYTE_ARRAY_LENGTH,
71 compareBlockHash, BYTE_ARRAY_OFFSET, BYTE_ARRAY_LENGTH) < 0;
72 }
73 }