From 9b0e88ca8753db1e16599c2ca388c587a01c494a Mon Sep 17 00:00:00 2001 From: catbref Date: Sat, 6 Feb 2021 11:40:29 +0000 Subject: [PATCH] Only compare same number of blocks when comparing peer chains --- src/main/java/org/qortal/block/Block.java | 5 ++-- .../java/org/qortal/block/BlockChain.java | 7 +++++- src/main/resources/blockchain.json | 3 ++- .../org/qortal/test/ChainWeightTests.java | 23 ++++++++++++++----- .../test-chain-v2-founder-rewards.json | 4 +++- .../test-chain-v2-leftover-reward.json | 4 +++- src/test/resources/test-chain-v2-minting.json | 4 +++- .../test-chain-v2-qora-holder-extremes.json | 4 +++- .../resources/test-chain-v2-qora-holder.json | 4 +++- .../test-chain-v2-reward-scaling.json | 4 +++- src/test/resources/test-chain-v2.json | 4 +++- 11 files changed, 48 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/qortal/block/Block.java b/src/main/java/org/qortal/block/Block.java index 7a2be548..ce7d220b 100644 --- a/src/main/java/org/qortal/block/Block.java +++ b/src/main/java/org/qortal/block/Block.java @@ -822,10 +822,9 @@ public class Block { parentHeight = blockSummaryData.getHeight(); parentBlockSignature = blockSummaryData.getSignature(); - /* Potential future consensus change: only comparing the same number of blocks. - if (parentHeight >= maxHeight) + // After this timestamp, we only compare the same number of blocks + if (NTP.getTime() >= BlockChain.getInstance().getCalcChainWeightTimestamp() && parentHeight >= maxHeight) break; - */ } return cumulativeWeight; diff --git a/src/main/java/org/qortal/block/BlockChain.java b/src/main/java/org/qortal/block/BlockChain.java index ad9140e3..43b19468 100644 --- a/src/main/java/org/qortal/block/BlockChain.java +++ b/src/main/java/org/qortal/block/BlockChain.java @@ -70,7 +70,8 @@ public class BlockChain { private GenesisBlock.GenesisInfo genesisInfo; public enum FeatureTrigger { - atFindNextTransactionFix; + atFindNextTransactionFix, + calcChainWeightTimestamp; } /** Map of which blockchain features are enabled when (height/timestamp) */ @@ -376,6 +377,10 @@ public class BlockChain { return this.featureTriggers.get(FeatureTrigger.atFindNextTransactionFix.name()).intValue(); } + public long getCalcChainWeightTimestamp() { + return this.featureTriggers.get(FeatureTrigger.calcChainWeightTimestamp.name()).longValue(); + } + // More complex getters for aspects that change by height or timestamp public long getRewardAtHeight(int ourHeight) { diff --git a/src/main/resources/blockchain.json b/src/main/resources/blockchain.json index 5b9a6202..17ffcf01 100644 --- a/src/main/resources/blockchain.json +++ b/src/main/resources/blockchain.json @@ -48,7 +48,8 @@ "minutesPerBlock": 1 }, "featureTriggers": { - "atFindNextTransactionFix": 275000 + "atFindNextTransactionFix": 275000, + "calcChainWeightTimestamp": 1616000000000, }, "genesisInfo": { "version": 4, diff --git a/src/test/java/org/qortal/test/ChainWeightTests.java b/src/test/java/org/qortal/test/ChainWeightTests.java index d133dad1..e53c4c8e 100644 --- a/src/test/java/org/qortal/test/ChainWeightTests.java +++ b/src/test/java/org/qortal/test/ChainWeightTests.java @@ -11,6 +11,7 @@ import java.util.Random; import org.qortal.account.Account; import org.qortal.block.Block; +import org.qortal.block.BlockChain; import org.qortal.data.block.BlockSummaryData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; @@ -19,7 +20,9 @@ import org.qortal.test.common.Common; import org.qortal.test.common.TestAccount; import org.qortal.transform.Transformer; import org.qortal.transform.block.BlockTransformer; +import org.qortal.utils.NTP; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; public class ChainWeightTests extends Common { @@ -27,6 +30,12 @@ public class ChainWeightTests extends Common { private static final Random RANDOM = new Random(); private static final NumberFormat FORMATTER = new DecimalFormat("0.###E0"); + @BeforeClass + public static void beforeClass() { + // We need this so that NTP.getTime() in Block.calcChainWeight() doesn't return null, causing NPE + NTP.setFixedOffset(0L); + } + @Before public void beforeTest() throws DataException { Common.useSettings("test-settings-v2-minting.json"); @@ -182,7 +191,7 @@ public class ChainWeightTests extends Common { return BigInteger.valueOf(blockSummaryData.getOnlineAccountsCount()).shiftLeft(accountsCountShift).add(keyDistance); } - // Check that a longer chain beats a shorter chain + // Check that a longer chain has same weight as shorter/truncated chain @Test public void testLongerChain() throws DataException { try (final Repository repository = RepositoryManager.getRepository()) { @@ -190,18 +199,20 @@ public class ChainWeightTests extends Common { BlockSummaryData commonBlockSummary = genBlockSummary(repository, commonBlockHeight); byte[] commonBlockGeneratorKey = commonBlockSummary.getMinterPublicKey(); - List shorterChain = genBlockSummaries(repository, 3, commonBlockSummary); - List longerChain = genBlockSummaries(repository, shorterChain.size() + 1, commonBlockSummary); - - populateBlockSummariesMinterLevels(repository, shorterChain); + List longerChain = genBlockSummaries(repository, 6, commonBlockSummary); populateBlockSummariesMinterLevels(repository, longerChain); + List shorterChain = longerChain.subList(0, longerChain.size() / 2); + final int mutualHeight = commonBlockHeight - 1 + Math.min(shorterChain.size(), longerChain.size()); BigInteger shorterChainWeight = Block.calcChainWeight(commonBlockHeight, commonBlockGeneratorKey, shorterChain, mutualHeight); BigInteger longerChainWeight = Block.calcChainWeight(commonBlockHeight, commonBlockGeneratorKey, longerChain, mutualHeight); - assertEquals("longer chain should have greater weight", 1, longerChainWeight.compareTo(shorterChainWeight)); + if (NTP.getTime() >= BlockChain.getInstance().getCalcChainWeightTimestamp()) + assertEquals("longer chain should have same weight", 0, longerChainWeight.compareTo(shorterChainWeight)); + else + assertEquals("longer chain should have greater weight", 1, longerChainWeight.compareTo(shorterChainWeight)); } } diff --git a/src/test/resources/test-chain-v2-founder-rewards.json b/src/test/resources/test-chain-v2-founder-rewards.json index 4ad21f35..6ffe946a 100644 --- a/src/test/resources/test-chain-v2-founder-rewards.json +++ b/src/test/resources/test-chain-v2-founder-rewards.json @@ -44,7 +44,9 @@ "powfixTimestamp": 0, "qortalTimestamp": 0, "newAssetPricingTimestamp": 0, - "groupApprovalTimestamp": 0 + "groupApprovalTimestamp": 0, + "atFindNextTransactionFix": 0, + "calcChainWeightTimestamp": 0 }, "genesisInfo": { "version": 4, diff --git a/src/test/resources/test-chain-v2-leftover-reward.json b/src/test/resources/test-chain-v2-leftover-reward.json index d402aa95..2cf6f2ab 100644 --- a/src/test/resources/test-chain-v2-leftover-reward.json +++ b/src/test/resources/test-chain-v2-leftover-reward.json @@ -44,7 +44,9 @@ "powfixTimestamp": 0, "qortalTimestamp": 0, "newAssetPricingTimestamp": 0, - "groupApprovalTimestamp": 0 + "groupApprovalTimestamp": 0, + "atFindNextTransactionFix": 0, + "calcChainWeightTimestamp": 0 }, "genesisInfo": { "version": 4, diff --git a/src/test/resources/test-chain-v2-minting.json b/src/test/resources/test-chain-v2-minting.json index 02b31ef9..4370f52b 100644 --- a/src/test/resources/test-chain-v2-minting.json +++ b/src/test/resources/test-chain-v2-minting.json @@ -44,7 +44,9 @@ "powfixTimestamp": 0, "qortalTimestamp": 0, "newAssetPricingTimestamp": 0, - "groupApprovalTimestamp": 0 + "groupApprovalTimestamp": 0, + "atFindNextTransactionFix": 0, + "calcChainWeightTimestamp": 0 }, "genesisInfo": { "version": 4, diff --git a/src/test/resources/test-chain-v2-qora-holder-extremes.json b/src/test/resources/test-chain-v2-qora-holder-extremes.json index 2962f7a7..1c0f0a7b 100644 --- a/src/test/resources/test-chain-v2-qora-holder-extremes.json +++ b/src/test/resources/test-chain-v2-qora-holder-extremes.json @@ -44,7 +44,9 @@ "powfixTimestamp": 0, "qortalTimestamp": 0, "newAssetPricingTimestamp": 0, - "groupApprovalTimestamp": 0 + "groupApprovalTimestamp": 0, + "atFindNextTransactionFix": 0, + "calcChainWeightTimestamp": 0 }, "genesisInfo": { "version": 4, diff --git a/src/test/resources/test-chain-v2-qora-holder.json b/src/test/resources/test-chain-v2-qora-holder.json index 11ccb0b0..ddb3cac9 100644 --- a/src/test/resources/test-chain-v2-qora-holder.json +++ b/src/test/resources/test-chain-v2-qora-holder.json @@ -44,7 +44,9 @@ "powfixTimestamp": 0, "qortalTimestamp": 0, "newAssetPricingTimestamp": 0, - "groupApprovalTimestamp": 0 + "groupApprovalTimestamp": 0, + "atFindNextTransactionFix": 0, + "calcChainWeightTimestamp": 0 }, "genesisInfo": { "version": 4, diff --git a/src/test/resources/test-chain-v2-reward-scaling.json b/src/test/resources/test-chain-v2-reward-scaling.json index e454d8e7..c588bc9f 100644 --- a/src/test/resources/test-chain-v2-reward-scaling.json +++ b/src/test/resources/test-chain-v2-reward-scaling.json @@ -44,7 +44,9 @@ "powfixTimestamp": 0, "qortalTimestamp": 0, "newAssetPricingTimestamp": 0, - "groupApprovalTimestamp": 0 + "groupApprovalTimestamp": 0, + "atFindNextTransactionFix": 0, + "calcChainWeightTimestamp": 0 }, "genesisInfo": { "version": 4, diff --git a/src/test/resources/test-chain-v2.json b/src/test/resources/test-chain-v2.json index 1939f357..e4f20209 100644 --- a/src/test/resources/test-chain-v2.json +++ b/src/test/resources/test-chain-v2.json @@ -44,7 +44,9 @@ "powfixTimestamp": 0, "qortalTimestamp": 0, "newAssetPricingTimestamp": 0, - "groupApprovalTimestamp": 0 + "groupApprovalTimestamp": 0, + "atFindNextTransactionFix": 0, + "calcChainWeightTimestamp": 0 }, "genesisInfo": { "version": 4,