diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeConstants.java index cc0f248ff88..5d59b76ad1c 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeConstants.java @@ -46,6 +46,7 @@ public abstract class BridgeConstants { protected Coin minimumPegoutTxValueInSatoshis; protected long federationActivationAge; + protected long federationActivationAgeLegacy; protected long fundsMigrationAgeSinceActivationBegin; protected long fundsMigrationAgeSinceActivationEnd; @@ -119,8 +120,8 @@ public int getRsk2BtcMinimumAcceptableConfirmations() { public Coin getMinimumPegoutTxValueInSatoshis() { return minimumPegoutTxValueInSatoshis; } - public long getFederationActivationAge() { - return federationActivationAge; + public long getFederationActivationAge(ActivationConfig.ForBlock activations) { + return activations.isActive(ConsensusRule.RSKIP383)? federationActivationAge: federationActivationAgeLegacy; } public long getFundsMigrationAgeSinceActivationBegin() { diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeDevNetConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeDevNetConstants.java index 6b34969f453..4646b261172 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeDevNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeDevNetConstants.java @@ -104,7 +104,8 @@ public BridgeDevNetConstants(List federationPublicKeys) { AddressBasedAuthorizer.MinimumRequiredCalculation.ONE ); - federationActivationAge = 10L; + federationActivationAgeLegacy = 10L; + federationActivationAge = 20L; fundsMigrationAgeSinceActivationBegin = 15L; fundsMigrationAgeSinceActivationEnd = 100L; diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java index 5acdaef2d3d..4d631af5ae4 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java @@ -93,7 +93,8 @@ public class BridgeMainNetConstants extends BridgeConstants { AddressBasedAuthorizer.MinimumRequiredCalculation.ONE ); - federationActivationAge = 18500L; + federationActivationAgeLegacy = 18500L; + federationActivationAge = 40320L; fundsMigrationAgeSinceActivationBegin = 0L; fundsMigrationAgeSinceActivationEnd = 10585L; diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeRegTestConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeRegTestConstants.java index c3258c4e3b3..f7ce7aa7669 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeRegTestConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeRegTestConstants.java @@ -90,7 +90,8 @@ public BridgeRegTestConstants(List federationPublicKeys) { AddressBasedAuthorizer.MinimumRequiredCalculation.MAJORITY ); - federationActivationAge = 10L; + federationActivationAgeLegacy = 10L; + federationActivationAge = 20L; fundsMigrationAgeSinceActivationBegin = 15L; fundsMigrationAgeSinceActivationEnd = 150L; diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java index 649ef3211ae..93a09a1b003 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java @@ -103,7 +103,8 @@ public class BridgeTestNetConstants extends BridgeConstants { AddressBasedAuthorizer.MinimumRequiredCalculation.ONE ); - federationActivationAge = 60L; + federationActivationAgeLegacy = 60L; + federationActivationAge = 120L; fundsMigrationAgeSinceActivationBegin = 60L; fundsMigrationAgeSinceActivationEnd = 900L; diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java index 1d98d19b3ed..077ac14f34c 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -998,7 +998,7 @@ private void processFundsMigration(Transaction rskTx) throws IOException { } private boolean federationIsInMigrationAge(Federation federation) { - long federationActivationAge = bridgeConstants.getFederationActivationAge(); + long federationActivationAge = bridgeConstants.getFederationActivationAge(activations); long federationAge = rskExecutionBlock.getNumber() - federation.getCreationBlockNumber(); long ageBegin = federationActivationAge + bridgeConstants.getFundsMigrationAgeSinceActivationBegin(); long ageEnd = federationActivationAge + bridgeConstants.getFundsMigrationAgeSinceActivationEnd(activations); @@ -1008,7 +1008,7 @@ private boolean federationIsInMigrationAge(Federation federation) { private boolean federationIsPastMigrationAge(Federation federation) { long federationAge = rskExecutionBlock.getNumber() - federation.getCreationBlockNumber(); - long ageEnd = bridgeConstants.getFederationActivationAge() + + long ageEnd = bridgeConstants.getFederationActivationAge(activations) + bridgeConstants.getFundsMigrationAgeSinceActivationEnd(activations); return federationAge >= ageEnd; @@ -1327,7 +1327,7 @@ private void updateFederationCreationBlockHeights() { long nextFederationCreationBlockHeight = nextFederationCreationBlockHeightOpt.get(); long curBlockHeight = rskExecutionBlock.getNumber(); - if (curBlockHeight >= nextFederationCreationBlockHeight + bridgeConstants.getFederationActivationAge()) { + if (curBlockHeight >= nextFederationCreationBlockHeight + bridgeConstants.getFederationActivationAge(activations)) { provider.setActiveFederationCreationBlockHeight(nextFederationCreationBlockHeight); provider.clearNextFederationCreationBlockHeight(); } @@ -2678,7 +2678,7 @@ public long getActiveFederationCreationBlockHeight() { if (nextFederationCreationBlockHeightOpt.isPresent()) { long nextFederationCreationBlockHeight = nextFederationCreationBlockHeightOpt.get(); long curBlockHeight = rskExecutionBlock.getNumber(); - if (curBlockHeight >= nextFederationCreationBlockHeight + bridgeConstants.getFederationActivationAge()) { + if (curBlockHeight >= nextFederationCreationBlockHeight + bridgeConstants.getFederationActivationAge(activations)) { return nextFederationCreationBlockHeight; } } diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java index f0c7e65b7ea..dcc9b9b8235 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java @@ -67,7 +67,7 @@ public BridgeSupport newInstance(Repository repository, Block executionBlock, activations ); - FederationSupport federationSupport = new FederationSupport(bridgeConstants, provider, executionBlock); + FederationSupport federationSupport = new FederationSupport(bridgeConstants, provider, executionBlock, activations); BridgeEventLogger eventLogger; if (logs == null) { diff --git a/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java b/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java index 98d9fea0f53..ea657d14fd5 100644 --- a/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java @@ -20,6 +20,7 @@ import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.UTXO; import co.rsk.config.BridgeConstants; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.core.Block; import javax.annotation.Nullable; @@ -34,11 +35,13 @@ private enum StorageFederationReference { NONE, NEW, OLD, GENESIS } private final BridgeStorageProvider provider; private final BridgeConstants bridgeConstants; private final Block executionBlock; + private final ActivationConfig.ForBlock activations; - public FederationSupport(BridgeConstants bridgeConstants, BridgeStorageProvider provider, Block executionBlock) { + public FederationSupport(BridgeConstants bridgeConstants, BridgeStorageProvider provider, Block executionBlock, ActivationConfig.ForBlock activations) { this.provider = provider; this.bridgeConstants = bridgeConstants; this.executionBlock = executionBlock; + this.activations = activations; } /** @@ -226,6 +229,6 @@ private StorageFederationReference getRetiringFederationReference() { private boolean shouldFederationBeActive(Federation federation) { long federationAge = executionBlock.getNumber() - federation.getCreationBlockNumber(); - return federationAge >= bridgeConstants.getFederationActivationAge(); + return federationAge >= bridgeConstants.getFederationActivationAge(activations); } } diff --git a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java index 3da68488d93..ae59b2617df 100644 --- a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java @@ -106,7 +106,7 @@ public void logCommitFederation(Block executionBlock, Federation oldFederation, String oldFederationBtcAddress = oldFederation.getAddress().toBase58(); byte[] newFederationFlatPubKeys = flatKeysAsByteArray(newFederation.getBtcPublicKeys()); String newFederationBtcAddress = newFederation.getAddress().toBase58(); - long newFedActivationBlockNumber = executionBlock.getNumber() + this.bridgeConstants.getFederationActivationAge(); + long newFedActivationBlockNumber = executionBlock.getNumber() + this.bridgeConstants.getFederationActivationAge(activations); CallTransaction.Function event = BridgeEvents.COMMIT_FEDERATION.getEvent(); byte[][] encodedTopicsInBytes = event.encodeEventTopics(); diff --git a/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java b/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java index 1fc1ecdc380..81d521ea1cb 100644 --- a/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java @@ -119,7 +119,7 @@ public void logCommitFederation(Block executionBlock, Federation oldFederation, byte[] newFedFlatPubKeys = flatKeysAsRlpCollection(newFederation.getBtcPublicKeys()); byte[] newFedData = RLP.encodeList(RLP.encodeElement(newFederation.getAddress().getHash160()), RLP.encodeList(newFedFlatPubKeys)); - long newFedActivationBlockNumber = executionBlock.getNumber() + this.bridgeConstants.getFederationActivationAge(); + long newFedActivationBlockNumber = executionBlock.getNumber() + this.bridgeConstants.getFederationActivationAge(activations); byte[] data = RLP.encodeList(oldFedData, newFedData, RLP.encodeString(Long.toString(newFedActivationBlockNumber))); diff --git a/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java b/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java index 7b582e41aa0..ae5c8fcc37b 100644 --- a/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java +++ b/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java @@ -38,13 +38,15 @@ public RemascFederationProvider( BridgeConstants bridgeConstants, Repository repository, Block processingBlock) { + + ActivationConfig.ForBlock activations = activationConfig.forBlock(processingBlock.getNumber()); BridgeStorageProvider bridgeStorageProvider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants, - activationConfig.forBlock(processingBlock.getNumber()) + activations ); - this.federationSupport = new FederationSupport(bridgeConstants, bridgeStorageProvider, processingBlock); + this.federationSupport = new FederationSupport(bridgeConstants, bridgeStorageProvider, processingBlock, activations); } public int getFederationSize() { diff --git a/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java b/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java index e456d3dcd63..4c9216ca398 100644 --- a/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java +++ b/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java @@ -83,6 +83,7 @@ public enum ConsensusRule { RSKIP374("rskip374"), RSKIP375("rskip375"), RSKIP377("rskip377"), + RSKIP383("rskip383"), RSKIP385("rskip385"), ; diff --git a/rskj-core/src/main/resources/expected.conf b/rskj-core/src/main/resources/expected.conf index 6f8e50452ce..a4347efdabd 100644 --- a/rskj-core/src/main/resources/expected.conf +++ b/rskj-core/src/main/resources/expected.conf @@ -81,6 +81,7 @@ blockchain = { rskip374 = rskip375 = rskip377 = + rskip383 = rskip385 = } } diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index 9d3819a9f69..bd03f37cb4a 100644 --- a/rskj-core/src/main/resources/reference.conf +++ b/rskj-core/src/main/resources/reference.conf @@ -69,6 +69,7 @@ blockchain = { rskip374 = fingerroot500 rskip375 = fingerroot500 rskip377 = fingerroot500 + rskip383 = fingerroot500 rskip385 = fingerroot500 } } diff --git a/rskj-core/src/test/java/co/rsk/config/BridgeConstantsTest.java b/rskj-core/src/test/java/co/rsk/config/BridgeConstantsTest.java index d8c4e606735..b61385cd019 100644 --- a/rskj-core/src/test/java/co/rsk/config/BridgeConstantsTest.java +++ b/rskj-core/src/test/java/co/rsk/config/BridgeConstantsTest.java @@ -13,8 +13,7 @@ import static org.mockito.Mockito.when; class BridgeConstantsTest { - - private static Stream generator() { + private static Stream fundsMigrationAgeSinceActivationEndArgsProvider() { return Stream.of( Arguments.of(BridgeMainNetConstants.getInstance(), false), Arguments.of(BridgeTestNetConstants.getInstance(), true), @@ -23,8 +22,8 @@ private static Stream generator() { } @ParameterizedTest() - @MethodSource("generator") - void test_getFundsMigrationAgeSinceActivationEnd(BridgeConstants bridgeConstants, boolean hasSameValueForBothMigrationAges) { + @MethodSource("fundsMigrationAgeSinceActivationEndArgsProvider") + void test_getFundsMigrationAgeSinceActivationEnd(BridgeConstants bridgeConstants, boolean hasSameValueForBothFields) { // Arrange ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); @@ -33,11 +32,11 @@ void test_getFundsMigrationAgeSinceActivationEnd(BridgeConstants bridgeConstants // assert assertEquals(fundsMigrationAgeSinceActivationEnd, bridgeConstants.fundsMigrationAgeSinceActivationEnd); - assertEquals(hasSameValueForBothMigrationAges, fundsMigrationAgeSinceActivationEnd == bridgeConstants.specialCaseFundsMigrationAgeSinceActivationEnd); + assertEquals(hasSameValueForBothFields, fundsMigrationAgeSinceActivationEnd == bridgeConstants.specialCaseFundsMigrationAgeSinceActivationEnd); } @ParameterizedTest() - @MethodSource("generator") + @MethodSource("fundsMigrationAgeSinceActivationEndArgsProvider") void test_getFundsMigrationAgeSinceActivationEnd_post_RSKIP357(BridgeConstants bridgeConstants, boolean hasSameValueForBothMigrationAges) { // Arrange ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); @@ -52,7 +51,7 @@ void test_getFundsMigrationAgeSinceActivationEnd_post_RSKIP357(BridgeConstants b } @ParameterizedTest() - @MethodSource("generator") + @MethodSource("fundsMigrationAgeSinceActivationEndArgsProvider") void test_getFundsMigrationAgeSinceActivationEnd_post_RSKIP374(BridgeConstants bridgeConstants, boolean hasSameValueForBothMigrationAges) { // Arrange ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); @@ -66,4 +65,32 @@ void test_getFundsMigrationAgeSinceActivationEnd_post_RSKIP374(BridgeConstants b assertEquals(fundsMigrationAgeSinceActivationEnd, bridgeConstants.fundsMigrationAgeSinceActivationEnd); assertEquals(hasSameValueForBothMigrationAges, fundsMigrationAgeSinceActivationEnd == bridgeConstants.specialCaseFundsMigrationAgeSinceActivationEnd); } + + private static Stream federationActivationAgeArgProvider() { + return Stream.of( + Arguments.of(BridgeMainNetConstants.getInstance(), false), + Arguments.of(BridgeTestNetConstants.getInstance(), false), + Arguments.of(BridgeRegTestConstants.getInstance(), false), + Arguments.of(BridgeMainNetConstants.getInstance(), true), + Arguments.of(BridgeTestNetConstants.getInstance(), true), + Arguments.of(BridgeRegTestConstants.getInstance(), true) + ); + } + + @ParameterizedTest() + @MethodSource("federationActivationAgeArgProvider") + void test_getFederationActivationAge(BridgeConstants bridgeConstants, boolean isRSKIP383Active) { + // Arrange + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + when(activations.isActive(ConsensusRule.RSKIP383)).thenReturn(isRSKIP383Active); + // Act + long federationActivationAge = bridgeConstants.getFederationActivationAge(activations); + + // assert + if (isRSKIP383Active){ + assertEquals(bridgeConstants.federationActivationAge, federationActivationAge); + } else { + assertEquals(bridgeConstants.federationActivationAgeLegacy, federationActivationAge); + } + } } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportFlyoverTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportFlyoverTest.java index 0b666ce114b..183c14fe378 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportFlyoverTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportFlyoverTest.java @@ -117,7 +117,7 @@ private BigInteger sendFundsToActiveFederation( // For the sake of simplicity, this set the fed activation age value equal to the value in the bridgeRegTestConstants // in order to be able to always get the current retiring federation when it's been mock with no need of creating // unnecessary blocks when testing on mainnet. - doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge()).when(bridgeConstants).getFederationActivationAge(); + doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge(activations)).when(bridgeConstants).getFederationActivationAge(activations); Context btcContext = mock(Context.class); doReturn(bridgeConstants.getBtcParams()).when(btcContext).getParams(); @@ -259,7 +259,7 @@ private BigInteger sendFundsToRetiringFederation( // For the sake of simplicity, this set the fed activation age value equal to the value in the bridgeRegTestConstants // in order to be able to always get the current retiring federation when it's been mock with no need of creating // unnecessary blocks when testing on mainnet. - doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge()).when(bridgeConstants).getFederationActivationAge(); + doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge(activations)).when(bridgeConstants).getFederationActivationAge(activations); Context btcContext = mock(Context.class); doReturn(bridgeConstants.getBtcParams()).when(btcContext).getParams(); @@ -403,7 +403,7 @@ private BigInteger sendFundsToActiveAndRetiringFederation( // For the sake of simplicity, this set the fed activation age value equal to the value in the bridgeRegTestConstants // in order to be able to always get the current retiring federation when it's been mock with no need of creating // unnecessary blocks when testing on mainnet. - doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge()).when(bridgeConstants).getFederationActivationAge(); + doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge(activations)).when(bridgeConstants).getFederationActivationAge(activations); Context btcContext = mock(Context.class); doReturn(bridgeConstants.getBtcParams()).when(btcContext).getParams(); @@ -571,7 +571,7 @@ private BigInteger sendFundsToAnyAddress( // For the sake of simplicity, this set the fed activation age value equal to the value in the bridgeRegTestConstants // in order to be able to always get the current retiring federation when it's been mock with no need of creating // unnecessary blocks when testing on mainnet. - doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge()).when(bridgeConstants).getFederationActivationAge(); + doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge(activations)).when(bridgeConstants).getFederationActivationAge(activations); Context btcContext = mock(Context.class); doReturn(bridgeConstants.getBtcParams()).when(btcContext).getParams(); @@ -1607,7 +1607,7 @@ void registerFlyoverBtcTransaction_failed_when_tx_with_witness_already_saved_in_ // For the sake of simplicity, this set the fed activation age value equal to the value in the bridgeRegTestConstants // in order to be able to always get the current retiring federation when it's been mock with no need of creating // unnecessary blocks when testing on mainnet. - doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge()).when(bridgeConstants).getFederationActivationAge(); + doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge(activations)).when(bridgeConstants).getFederationActivationAge(activations); Context btcContext = mock(Context.class); doReturn(bridgeConstants.getBtcParams()).when(btcContext).getParams(); @@ -1791,7 +1791,7 @@ void registerFlyoverBtcTransaction_failed_when_tx_with_witness_surpassing_lockin // For the sake of simplicity, this set the fed activation age value equal to the value in the bridgeRegTestConstants // in order to be able to always get the current retiring federation when it's been mock with no need of creating // unnecessary blocks when testing on mainnet. - doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge()).when(bridgeConstants).getFederationActivationAge(); + doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge(activations)).when(bridgeConstants).getFederationActivationAge(activations); Context btcContext = mock(Context.class); doReturn(bridgeConstants.getBtcParams()).when(btcContext).getParams(); @@ -1985,7 +1985,7 @@ void registerFlyoverBtcTransaction_failed_when_tx_with_witness_surpassing_lockin // For the sake of simplicity, this set the fed activation age value equal to the value in the bridgeRegTestConstants // in order to be able to always get the current retiring federation when it's been mock with no need of creating // unnecessary blocks when testing on mainnet. - doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge()).when(bridgeConstants).getFederationActivationAge(); + doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge(activations)).when(bridgeConstants).getFederationActivationAge(activations); Context btcContext = mock(Context.class); doReturn(bridgeConstants.getBtcParams()).when(btcContext).getParams(); @@ -2179,7 +2179,7 @@ void registerFlyoverBtcTransaction_failed_when_tx_without_witness_surpassing_loc // For the sake of simplicity, this set the fed activation age value equal to the value in the bridgeRegTestConstants // in order to be able to always get the current retiring federation when it's been mock with no need of creating // unnecessary blocks when testing on mainnet. - doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge()).when(bridgeConstants).getFederationActivationAge(); + doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge(activations)).when(bridgeConstants).getFederationActivationAge(activations); Context btcContext = mock(Context.class); doReturn(bridgeConstants.getBtcParams()).when(btcContext).getParams(); @@ -2346,7 +2346,7 @@ void registerFlyoverBtcTransaction_failed_when_tx_without_witness_surpassing_loc // For the sake of simplicity, this set the fed activation age value equal to the value in the bridgeRegTestConstants // in order to be able to always get the current retiring federation when it's been mock with no need of creating // unnecessary blocks when testing on mainnet. - doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge()).when(bridgeConstants).getFederationActivationAge(); + doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge(activations)).when(bridgeConstants).getFederationActivationAge(activations); Context btcContext = mock(Context.class); doReturn(bridgeConstants.getBtcParams()).when(btcContext).getParams(); @@ -2528,7 +2528,7 @@ void registerFlyoverBtcTransaction_failed_when_tx_without_witness_already_saved_ // For the sake of simplicity, this set the fed activation age value equal to the value in the bridgeRegTestConstants // in order to be able to always get the current retiring federation when it's been mock with no need of creating // unnecessary blocks when testing on mainnet. - doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge()).when(bridgeConstants).getFederationActivationAge(); + doReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge(activations)).when(bridgeConstants).getFederationActivationAge(activations); Context btcContext = mock(Context.class); doReturn(bridgeConstants.getBtcParams()).when(btcContext).getParams(); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportProcessFundsMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportProcessFundsMigrationTest.java index 062ef64b2af..17df5e2533f 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportProcessFundsMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportProcessFundsMigrationTest.java @@ -16,6 +16,9 @@ import org.ethereum.core.Transaction; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import java.io.IOException; import java.math.BigInteger; @@ -23,157 +26,84 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.function.Function; +import java.util.stream.Stream; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; class BridgeSupportProcessFundsMigrationTest { - @Test - void processFundsMigration_in_migration_age_before_rskip_146_activation_testnet() throws IOException { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(false); - when(activations.isActive(ConsensusRule.RSKIP357)).thenReturn(false); - when(activations.isActive(ConsensusRule.RSKIP374)).thenReturn(false); - test_processFundsMigration(BridgeTestNetConstants.getInstance(), activations, true); - } - - @Test - void processFundsMigration_in_migration_age_after_rskip_146_activation_testnet() throws IOException { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP357)).thenReturn(false); - when(activations.isActive(ConsensusRule.RSKIP374)).thenReturn(false); - test_processFundsMigration(BridgeTestNetConstants.getInstance(), activations, true); - } - - @Test - void processFundsMigration_in_migration_age_after_rskip_357_activation_testnet() throws IOException { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP357)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP374)).thenReturn(false); - test_processFundsMigration(BridgeTestNetConstants.getInstance(), activations, true); - } - - @Test - void processFundsMigration_in_migration_age_after_rskip_374_activation_testnet() throws IOException { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP357)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP374)).thenReturn(true); - test_processFundsMigration(BridgeTestNetConstants.getInstance(), activations, true); - } - - @Test - void processFundsMigration_past_migration_age_before_rskip_146_activation_testnet() throws IOException { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(false); - when(activations.isActive(ConsensusRule.RSKIP357)).thenReturn(false); - when(activations.isActive(ConsensusRule.RSKIP374)).thenReturn(false); - test_processFundsMigration(BridgeTestNetConstants.getInstance(), activations, false); - } - - @Test - void processFundsMigration_past_migration_age_after_rskip_146_activation_testnet() throws IOException { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP357)).thenReturn(false); - when(activations.isActive(ConsensusRule.RSKIP374)).thenReturn(false); - test_processFundsMigration(BridgeTestNetConstants.getInstance(), activations, false); - } - - @Test - void processFundsMigration_past_migration_age_after_rskip_357_activation_testnet() throws IOException { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP357)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP374)).thenReturn(false); - test_processFundsMigration(BridgeTestNetConstants.getInstance(), activations, false); - } - - @Test - void processFundsMigration_past_migration_age_after_rskip_374_activation_testnet() throws IOException { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP357)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP374)).thenReturn(true); - test_processFundsMigration(BridgeTestNetConstants.getInstance(), activations, false); - } + private static Stream processFundMigrationArgsProvider() { + BridgeMainNetConstants bridgeMainNetConstants = BridgeMainNetConstants.getInstance(); + BridgeTestNetConstants bridgeTestNetConstants = BridgeTestNetConstants.getInstance(); - @Test - void processFundsMigration_in_migration_age_before_rskip_146_activation_mainnet() throws IOException { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(false); - when(activations.isActive(ConsensusRule.RSKIP357)).thenReturn(false); - when(activations.isActive(ConsensusRule.RSKIP374)).thenReturn(false); - test_processFundsMigration(BridgeMainNetConstants.getInstance(), activations, true); - } + ActivationConfig.ForBlock activationsBeforeRSKIP146 = mock(ActivationConfig.ForBlock.class); - @Test - void processFundsMigration_in_migration_age_after_rskip_146_activation_mainnet() throws IOException { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP357)).thenReturn(false); - when(activations.isActive(ConsensusRule.RSKIP374)).thenReturn(false); - test_processFundsMigration(BridgeMainNetConstants.getInstance(), activations, true); - } + Stream beforeRskip146Tests = Stream.of( + Arguments.of(bridgeTestNetConstants, activationsBeforeRSKIP146, false), + Arguments.of(bridgeTestNetConstants, activationsBeforeRSKIP146, true), + Arguments.of(bridgeMainNetConstants, activationsBeforeRSKIP146, false), + Arguments.of(bridgeMainNetConstants, activationsBeforeRSKIP146, true) + ); - @Test - void processFundsMigration_in_migration_age_after_rskip_357_activation_mainnet() throws IOException { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP357)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP374)).thenReturn(false); - test_processFundsMigration(BridgeMainNetConstants.getInstance(), activations, true); - } + ActivationConfig.ForBlock activationsAfterRSKIP146 = mock(ActivationConfig.ForBlock.class); + when(activationsAfterRSKIP146.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - @Test - void processFundsMigration_in_migration_age_after_rskip_374_activation_mainnet() throws IOException { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP357)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP374)).thenReturn(true); - test_processFundsMigration(BridgeMainNetConstants.getInstance(), activations, true); - } + Stream afterRskip146Tests = Stream.of( + Arguments.of(bridgeTestNetConstants, activationsAfterRSKIP146, false), + Arguments.of(bridgeTestNetConstants, activationsAfterRSKIP146, true), + Arguments.of(bridgeMainNetConstants, activationsAfterRSKIP146, false), + Arguments.of(bridgeMainNetConstants, activationsAfterRSKIP146, true) + ); - @Test - void processFundsMigration_past_migration_age_before_rskip_146_activation_mainnet() throws IOException { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(false); - when(activations.isActive(ConsensusRule.RSKIP357)).thenReturn(false); - when(activations.isActive(ConsensusRule.RSKIP374)).thenReturn(false); - test_processFundsMigration(BridgeMainNetConstants.getInstance(), activations, false); - } + ActivationConfig.ForBlock activationsAfterRSKIP357 = mock(ActivationConfig.ForBlock.class); + when(activationsAfterRSKIP357.isActive(ConsensusRule.RSKIP146)).thenReturn(true); + when(activationsAfterRSKIP357.isActive(ConsensusRule.RSKIP357)).thenReturn(true); - @Test - void processFundsMigration_past_migration_age_after_rskip_146_activation_mainnet() throws IOException { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP357)).thenReturn(false); - when(activations.isActive(ConsensusRule.RSKIP374)).thenReturn(false); - test_processFundsMigration(BridgeMainNetConstants.getInstance(), activations, false); - } + Stream afterRskip357Tests = Stream.of( + Arguments.of(bridgeTestNetConstants, activationsAfterRSKIP357, false), + Arguments.of(bridgeTestNetConstants, activationsAfterRSKIP357, true), + Arguments.of(bridgeMainNetConstants, activationsAfterRSKIP357, false), + Arguments.of(bridgeMainNetConstants, activationsAfterRSKIP357, true) + ); - @Test - void processFundsMigration_past_migration_age_after_rskip_357_activation_mainnet() throws IOException { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP357)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP374)).thenReturn(false); - test_processFundsMigration(BridgeMainNetConstants.getInstance(), activations, false); - } + ActivationConfig.ForBlock activationsAfterRSKIP374 = mock(ActivationConfig.ForBlock.class); + when(activationsAfterRSKIP374.isActive(ConsensusRule.RSKIP146)).thenReturn(true); + when(activationsAfterRSKIP374.isActive(ConsensusRule.RSKIP357)).thenReturn(true); + when(activationsAfterRSKIP374.isActive(ConsensusRule.RSKIP374)).thenReturn(true); - @Test - void processFundsMigration_past_migration_age_after_rskip_374_activation_mainnet() throws IOException { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP357)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP374)).thenReturn(true); - test_processFundsMigration(BridgeMainNetConstants.getInstance(), activations, false); - } + Stream afterRskip374Tests = Stream.of( + Arguments.of(bridgeTestNetConstants, activationsAfterRSKIP374, false), + Arguments.of(bridgeTestNetConstants, activationsAfterRSKIP374, true), + Arguments.of(bridgeMainNetConstants, activationsAfterRSKIP374, false), + Arguments.of(bridgeMainNetConstants, activationsAfterRSKIP374, true) + ); - private void test_processFundsMigration( + ActivationConfig.ForBlock activationsAfterRSKIP383 = mock(ActivationConfig.ForBlock.class); + when(activationsAfterRSKIP383.isActive(ConsensusRule.RSKIP146)).thenReturn(true); + when(activationsAfterRSKIP383.isActive(ConsensusRule.RSKIP357)).thenReturn(true); + when(activationsAfterRSKIP383.isActive(ConsensusRule.RSKIP374)).thenReturn(true); + when(activationsAfterRSKIP383.isActive(ConsensusRule.RSKIP383)).thenReturn(true); + + Stream afterRskip383Tests = Stream.of( + Arguments.of(bridgeTestNetConstants, activationsAfterRSKIP383, false), + Arguments.of(bridgeTestNetConstants, activationsAfterRSKIP383, true), + Arguments.of(bridgeMainNetConstants, activationsAfterRSKIP383, false), + Arguments.of(bridgeMainNetConstants, activationsAfterRSKIP383, true) + ); + return Stream.of( + beforeRskip146Tests, + afterRskip146Tests, + afterRskip357Tests, + afterRskip374Tests, + afterRskip383Tests + ).flatMap(Function.identity()); + } + + @ParameterizedTest + @MethodSource("processFundMigrationArgsProvider") + void test_processFundsMigration( BridgeConstants bridgeConstants, ActivationConfig.ForBlock activations, boolean inMigrationAge @@ -181,13 +111,13 @@ private void test_processFundsMigration( BridgeEventLogger bridgeEventLogger = mock(BridgeEventLogger.class); Federation oldFederation = bridgeConstants.getGenesisFederation(); + long federationActivationAge = bridgeConstants.getFederationActivationAge(activations); long federationCreationBlockNumber = 5L; - long federationInMigrationAgeHeight = federationCreationBlockNumber + - bridgeConstants.getFederationActivationAge() + + long federationInMigrationAgeHeight = federationCreationBlockNumber + federationActivationAge + bridgeConstants.getFundsMigrationAgeSinceActivationBegin() + 1; long federationPastMigrationAgeHeight = federationCreationBlockNumber + - bridgeConstants.getFederationActivationAge() + + federationActivationAge + bridgeConstants.getFundsMigrationAgeSinceActivationEnd(activations) + 1; Federation newFederation = new Federation( @@ -229,7 +159,14 @@ private void test_processFundsMigration( bridgeSupport.updateCollections(updateCollectionsTx); Assertions.assertEquals(activations.isActive(ConsensusRule.RSKIP146)? 0 : 1, provider.getPegoutsWaitingForConfirmations().getEntriesWithoutHash().size()); - Assertions.assertEquals(activations.isActive(ConsensusRule.RSKIP146) ? 1 : 0, provider.getPegoutsWaitingForConfirmations().getEntriesWithHash().size()); + Assertions.assertEquals(activations.isActive(ConsensusRule.RSKIP146)? 1 : 0, provider.getPegoutsWaitingForConfirmations().getEntriesWithHash().size()); + + Assertions.assertTrue(sufficientUTXOsForMigration.isEmpty()); + if (inMigrationAge){ + verify(provider, never()).setOldFederation(null); + } else { + verify(provider, times(1)).setOldFederation(null); + } if (activations.isActive(ConsensusRule.RSKIP146)) { // Should have been logged with the migrated UTXO diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java index c8a444a596e..58aa3961e41 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java @@ -2109,6 +2109,7 @@ void rskTxWaitingForSignature_uses_updateCollection_rskTxHash_after_rskip_176_ac private static Stream provideBridgeConstants() { return Stream.of(BridgeRegTestConstants.getInstance(), BridgeTestNetConstants.getInstance(), BridgeMainNetConstants.getInstance()); } + @ParameterizedTest @MethodSource("provideBridgeConstants") void rskTxWaitingForSignature_uses_pegoutCreation_rskTxHash_after_rskip_375_activation(BridgeConstants bridgeConstants) throws IOException { @@ -6677,7 +6678,7 @@ private void test_migrating_many_utxos(boolean isRskip294Active, int utxosToCrea Block block = mock(Block.class); // Set block right after the migration should start long blockNumber = newFed.getCreationBlockNumber() + - bridgeConstantsRegtest.getFederationActivationAge() + + bridgeConstantsRegtest.getFederationActivationAge(activations) + bridgeConstantsRegtest.getFundsMigrationAgeSinceActivationBegin() + 1; when(block.getNumber()).thenReturn(blockNumber); @@ -7382,7 +7383,7 @@ private BridgeSupport getBridgeSupport(BridgeConstants constants, BridgeStorageP track, executionBlock, new Context(constants.getBtcParams()), - new FederationSupport(constants, provider, executionBlock), + new FederationSupport(constants, provider, executionBlock, activations), blockStoreFactory, activations, signatureCache diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java index ff962ebb191..2cc6482e2d9 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java @@ -227,7 +227,7 @@ void testGetBtcBlockchainBlockLocatorWithBtcCheckpoints() throws Exception { track, null, new Context(bridgeConstants.getBtcParams()), - new FederationSupport(bridgeConstants, provider, null), + new FederationSupport(bridgeConstants, provider, null, activationsBeforeForks), btcBlockStoreFactory, mock(ActivationConfig.ForBlock.class), signatureCache @@ -3750,8 +3750,9 @@ private BridgeSupport getBridgeSupportWithMocksForFederationTests( when(constantsMock.getBtcParams()).thenReturn(NetworkParameters.fromID(NetworkParameters.ID_REGTEST)); when(constantsMock.getFederationChangeAuthorizer()).thenReturn(bridgeConstants.getFederationChangeAuthorizer()); - long federationActivationAge = bridgeConstants.getFederationActivationAge(); - when(constantsMock.getFederationActivationAge()).thenReturn(federationActivationAge); + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + long federationActivationAge = bridgeConstants.getFederationActivationAge(activations); + when(constantsMock.getFederationActivationAge(any())).thenReturn(federationActivationAge); class FederationHolder { private PendingFederation pendingFederation; @@ -3968,7 +3969,7 @@ private BridgeSupport getBridgeSupport( track, executionBlock, new Context(constants.getBtcParams()), - new FederationSupport(constants, provider, executionBlock), + new FederationSupport(constants, provider, executionBlock, activations), blockStoreFactory, activations, signatureCache diff --git a/rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java b/rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java index bde6a2a362d..42d49ae32b4 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java @@ -20,17 +20,25 @@ import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.config.BridgeConstants; +import co.rsk.config.BridgeMainNetConstants; +import co.rsk.config.BridgeTestNetConstants; import org.bouncycastle.util.encoders.Hex; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.core.Block; import org.ethereum.crypto.ECKey; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import java.time.Instant; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.stream.Stream; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -43,18 +51,20 @@ class FederationSupportTest { private BridgeConstants bridgeConstants; private BridgeStorageProvider provider; private Block executionBlock; - + private ActivationConfig.ForBlock activations; @BeforeEach void setUp() { provider = mock(BridgeStorageProvider.class); bridgeConstants = mock(BridgeConstants.class); executionBlock = mock(Block.class); + activations = mock(ActivationConfig.ForBlock.class); federationSupport = new FederationSupport( bridgeConstants, provider, - executionBlock + executionBlock, + activations ); } @@ -80,30 +90,69 @@ void whenOldFederationIsNullThenActiveFederationIsNewFederation() { assertThat(federationSupport.getActiveFederation(), is(newFederation)); } - @Test - void whenOldAndNewFederationArePresentReturnOldFederationByActivationAge() { - Federation newFederation = getNewFakeFederation(75); - Federation oldFederation = getNewFakeFederation(0); + private static Stream fedActivationAgeTestArgs() { + BridgeConstants bridgeTestNetConstants = BridgeTestNetConstants.getInstance(); + BridgeConstants bridgeMainnetConstants = BridgeMainNetConstants.getInstance(); + ActivationConfig.ForBlock hopActivations = ActivationConfigsForTest.hop400().forBlock(0); + ActivationConfig.ForBlock fingerrootActivations = ActivationConfigsForTest.fingerroot500().forBlock(0); + + return Stream.of( + Arguments.of(bridgeTestNetConstants, hopActivations, false), + Arguments.of(bridgeTestNetConstants, hopActivations, true), + Arguments.of(bridgeTestNetConstants, fingerrootActivations, false), + Arguments.of(bridgeTestNetConstants, fingerrootActivations, true), + Arguments.of(bridgeMainnetConstants, hopActivations, false), + Arguments.of(bridgeMainnetConstants, hopActivations, true), + Arguments.of(bridgeMainnetConstants, fingerrootActivations, false), + Arguments.of(bridgeMainnetConstants, fingerrootActivations, true) + ); + } - when(provider.getNewFederation()).thenReturn(newFederation); - when(provider.getOldFederation()).thenReturn(oldFederation); - when(executionBlock.getNumber()).thenReturn(80L); - when(bridgeConstants.getFederationActivationAge()).thenReturn(10L); - assertThat(federationSupport.getActiveFederation(), is(oldFederation)); - } + @ParameterizedTest + @MethodSource("fedActivationAgeTestArgs") + void whenOldAndNewFederationArePresentReturnActiveFederationByActivationAge( + BridgeConstants bridgeConstants, + ActivationConfig.ForBlock activations, + boolean newFedExpectedToBeActive + ) { + int newFedCreationBlockNumber = 65; + int oldFedCreationBlockNumber = 0; + long currentBlockNumber = newFedCreationBlockNumber + bridgeConstants.getFederationActivationAge(activations); + + if (newFedExpectedToBeActive) { + currentBlockNumber++; + } else { + currentBlockNumber--; + } - @Test - void whenOldAndNewFederationArePresentReturnNewFederationByActivationAge() { - Federation newFederation = getNewFakeFederation(65); - Federation oldFederation = getNewFakeFederation(0); + // Arrange + Federation newFederation = getNewFakeFederation(newFedCreationBlockNumber); + Federation oldFederation = getNewFakeFederation(oldFedCreationBlockNumber); + BridgeStorageProvider provider = mock(BridgeStorageProvider.class); when(provider.getNewFederation()).thenReturn(newFederation); when(provider.getOldFederation()).thenReturn(oldFederation); - when(executionBlock.getNumber()).thenReturn(80L); - when(bridgeConstants.getFederationActivationAge()).thenReturn(10L); - assertThat(federationSupport.getActiveFederation(), is(newFederation)); + Block executionBlock = mock(Block.class); + when(executionBlock.getNumber()).thenReturn(currentBlockNumber); + + FederationSupport federationSupport = new FederationSupport( + bridgeConstants, + provider, + executionBlock, + activations + ); + + // Act + Federation activeFederation = federationSupport.getActiveFederation(); + + // Assert + if (newFedExpectedToBeActive){ + assertThat(activeFederation, is(newFederation)); + } else { + assertThat(activeFederation, is(oldFederation)); + } } @Test diff --git a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java index a757b06b79d..72c3a7c38a9 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java @@ -30,8 +30,8 @@ import org.ethereum.util.ByteUtil; import org.ethereum.vm.PrecompiledContracts; import org.ethereum.vm.program.InternalTransaction; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; import org.mockito.ArgumentCaptor; import java.io.IOException; @@ -275,13 +275,39 @@ private void testChangePowpeg( /* Activation phase */ - // Move the required blocks ahead for the new powpeg to become active // (overriding block number to ensure we don't move beyond the activation phase) - blockNumber = initialBlock.getNumber() + bridgeConstants.getFederationActivationAge(); + blockNumber = initialBlock.getNumber() + bridgeConstants.getFederationActivationAge(activations); Block activationBlock = mock(Block.class); doReturn(blockNumber).when(activationBlock).getNumber(); + // assuming fed activation age after rskip383 is greater than legacy fed activation age, we can check that new fed + // should not be active at the legacy activation age when RSKIP383 is active + if (activations.isActive(ConsensusRule.RSKIP383)){ + ActivationConfig.ForBlock activationsBeforeRSKIP383 = mock(ActivationConfig.ForBlock.class); + when(activationsBeforeRSKIP383.isActive(ConsensusRule.RSKIP383)).thenReturn(false); + + long legacyFedActivationBlockNumber = initialBlock.getNumber() + bridgeConstants.getFederationActivationAge(activationsBeforeRSKIP383); + Assertions.assertTrue(blockNumber > legacyFedActivationBlockNumber); + + Block legacyFedActivationBlock = mock(Block.class); + doReturn(legacyFedActivationBlockNumber).when(legacyFedActivationBlock).getNumber(); + + bridgeSupport = new BridgeSupportBuilder() + .withProvider(bridgeStorageProvider) + .withRepository(repository) + .withEventLogger(bridgeEventLogger) + .withExecutionBlock(legacyFedActivationBlock) + .withActivations(activations) + .withBridgeConstants(bridgeConstants) + .withBtcBlockStoreFactory(btcBlockStoreFactory) + .withPeginInstructionsProvider(new PeginInstructionsProvider()) + .build(); + + assertEquals(oldPowPegAddress, bridgeSupport.getFederationAddress()); + assertNull(bridgeSupport.getRetiringFederation()); + } + bridgeSupport = new BridgeSupportBuilder() .withProvider(bridgeStorageProvider) .withRepository(repository) diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java index 733e9faf91f..7876cc65a4e 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java @@ -34,6 +34,8 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import java.math.BigInteger; import java.time.Instant; @@ -44,6 +46,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -200,8 +203,10 @@ void logReleaseBtc() { assertEvent(eventLogs, 0, BridgeEvents.RELEASE_BTC.getEvent(), new Object[]{rskTxHash.getBytes()}, new Object[]{btcTx.bitcoinSerialize()}); } - @Test - void logCommitFederation() { + @ParameterizedTest + @ValueSource(booleans = {false, true}) + void logCommitFederation(boolean isRSKIP383Active) { + when(activations.isActive(ConsensusRule.RSKIP383)).thenReturn(isRSKIP383Active); // Setup parameters for test method call Block executionBlock = mock(Block.class); when(executionBlock.getTimestamp()).thenReturn(15005L); @@ -249,7 +254,8 @@ void logCommitFederation() { String oldFederationBtcAddress = oldFederation.getAddress().toBase58(); byte[] newFederationFlatPubKeys = flatKeysAsByteArray(newFederation.getBtcPublicKeys()); String newFederationBtcAddress = newFederation.getAddress().toBase58(); - long newFedActivationBlockNumber = executionBlock.getNumber() + CONSTANTS.getFederationActivationAge(); + long newFedActivationBlockNumber = executionBlock.getNumber() + CONSTANTS.getFederationActivationAge(activations); + Object[] data = new Object[]{ oldFederationFlatPubKeys, oldFederationBtcAddress, @@ -257,7 +263,32 @@ void logCommitFederation() { newFederationBtcAddress, newFedActivationBlockNumber }; - assertEvent(eventLogs, 0, BridgeEvents.COMMIT_FEDERATION.getEvent(), new Object[]{}, data); + + CallTransaction.Function event = BridgeEvents.COMMIT_FEDERATION.getEvent(); + Object[] topics = {}; + assertEvent(eventLogs, 0, event, topics, data); + + final LogInfo log = eventLogs.get(0); + Object[] decodeEventData = event.decodeEventData(log.getData()); + long loggedFedActivationBlockNumber = ((BigInteger) decodeEventData[4]).longValue(); + + assertEquals(loggedFedActivationBlockNumber, newFedActivationBlockNumber); + + // assert fed activation has different values before and after RSKIP383 respectively + if (isRSKIP383Active){ + ActivationConfig.ForBlock activationsForLegacyFedActivationAge = mock(ActivationConfig.ForBlock.class); + when(activationsForLegacyFedActivationAge.isActive(ConsensusRule.RSKIP383)).thenReturn(false); + + long legacyFedActivationBlockNumber = executionBlock.getNumber() + CONSTANTS.getFederationActivationAge(activationsForLegacyFedActivationAge); + + assertNotEquals(loggedFedActivationBlockNumber, legacyFedActivationBlockNumber); + } else { + ActivationConfig.ForBlock activationsForDefaultFedActivationAge = mock(ActivationConfig.ForBlock.class); + when(activationsForDefaultFedActivationAge.isActive(ConsensusRule.RSKIP383)).thenReturn(true); + + long defaultFedActivationBlockNumber = executionBlock.getNumber() + CONSTANTS.getFederationActivationAge(activationsForDefaultFedActivationAge); + assertNotEquals(loggedFedActivationBlockNumber, defaultFedActivationBlockNumber); + } } @Test diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java index f85ff6e6be0..ea3473dfe26 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java @@ -45,6 +45,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -105,7 +106,7 @@ void testLogUpdateCollectionsBeforeRskip146() { void testLogUpdateCollectionsAfterRskip146() { when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); Transaction anyTx = any(); - Assertions.assertThrows(DeprecatedMethodCallException.class, () -> eventLogger.logUpdateCollections(anyTx)); + assertThrows(DeprecatedMethodCallException.class, () -> eventLogger.logUpdateCollections(anyTx)); } @Test @@ -147,7 +148,7 @@ void testLogAddSignatureAfterRskip146() { when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); BtcECKey federatorPublicKey = new BtcECKey(); byte[] bytes = rskTxHash.getBytes(); - Assertions.assertThrows(DeprecatedMethodCallException.class, () -> eventLogger.logAddSignature(federatorPublicKey, btcTxMock, bytes)); + assertThrows(DeprecatedMethodCallException.class, () -> eventLogger.logAddSignature(federatorPublicKey, btcTxMock, bytes)); } @Test @@ -185,7 +186,7 @@ void testLogReleaseBtcAfterRskip146() { // Act byte[] bytes = rskTxHash.getBytes(); - Assertions.assertThrows(DeprecatedMethodCallException.class, () -> eventLogger.logReleaseBtc(btcTxMock, bytes)); + assertThrows(DeprecatedMethodCallException.class, () -> eventLogger.logReleaseBtc(btcTxMock, bytes)); } @Test @@ -269,7 +270,7 @@ void testLogCommitFederationBeforeRskip146() { } // Assert new federation activation block number - Assertions.assertEquals(15L + constantsMock.getFederationActivationAge(), Long.valueOf(new String(dataList.get(2).getRLPData(), StandardCharsets.UTF_8)).longValue()); + Assertions.assertEquals(15L + constantsMock.getFederationActivationAge(activations), Long.valueOf(new String(dataList.get(2).getRLPData(), StandardCharsets.UTF_8)).longValue()); } @Test @@ -278,7 +279,7 @@ void testLogCommitFederationAfterRskip146() { when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); // Act - Assertions.assertThrows(DeprecatedMethodCallException.class, () -> eventLogger.logCommitFederation(mock(Block.class), mock(Federation.class), mock(Federation.class))); + assertThrows(DeprecatedMethodCallException.class, () -> eventLogger.logCommitFederation(mock(Block.class), mock(Federation.class), mock(Federation.class))); } /********************************** diff --git a/rskj-core/src/test/java/co/rsk/test/builders/BridgeSupportBuilder.java b/rskj-core/src/test/java/co/rsk/test/builders/BridgeSupportBuilder.java index 65dc5402c77..0bc09cb56a7 100644 --- a/rskj-core/src/test/java/co/rsk/test/builders/BridgeSupportBuilder.java +++ b/rskj-core/src/test/java/co/rsk/test/builders/BridgeSupportBuilder.java @@ -99,7 +99,7 @@ public BridgeSupport build() { repository, executionBlock, new Context(bridgeConstants.getBtcParams()), - new FederationSupport(bridgeConstants, provider, executionBlock), + new FederationSupport(bridgeConstants, provider, executionBlock, activations), btcBlockStoreFactory, activations, signatureCache diff --git a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigTest.java b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigTest.java index d934d44ddf0..b96f8064fc2 100644 --- a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigTest.java +++ b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigTest.java @@ -108,6 +108,7 @@ class ActivationConfigTest { " rskip374: fingerroot500", " rskip375: fingerroot500", " rskip377: fingerroot500", + " rskip383: fingerroot500", " rskip385: fingerroot500", "}" )); diff --git a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java index f865a918975..277347a45bb 100644 --- a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java +++ b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java @@ -167,7 +167,8 @@ private static List getFingerroot500Rskips() { ConsensusRule.RSKIP326, ConsensusRule.RSKIP374, ConsensusRule.RSKIP375, - ConsensusRule.RSKIP377 + ConsensusRule.RSKIP377, + ConsensusRule.RSKIP383 )); return rskips;