diff --git a/rskj-core/src/main/java/co/rsk/peg/PegUtils.java b/rskj-core/src/main/java/co/rsk/peg/PegUtils.java index 1827ff38b09..ab534322e96 100644 --- a/rskj-core/src/main/java/co/rsk/peg/PegUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/PegUtils.java @@ -44,7 +44,7 @@ static PegTxType getTransactionTypeUsingPegoutIndex( List liveFederationOutputs = btcTransaction.getWalletOutputs(liveFederationsWallet); Optional inputSigHash = BitcoinUtils.getSigHashForPegoutIndex(btcTransaction); - if (inputSigHash.isPresent() && provider.hasPegoutTxSigHash(inputSigHash.get())){ + if (inputSigHash.isPresent() && provider.hasPegoutTxSigHash(inputSigHash.get())) { return PegTxType.PEGOUT_OR_MIGRATION; } else if (!liveFederationOutputs.isEmpty()){ return PegTxType.PEGIN; @@ -143,18 +143,6 @@ private static boolean isPegoutTxIndexEnabled( btcTransactionHeight >= heightAtWhichToStartUsingPegoutIndex; } - private static boolean isFederationsPendingBtcUTXOsEnabled( - BridgeConstants bridgeConstants, - ActivationConfig.ForBlock activations, - long btcTransactionHeight - ) { - int btcHeightWhenFederationsPendingBtcUTXOsActivates = bridgeConstants.getBtcHeightWhenFederationsPendingBtcUTXOsActivates(); - int gracePeriodInBtcBlocks = bridgeConstants.getPegoutTxIndexGracePeriodInBtcBlocks(); - int heightAtWhichToStartUsingFederationsPendingBtcUTXOs = btcHeightWhenFederationsPendingBtcUTXOsActivates + gracePeriodInBtcBlocks; - return activations.isActive(ConsensusRule.RSKIP643) && - btcTransactionHeight >= heightAtWhichToStartUsingFederationsPendingBtcUTXOs; - } - private static boolean isTheSvpFundTransaction( BridgeStorageProvider provider, ActivationConfig.ForBlock activations, diff --git a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeConstants.java b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeConstants.java index e95346d27ef..1e1b0d51650 100644 --- a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeConstants.java @@ -72,7 +72,6 @@ public abstract class BridgeConstants { protected int btcHeightWhenPegoutTxIndexActivates; protected int pegoutTxIndexGracePeriodInBtcBlocks; - protected int btcHeightWhenFederationsPendingBtcUTXOsActivates; protected int blockWithTooMuchChainWorkHeight; public NetworkParameters getBtcParams() { @@ -154,9 +153,5 @@ public int getPegoutTxIndexGracePeriodInBtcBlocks() { return pegoutTxIndexGracePeriodInBtcBlocks; } - public int getBtcHeightWhenFederationsPendingBtcUTXOsActivates() { - return btcHeightWhenFederationsPendingBtcUTXOsActivates; - } - public int getBlockWithTooMuchChainWorkHeight() { return blockWithTooMuchChainWorkHeight; } } diff --git a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeMainNetConstants.java b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeMainNetConstants.java index 540619b3304..68207e1e49d 100644 --- a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeMainNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeMainNetConstants.java @@ -48,8 +48,6 @@ private BridgeMainNetConstants() { btcHeightWhenPegoutTxIndexActivates = 837_589; // Estimated date Wed, 03 Apr 2024 15:00:00 GMT. 832,430 was the block number at time of calculation pegoutTxIndexGracePeriodInBtcBlocks = THIRTY_DAYS_IN_BTC_BLOCKS; - // TODO: estimate the BTC height for the RSKIP643 activation date once it is scheduled - btcHeightWhenFederationsPendingBtcUTXOsActivates = 10_000_000; blockWithTooMuchChainWorkHeight = 849_138; } diff --git a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeRegTestConstants.java b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeRegTestConstants.java index d84bc752323..6792592521b 100644 --- a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeRegTestConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeRegTestConstants.java @@ -83,8 +83,6 @@ public BridgeRegTestConstants(List federationPublicKeys) { btcHeightWhenPegoutTxIndexActivates = 250; pegoutTxIndexGracePeriodInBtcBlocks = 100; - // TODO: estimate the BTC height for the RSKIP643 activation date once it is scheduled - btcHeightWhenFederationsPendingBtcUTXOsActivates = btcHeightWhenPegoutTxIndexActivates + 10; blockWithTooMuchChainWorkHeight = Integer.MAX_VALUE; } diff --git a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeTestNet2Constants.java b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeTestNet2Constants.java index ec010621ea4..c42c0171248 100644 --- a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeTestNet2Constants.java +++ b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeTestNet2Constants.java @@ -73,8 +73,6 @@ public class BridgeTestNet2Constants extends BridgeConstants { // Pegout tx index active since genesis btcHeightWhenPegoutTxIndexActivates = 0; pegoutTxIndexGracePeriodInBtcBlocks = 0; - // TODO: estimate the BTC height for the RSKIP643 activation date once it is scheduled - btcHeightWhenFederationsPendingBtcUTXOsActivates = 10_000_000; blockWithTooMuchChainWorkHeight = Integer.MAX_VALUE; } diff --git a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeTestNetConstants.java b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeTestNetConstants.java index 65f3737792c..724f9883a52 100644 --- a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeTestNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeTestNetConstants.java @@ -66,8 +66,6 @@ public class BridgeTestNetConstants extends BridgeConstants { btcHeightWhenPegoutTxIndexActivates = 2_589_553; // Estimated date Wed, 20 Mar 2024 15:00:00 GMT. 2,579,823 was the block number at time of calculation pegoutTxIndexGracePeriodInBtcBlocks = 1_440; // 10 days in BTC blocks (considering 1 block every 10 minutes) - // TODO: estimate the BTC height for the RSKIP643 activation date once it is scheduled - btcHeightWhenFederationsPendingBtcUTXOsActivates = 10_000_000; blockWithTooMuchChainWorkHeight = Integer.MAX_VALUE; } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java index 604728af23c..785fa947f8a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java @@ -89,6 +89,8 @@ class BridgeSupportRegisterBtcTransactionTest { private static final int BTC_HEIGHT_WHEN_PEGOUT_TX_INDEX_ACTIVATES = bridgeMainnetConstants.getBtcHeightWhenPegoutTxIndexActivates(); private static final int PEGOUT_TX_INDEX_GRACE_PERIOD_IN_BTC_BLOCKS = bridgeMainnetConstants.getPegoutTxIndexGracePeriodInBtcBlocks(); private static final int HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX = BTC_HEIGHT_WHEN_PEGOUT_TX_INDEX_ACTIVATES + PEGOUT_TX_INDEX_GRACE_PERIOD_IN_BTC_BLOCKS; + private static final int BTC_BLOCKS_BETWEEN_PEGOUT_INDEX_AND_FEDERATIONS_PENDING_BTC_UTXOS = 100; + private static final int HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS = HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + BTC_BLOCKS_BETWEEN_PEGOUT_INDEX_AND_FEDERATIONS_PENDING_BTC_UTXOS; private static final int HEIGHT_BEFORE_USING_PEGOUT_INDEX = 1; private static final int UTXO_HEIGHT_BEFORE_CARDAMOM = 0; private static final Address userAddress = BitcoinTestUtils.createP2PKHAddress(btcMainnetParams, "userAddress"); @@ -3059,7 +3061,7 @@ void registerBtcTransaction_withNoChangeOutput_forReed_withRetiringFed_withSegwi registerPegoutTxSigHash(btcTransaction); // act - registerReleaseTransaction(btcTransaction); + registerReleaseTransaction(btcTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); // assert assertReleaseTxWasProcessedWithNoNewUtxo(btcTransaction); @@ -3073,7 +3075,7 @@ void registerBtcTransaction_withNoChangeOutput_withoutRetiringFed_withSegwitActi registerPegoutTxSigHash(btcTransaction); // act - registerReleaseTransaction(btcTransaction); + registerReleaseTransaction(btcTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); // assert assertReleaseTxWasProcessedWithNoNewUtxo(btcTransaction); @@ -3087,7 +3089,7 @@ void registerBtcTransaction_withNoChangeOutput_withoutRetiringFed_withSegwitActi // with no output sent to the live federations, no federations pending utxos are saved // act - registerReleaseTransaction(btcTransaction); + registerReleaseTransaction(btcTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); // assert assertReleaseTxWasNotProcessed(btcTransaction); @@ -3129,7 +3131,7 @@ void registerBtcTransaction_notInPegoutTxIndexWithChangeOutputFromFederation_wit BtcTransaction btcTransaction = getPegoutTxWithOneInputAndOutputWithChange(); // act - registerReleaseTransaction(btcTransaction); + registerReleaseTransaction(btcTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); // assert assertLogRejectedPegin(logs, btcTransaction, LEGACY_PEGIN_MULTISIG_SENDER); @@ -3157,7 +3159,7 @@ void registerBtcTransaction_notInPegoutTxIndexWithChangeOutputFromFederation_wit BtcTransaction btcTransaction = getPegoutTxWithOneInputAndOutputWithChange(); // act - registerReleaseTransaction(btcTransaction); + registerReleaseTransaction(btcTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); // assert assertLogRejectedPegin(logs, btcTransaction, LEGACY_PEGIN_MULTISIG_SENDER); @@ -3296,7 +3298,7 @@ void registerBtcTransaction_withManyOutputsAndInputsAndChangeOutput_forReed_with registerPegoutTxSigHash(btcTransaction); // act - registerReleaseTransaction(btcTransaction); + registerReleaseTransaction(btcTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( @@ -3315,7 +3317,7 @@ void registerBtcTransaction_withManyOutputsAndInputsAndChangeOutput_withRetiring registerPegoutTxSigHash(btcTransaction); // act - registerReleaseTransaction(btcTransaction); + registerReleaseTransaction(btcTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( @@ -3334,19 +3336,38 @@ void registerBtcTransaction_withManyOutputsAndInputsAndChangeOutput_withRetiring registerPegoutTxInFederationsPendingBtcUtxos(btcTransaction); // act - registerReleaseTransaction(btcTransaction); + registerReleaseTransaction(btcTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( btcTransaction, activeFederation, - HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); assertPegoutWithChangeWasProcessed(btcTransaction, expectedUtxosRegistered); assertLogUtxosRegisteredForPegoutChange(btcTransaction); assertNotPendingUtxos(btcTransaction); } + @Test + void registerBtcTransaction_withManyOutputsAndInputsAndChangeOutput_withoutRetiringFed_withSegwitActiveFed_forVetiver_shouldRegisterPegoutTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { + // arrange + setupSegwitActiveFed(vetiver900Activations); + BtcTransaction btcTransaction = getPegoutTxWithManyOutputsAndInputsWithChangeOutput(); + registerPegoutTxSigHash(btcTransaction); + + // act + registerReleaseTransaction(btcTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); + + // assert + List expectedUtxosRegistered = buildExpectedUtxosRegistered( + btcTransaction, + activeFederation, + UTXO_HEIGHT_BEFORE_CARDAMOM + ); + assertPegoutWithChangeWasProcessed(btcTransaction, expectedUtxosRegistered); + } + @Test void registerBtcTransaction_withManyOutputsAndInputsAndChangeOutput_withoutRetiringFed_withSegwitActiveFed_shouldRegisterPegoutTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange @@ -3355,13 +3376,13 @@ void registerBtcTransaction_withManyOutputsAndInputsAndChangeOutput_withoutRetir registerPegoutTxInFederationsPendingBtcUtxos(btcTransaction); // act - registerReleaseTransaction(btcTransaction); + registerReleaseTransaction(btcTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( btcTransaction, activeFederation, - HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); assertPegoutWithChangeWasProcessed(btcTransaction, expectedUtxosRegistered); assertLogUtxosRegisteredForPegoutChange(btcTransaction); @@ -3486,7 +3507,7 @@ void registerBtcTransaction_withManyOutputsAndOneInputAndChangeOutput_forReed_wi registerPegoutTxSigHash(btcTransaction); // act - registerReleaseTransaction(btcTransaction); + registerReleaseTransaction(btcTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( @@ -3498,6 +3519,25 @@ void registerBtcTransaction_withManyOutputsAndOneInputAndChangeOutput_forReed_wi assertUtxosRegisteredWasNotEmitted(); } + @Test + void registerBtcTransaction_withManyOutputsAndOneInputAndChangeOutput_withRetiringFed_withSegwitActiveFed_forVetiver_shouldRegisterPegoutTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { + // arrange + setupSegwitActiveAndSegwitRetiringFeds(vetiver900Activations); + BtcTransaction btcTransaction = getPegoutTxWithManyOutputsAndOneInputWithChangeOutput(); + registerPegoutTxSigHash(btcTransaction); + + // act + registerReleaseTransaction(btcTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); + + // assert + List expectedUtxosRegistered = buildExpectedUtxosRegistered( + btcTransaction, + activeFederation, + UTXO_HEIGHT_BEFORE_CARDAMOM + ); + assertPegoutWithChangeWasProcessed(btcTransaction, expectedUtxosRegistered); + } + @Test void registerBtcTransaction_withManyOutputsAndOneInputAndChangeOutput_withRetiringFed_withSegwitActiveFed_shouldRegisterPegoutTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange @@ -3506,19 +3546,38 @@ void registerBtcTransaction_withManyOutputsAndOneInputAndChangeOutput_withRetiri registerPegoutTxInFederationsPendingBtcUtxos(btcTransaction); // act - registerReleaseTransaction(btcTransaction); + registerReleaseTransaction(btcTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( btcTransaction, activeFederation, - HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); assertPegoutWithChangeWasProcessed(btcTransaction, expectedUtxosRegistered); assertLogUtxosRegisteredForPegoutChange(btcTransaction); assertNotPendingUtxos(btcTransaction); } + @Test + void registerBtcTransaction_withManyOutputsAndOneInputAndChangeOutput_withoutRetiringFed_withSegwitActiveFed_forVetiver_shouldRegisterPegoutTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { + // arrange + setupSegwitActiveFed(vetiver900Activations); + BtcTransaction btcTransaction = getPegoutTxWithManyOutputsAndOneInputWithChangeOutput(); + registerPegoutTxSigHash(btcTransaction); + + // act + registerReleaseTransaction(btcTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); + + // assert + List expectedUtxosRegistered = buildExpectedUtxosRegistered( + btcTransaction, + activeFederation, + UTXO_HEIGHT_BEFORE_CARDAMOM + ); + assertPegoutWithChangeWasProcessed(btcTransaction, expectedUtxosRegistered); + } + @Test void registerBtcTransaction_withManyOutputsAndOneInputAndChangeOutput_withoutRetiringFed_withSegwitActiveFed_shouldRegisterPegoutTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange @@ -3527,13 +3586,13 @@ void registerBtcTransaction_withManyOutputsAndOneInputAndChangeOutput_withoutRet registerPegoutTxInFederationsPendingBtcUtxos(btcTransaction); // act - registerReleaseTransaction(btcTransaction); + registerReleaseTransaction(btcTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( btcTransaction, activeFederation, - HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); assertPegoutWithChangeWasProcessed(btcTransaction, expectedUtxosRegistered); assertLogUtxosRegisteredForPegoutChange(btcTransaction); @@ -3628,7 +3687,21 @@ void registerBtcTransaction_withNoChangeOutputAndManyInputs_forReed_withRetiring // act registerPegoutTxSigHash(btcTransaction); - registerReleaseTransaction(btcTransaction); + registerReleaseTransaction(btcTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); + + // assert + assertReleaseTxWasProcessedWithNoNewUtxo(btcTransaction); + } + + @Test + void registerBtcTransaction_withNoChangeOutputAndManyInputs_withRetiringFed_withSegwitActiveFed_forVetiver_shouldRegisterPegoutTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { + // arrange + setupSegwitActiveAndSegwitRetiringFeds(vetiver900Activations); + BtcTransaction btcTransaction = getPegoutTxWithOneOutputAndManyInputsWithoutChange(); + registerPegoutTxSigHash(btcTransaction); + + // act + registerReleaseTransaction(btcTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); // assert assertReleaseTxWasProcessedWithNoNewUtxo(btcTransaction); @@ -3642,13 +3715,27 @@ void registerBtcTransaction_withNoChangeOutputAndManyInputs_withRetiringFed_with // act // with no output sent to the live federations, no federations pending utxos are saved - registerReleaseTransaction(btcTransaction); + registerReleaseTransaction(btcTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); // assert assertReleaseTxWasNotProcessed(btcTransaction); assertUtxosRegisteredWasNotEmitted(); } + @Test + void registerBtcTransaction_withNoChangeOutputAndManyInputs_withoutRetiringFed_withSegwitActiveFed_forVetiver_shouldRegisterPegoutTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { + // arrange + setupSegwitActiveFed(vetiver900Activations); + BtcTransaction btcTransaction = getPegoutTxWithOneOutputAndManyInputsWithoutChange(); + registerPegoutTxSigHash(btcTransaction); + + // act + registerReleaseTransaction(btcTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); + + // assert + assertReleaseTxWasProcessedWithNoNewUtxo(btcTransaction); + } + @Test void registerBtcTransaction_withNoChangeOutputAndManyInputs_withoutRetiringFed_withSegwitActiveFed_shouldNotRegisterPegoutTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange @@ -3657,7 +3744,7 @@ void registerBtcTransaction_withNoChangeOutputAndManyInputs_withoutRetiringFed_w // act // with no output sent to the live federations, no federations pending utxos are saved - registerReleaseTransaction(btcTransaction); + registerReleaseTransaction(btcTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); // assert assertReleaseTxWasNotProcessed(btcTransaction); @@ -3759,6 +3846,16 @@ class MigrationTransaction { private static final int MANY_MIGRATION_UTXOS = 40; private static final int OLD_FEDERATION_MIGRATION_HEIGHT = 5; + // registerReleaseTransaction needs a witness-bearing tx, so the retired fed must be segwit + private Federation buildSegwitRetiredFed() { + return P2shP2wshErpFederationBuilder.builder() + .withNetworkParameters(btcMainnetParams) + .withMembersBtcPublicKeys(retiredFedSigners) + .withErpActivationDelay(activationDelay) + .withErpPublicKeys(erpPubKeys) + .build(); + } + @Test void registerBtcTransaction_withOneInputAndOutput_forFingerroot_shouldRegisterMigrationTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange @@ -3858,7 +3955,7 @@ void registerBtcTransaction_withOneInputAndOutput_withSegwitActiveAndRetiringFed // act registerPegoutTxSigHash(migrationTx); - registerReleaseTransaction(migrationTx); + registerReleaseTransaction(migrationTx, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( @@ -3881,13 +3978,13 @@ void registerBtcTransaction_withOneInputAndOutput_withSegwitActiveAndRetiringFed registerPegoutTxInFederationsPendingBtcUtxos(migrationTx); // act - registerReleaseTransaction(migrationTx); + registerReleaseTransaction(migrationTx, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( migrationTx, activeFederation, - HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); assertMigrationTxWasProcessed( migrationTx, @@ -4047,7 +4144,7 @@ void registerBtcTransaction_withManyOutputsAndInputs_withSegwitActiveAndRetiring // act registerPegoutTxSigHash(migrationTx); - registerReleaseTransaction(migrationTx); + registerReleaseTransaction(migrationTx, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( @@ -4070,13 +4167,13 @@ void registerBtcTransaction_withManyOutputsAndInputs_withSegwitActiveAndRetiring registerPegoutTxInFederationsPendingBtcUtxos(migrationTx); // act - registerReleaseTransaction(migrationTx); + registerReleaseTransaction(migrationTx, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( migrationTx, activeFederation, - HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); assertMigrationTxWasProcessed( migrationTx, @@ -4178,6 +4275,29 @@ void registerBtcTransaction_withManyOutputsAndOneInput_forReed_withSegwitActiveF assertUtxosRegisteredWasNotEmitted(); } + @Test + void registerBtcTransaction_withManyOutputsAndOneInput_withSegwitActiveAndRetiringFeds_forVetiver_shouldRegisterMigrationTxUtxosWithZeroHeight() throws BlockStoreException, BridgeIllegalArgumentException, IOException { + // arrange + setupSegwitActiveAndSegwitRetiringFeds(vetiver900Activations); + BtcTransaction migrationTx = getMigrationTxWithManyOutputsAndOneInput(); + registerPegoutTxSigHash(migrationTx); + + // act + registerReleaseTransaction(migrationTx, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); + + // assert + List expectedUtxosRegistered = buildExpectedUtxosRegistered( + migrationTx, + activeFederation, + UTXO_HEIGHT_BEFORE_CARDAMOM + ); + assertMigrationTxWasProcessed( + migrationTx, + MANY_MIGRATION_UTXOS, + expectedUtxosRegistered + ); + } + @Test void registerBtcTransaction_withManyOutputsAndOneInput_withSegwitActiveAndRetiringFeds_shouldRegisterMigrationTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange @@ -4186,13 +4306,13 @@ void registerBtcTransaction_withManyOutputsAndOneInput_withSegwitActiveAndRetiri registerPegoutTxInFederationsPendingBtcUtxos(migrationTx); // act - registerReleaseTransaction(migrationTx); + registerReleaseTransaction(migrationTx, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( migrationTx, activeFederation, - HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); assertMigrationTxWasProcessed( migrationTx, @@ -4294,6 +4414,29 @@ void registerBtcTransaction_withOneOutputAndManyInputs_forReed_withSegwitActiveF assertUtxosRegisteredWasNotEmitted(); } + @Test + void registerBtcTransaction_withOneOutputAndManyInputs_withSegwitActiveAndRetiringFeds_forVetiver_shouldRegisterMigrationTxUtxosWithZeroHeight() throws BlockStoreException, BridgeIllegalArgumentException, IOException { + // arrange + setupSegwitActiveAndSegwitRetiringFeds(vetiver900Activations); + BtcTransaction migrationTx = getMigrationTxWithOneOutputAndManyInputs(); + registerPegoutTxSigHash(migrationTx); + + // act + registerReleaseTransaction(migrationTx, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); + + // assert + List expectedUtxosRegistered = buildExpectedUtxosRegistered( + migrationTx, + activeFederation, + UTXO_HEIGHT_BEFORE_CARDAMOM + ); + assertMigrationTxWasProcessed( + migrationTx, + ONE_MIGRATION_UTXO, + expectedUtxosRegistered + ); + } + @Test void registerBtcTransaction_withOneOutputAndManyInputs_withSegwitActiveAndRetiringFeds_shouldRegisterMigrationTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange @@ -4302,13 +4445,13 @@ void registerBtcTransaction_withOneOutputAndManyInputs_withSegwitActiveAndRetiri registerPegoutTxInFederationsPendingBtcUtxos(migrationTx); // act - registerReleaseTransaction(migrationTx); + registerReleaseTransaction(migrationTx, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( migrationTx, activeFederation, - HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); assertMigrationTxWasProcessed( migrationTx, @@ -4418,7 +4561,7 @@ void registerBtcTransaction_withFlyoverUtxoWithOneInputAndOutput_withSegwitActiv // act registerPegoutTxSigHash(migrationTx); - registerReleaseTransaction(migrationTx); + registerReleaseTransaction(migrationTx, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( @@ -4442,13 +4585,13 @@ void registerBtcTransaction_withFlyoverUtxoWithOneInputAndOutput_withSegwitActiv registerPegoutTxInFederationsPendingBtcUtxos(migrationTx); // act - registerReleaseTransaction(migrationTx); + registerReleaseTransaction(migrationTx, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( migrationTx, activeFederation, - HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); assertMigrationTxWasProcessed( migrationTx, @@ -4667,21 +4810,46 @@ void registerBtcTransaction_fromRetiredFederationNotInStorage_withPegoutIndex_fo ); } + @Test + void registerBtcTransaction_fromRetiredFederationNotInStorage_withSegwitActiveFed_forVetiver_shouldRegisterMigrationTxUtxosWithZeroHeight() throws BlockStoreException, BridgeIllegalArgumentException, IOException { + // arrange + setupSegwitActiveFed(vetiver900Activations); + Federation segwitRetiredFed = buildSegwitRetiredFed(); + BtcTransaction migrationTx = getReleaseTxWithOneInputAndOutputWithoutChange(segwitRetiredFed, retiredFedSigners, activeFederation.getAddress()); + registerPegoutTxSigHash(migrationTx); + + // act + registerReleaseTransaction(migrationTx, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); + + // assert + List expectedUtxosRegistered = buildExpectedUtxosRegistered( + migrationTx, + activeFederation, + UTXO_HEIGHT_BEFORE_CARDAMOM + ); + assertMigrationTxWasProcessed( + migrationTx, + ONE_MIGRATION_UTXO, + expectedUtxosRegistered + ); + } + @Test void registerBtcTransaction_fromRetiredFederationNotInStorage_withSegwitActiveFed_shouldRegisterMigrationTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange setupSegwitActiveFed(allActivations); - BtcTransaction migrationTx = getReleaseTxWithOneInputAndOutputWithoutChange(retiredFed, retiredFedSigners, activeFederation.getAddress()); + Federation segwitRetiredFed = buildSegwitRetiredFed(); + BtcTransaction migrationTx = getReleaseTxWithOneInputAndOutputWithoutChange(segwitRetiredFed, retiredFedSigners, activeFederation.getAddress()); registerPegoutTxInFederationsPendingBtcUtxos(migrationTx); // act - registerLegacyReleaseTransaction(migrationTx, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX, bridgeMainnetConstants); + registerReleaseTransaction(migrationTx, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( migrationTx, activeFederation, - HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); assertMigrationTxWasProcessed( migrationTx, @@ -5092,11 +5260,11 @@ private void registerLegacyReleaseTransaction(BtcTransaction releaseTx, int heig bridgeSupport.save(); } - private void registerReleaseTransaction(BtcTransaction releaseTx) throws BlockStoreException, BridgeIllegalArgumentException, IOException { + private void registerReleaseTransaction(BtcTransaction releaseTx, int height) throws BlockStoreException, BridgeIllegalArgumentException, IOException { PartialMerkleTree pmtWithWitness = buildPMTAndRecreateChainForSegwitTransactionRegistration( bridgeStorageProvider, bridgeMainnetConstants, - HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX, + height, releaseTx, btcBlockStore ); @@ -5104,7 +5272,7 @@ private void registerReleaseTransaction(BtcTransaction releaseTx) throws BlockSt bridgeSupport.registerBtcTransaction( rskTx, releaseTx.bitcoinSerialize(), - HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX, + height, pmtWithWitness.bitcoinSerialize() ); bridgeSupport.save(); @@ -5176,9 +5344,6 @@ private BtcTransaction getReleaseTxWithOneInputAndOutputWithoutChange(Federation @Nested class ReleaseWithFederationsPendingBtcUTXOs { - // well past the pegout index start, so the release is not identified by its inputs as legacy releases are, - // and since it was created after RSKIP643 it is not in the pegout index either - private static final int BTC_BLOCK_WITH_RELEASE_HEIGHT = HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + 1_000; private static final long ACTIVE_FEDERATION_CREATION_BLOCK_NUMBER = 1L; // the active federation must be active for the pegout to be created private static final long PEGOUT_CREATION_BLOCK_NUMBER = ACTIVE_FEDERATION_CREATION_BLOCK_NUMBER @@ -5254,7 +5419,42 @@ void setUp() { } @Test - void registerBtcTransaction_withPegoutWithChange_shouldRegisterChangeInActiveFed() throws BlockStoreException, BridgeIllegalArgumentException, IOException { + void registerBtcTransaction_withPegoutWithChangeCreatedForVetiver_shouldRegisterChangeInActiveFed() throws BlockStoreException, BridgeIllegalArgumentException, IOException { + // arrange + // before RSKIP643 the pegout sighash is saved in the pegout index instead of its change as federations pending utxos + BtcTransaction pegout = createPegoutForVetiverFromActiveFedPayingToUser(PEGOUT_REQUEST_VALUE); + assertFalse(federationSupport.hasFederationsPendingBtcUTXOs(pegout.getHash())); + setUpBridgeAndFederationSupport(PEGOUT_REGISTRATION_BLOCK_NUMBER); + + // act + signAndRegisterReleaseTransaction( + pegout, + segwitActiveFederation, + segwitActiveFederationKeys, + HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + ); + + // assert + List expectedUtxosRegistered = buildExpectedUtxosRegistered( + pegout, + segwitActiveFederation, + HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + ); + assertUtxosAreEqual(expectedUtxosRegistered, federationSupport.getActiveFederationBtcUTXOs()); + assertReleaseWasRegistered( + bridgeStorageProvider, + federationSupport, + logs, + (int) rskExecutionBlock.getNumber(), + pegout, + List.of(CHANGE_VALUE), + List.of(OUTPUT_INDEX_FOR_PEGOUT_CHANGE), + segwitActiveFederation.getAddress() + ); + } + + @Test + void registerBtcTransaction_withPegoutWithChangeCreatedForCardamom_shouldRegisterChangeInActiveFed() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange BtcTransaction pegout = createPegoutFromActiveFedPayingToUser(PEGOUT_REQUEST_VALUE); setUpBridgeAndFederationSupport(PEGOUT_REGISTRATION_BLOCK_NUMBER); @@ -5263,14 +5463,15 @@ void registerBtcTransaction_withPegoutWithChange_shouldRegisterChangeInActiveFed signAndRegisterReleaseTransaction( pegout, segwitActiveFederation, - segwitActiveFederationKeys + segwitActiveFederationKeys, + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( pegout, segwitActiveFederation, - BTC_BLOCK_WITH_RELEASE_HEIGHT + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); assertUtxosAreEqual(expectedUtxosRegistered, federationSupport.getActiveFederationBtcUTXOs()); assertReleaseWasRegistered( @@ -5286,7 +5487,7 @@ void registerBtcTransaction_withPegoutWithChange_shouldRegisterChangeInActiveFed } @Test - void registerBtcTransaction_withPegoutWithoutChange_shouldNotRegister() throws BlockStoreException, BridgeIllegalArgumentException, IOException { + void registerBtcTransaction_withPegoutWithoutChangeCreatedForCardamom_shouldNotRegister() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange // with no output sent to the live federations, no federations pending utxos are saved // requesting the whole input value leaves no change @@ -5297,7 +5498,8 @@ void registerBtcTransaction_withPegoutWithoutChange_shouldNotRegister() throws B signAndRegisterReleaseTransaction( pegout, segwitActiveFederation, - segwitActiveFederationKeys + segwitActiveFederationKeys, + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); // assert @@ -5320,7 +5522,8 @@ void registerBtcTransaction_withPegoutWithoutChangeCreatedForVetiver_shouldMarkA signAndRegisterReleaseTransaction( pegout, segwitActiveFederation, - segwitActiveFederationKeys + segwitActiveFederationKeys, + HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX ); // assert @@ -5333,40 +5536,6 @@ void registerBtcTransaction_withPegoutWithoutChangeCreatedForVetiver_shouldMarkA assertEventWasNotEmitted(logs, BridgeEvents.UTXOS_REGISTERED.getEvent()); } - @Test - void registerBtcTransaction_withPegoutCreatedForVetiver_shouldRegisterChangeInActiveFed() throws BlockStoreException, BridgeIllegalArgumentException, IOException { - // arrange - // before RSKIP643 the pegout sighash is saved in the pegout index instead of its change as federations pending utxos - BtcTransaction pegout = createPegoutForVetiverFromActiveFedPayingToUser(PEGOUT_REQUEST_VALUE); - assertNotPendingUtxos(pegout); - setUpBridgeAndFederationSupport(PEGOUT_REGISTRATION_BLOCK_NUMBER); - - // act - signAndRegisterReleaseTransaction( - pegout, - segwitActiveFederation, - segwitActiveFederationKeys - ); - - // assert - List expectedUtxosRegistered = buildExpectedUtxosRegistered( - pegout, - segwitActiveFederation, - BTC_BLOCK_WITH_RELEASE_HEIGHT - ); - assertUtxosAreEqual(expectedUtxosRegistered, federationSupport.getActiveFederationBtcUTXOs()); - assertReleaseWasRegistered( - bridgeStorageProvider, - federationSupport, - logs, - (int) rskExecutionBlock.getNumber(), - pegout, - List.of(CHANGE_VALUE), - List.of(OUTPUT_INDEX_FOR_PEGOUT_CHANGE), - segwitActiveFederation.getAddress() - ); - } - @Test void registerBtcTransaction_withPegoutToActiveFed_afterChangingToRetiringFed_shouldRegisterChangeInRetiringFed() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange @@ -5379,14 +5548,15 @@ void registerBtcTransaction_withPegoutToActiveFed_afterChangingToRetiringFed_sho signAndRegisterReleaseTransaction( pegout, segwitActiveFederation, - segwitActiveFederationKeys + segwitActiveFederationKeys, + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); // assert List expectedUtxosRegistered = buildExpectedUtxosRegistered( pegout, segwitActiveFederation, - BTC_BLOCK_WITH_RELEASE_HEIGHT + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); assertUtxosAreEqual(expectedUtxosRegistered, federationSupport.getRetiringFederationBtcUTXOs()); assertTrue(federationSupport.getActiveFederationBtcUTXOs().isEmpty()); @@ -5414,7 +5584,8 @@ void registerBtcTransaction_withPegoutToActiveFed_afterChangingToRetiredFed_shou signAndRegisterReleaseTransaction( pegout, segwitActiveFederation, - segwitActiveFederationKeys + segwitActiveFederationKeys, + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); // assert @@ -5442,7 +5613,7 @@ void registerBtcTransaction_withPegoutAlreadyRegisteredThroughRegisterPegoutTran PartialMerkleTree pmtWithWitness = buildPMTAndRecreateChainForSegwitTransactionRegistration( bridgeStorageProvider, bridgeMainnetConstants, - BTC_BLOCK_WITH_RELEASE_HEIGHT, + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS, pegout, btcBlockStore ); @@ -5450,7 +5621,7 @@ void registerBtcTransaction_withPegoutAlreadyRegisteredThroughRegisterPegoutTran PartialMerkleTree pmtWithTxId = createValidPmtForTransactionsHashes(List.of(pegout.getHash()), btcMainnetParams); bridgeSupport.registerPegoutTransaction( pegout.getHash(), - BTC_BLOCK_WITH_RELEASE_HEIGHT, + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS, pmtWithTxId.bitcoinSerialize() ); bridgeSupport.save(); @@ -5465,7 +5636,7 @@ void registerBtcTransaction_withPegoutAlreadyRegisteredThroughRegisterPegoutTran bridgeSupport.registerBtcTransaction( rskTx, pegout.bitcoinSerialize(), - BTC_BLOCK_WITH_RELEASE_HEIGHT, + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS, pmtWithWitness.bitcoinSerialize() ); bridgeSupport.save(); @@ -5478,7 +5649,32 @@ void registerBtcTransaction_withPegoutAlreadyRegisteredThroughRegisterPegoutTran } @Test - void registerBtcTransaction_withMigrationWithOneOutput_shouldRegisterMigratedUtxosInActiveFed() throws BlockStoreException, BridgeIllegalArgumentException, IOException { + void registerBtcTransaction_withMigrationWithOneOutputCreatedForVetiver_shouldRegisterMigratedUtxosInActiveFed() throws BlockStoreException, BridgeIllegalArgumentException, IOException { + // arrange + // before RSKIP643 the migration sighash is saved in the pegout index instead of its outputs as federations pending utxos + BtcTransaction migrationTransaction = createMigrationForVetiverFromRetiringFedToActiveFed(); + assertFalse(federationSupport.hasFederationsPendingBtcUTXOs(migrationTransaction.getHash())); + setUpBridgeAndFederationSupport(MIGRATION_REGISTRATION_BLOCK_NUMBER); + + // act + signAndRegisterReleaseTransaction( + migrationTransaction, + retiringFederation, + retiringFederationKeys, + HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + ); + + // assert + assertEquals(1, migrationTransaction.getOutputs().size()); + assertMigrationWasRegisteredInActiveFed( + migrationTransaction, + List.of(0L), + HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + ); + } + + @Test + void registerBtcTransaction_withMigrationWithOneOutputCreatedForCardamom_shouldRegisterMigratedUtxosInActiveFed() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange BtcTransaction migrationTransaction = createMigrationFromRetiringFedToActiveFed(INPUT_VALUE); setUpBridgeAndFederationSupport(MIGRATION_REGISTRATION_BLOCK_NUMBER); @@ -5487,14 +5683,16 @@ void registerBtcTransaction_withMigrationWithOneOutput_shouldRegisterMigratedUtx signAndRegisterReleaseTransaction( migrationTransaction, retiringFederation, - retiringFederationKeys + retiringFederationKeys, + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); // assert assertEquals(1, migrationTransaction.getOutputs().size()); assertMigrationWasRegisteredInActiveFed( migrationTransaction, - List.of(0L) + List.of(0L), + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); } @@ -5508,14 +5706,16 @@ void registerBtcTransaction_withMigrationWithFixedValueOutputs_shouldRegisterMig signAndRegisterReleaseTransaction( migrationTransaction, retiringFederation, - retiringFederationKeys + retiringFederationKeys, + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); // assert assertEquals(FIXED_VALUE_MIGRATION_OUTPUTS, migrationTransaction.getOutputs().size()); assertMigrationWasRegisteredInActiveFed( migrationTransaction, - List.of(0L, 1L, 2L) + List.of(0L, 1L, 2L), + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); } @@ -5530,7 +5730,8 @@ void registerBtcTransaction_withMigrationWithEvenlyDistributedOutputs_withMaximu signAndRegisterReleaseTransaction( migrationTransaction, retiringFederation, - retiringFederationKeys + retiringFederationKeys, + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); // assert @@ -5541,7 +5742,8 @@ void registerBtcTransaction_withMigrationWithEvenlyDistributedOutputs_withMaximu .toList(); assertMigrationWasRegisteredInActiveFed( migrationTransaction, - expectedOutputIndexes + expectedOutputIndexes, + HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS ); } @@ -5567,6 +5769,7 @@ private void setUpBridgeAndFederationSupportWithActivations(long executionBlockN .withRepository(repository) .withEventLogger(new BridgeEventLoggerImpl(bridgeMainnetConstants, activations, logs)) .withBtcBlockStoreFactory(btcBlockStoreFactory) + .withBtcLockSenderProvider(btcLockSenderProvider) .withFederationSupport(federationSupport) .withFeePerKbSupport(feePerKbSupport) .build(); @@ -5608,7 +5811,16 @@ private BtcTransaction createMigrationFromRetiringFedToActiveFed(Coin retiringFe .withValue(retiringFederationBalance) .withScriptPubKey(retiringFederation.getP2SHScript()) .build(); - return createMigrationSpendingRetiringFedUtxos(List.of(retiringFederationUtxo)); + return createMigrationWithActivationsSpendingRetiringFedUtxos(allActivations, List.of(retiringFederationUtxo)); + } + + private BtcTransaction createMigrationForVetiverFromRetiringFedToActiveFed() throws IOException { + UTXO retiringFederationUtxo = UTXOBuilder.builder() + .withTransactionHash(BitcoinTestUtils.createHash(3)) + .withValue(INPUT_VALUE) + .withScriptPubKey(retiringFederation.getP2SHScript()) + .build(); + return createMigrationWithActivationsSpendingRetiringFedUtxos(vetiver900Activations, List.of(retiringFederationUtxo)); } private BtcTransaction createMigrationWithMaximumInputsFromRetiringFedToActiveFed() throws IOException { @@ -5616,15 +5828,16 @@ private BtcTransaction createMigrationWithMaximumInputsFromRetiringFedToActiveFe .withValue(EVENLY_DISTRIBUTED_MIGRATION_RETIRING_FEDERATION_UTXO_VALUE) .withScriptPubKey(retiringFederation.getP2SHScript()) .buildMany(MAXIMUM_MIGRATION_INPUTS, i -> BitcoinTestUtils.createHash(i + 1)); - return createMigrationSpendingRetiringFedUtxos(retiringFederationUtxos); + return createMigrationWithActivationsSpendingRetiringFedUtxos(allActivations, retiringFederationUtxos); } - private BtcTransaction createMigrationSpendingRetiringFedUtxos(List retiringFederationUtxos) throws IOException { - setUpBridgeAndFederationSupport(MIGRATION_CREATION_BLOCK_NUMBER); + private BtcTransaction createMigrationWithActivationsSpendingRetiringFedUtxos(ForBlock activations, List retiringFederationUtxos) throws IOException { + setUpBridgeAndFederationSupportWithActivations(MIGRATION_CREATION_BLOCK_NUMBER, activations); federationStorageProvider.setOldFederation(retiringFederation); federationStorageProvider.getOldFederationBtcUTXOs().addAll(retiringFederationUtxos); // with the migration ongoing, migrates the retiring federation funds, storing the migrated outputs as federations pending utxos + // after RSKIP643, or the migration sighash in the pegout index before it bridgeSupport.updateCollections(updateCollectionsTransaction); return getReleaseFromPegoutsWFC(bridgeStorageProvider); @@ -5632,12 +5845,13 @@ private BtcTransaction createMigrationSpendingRetiringFedUtxos(List retiri private void assertMigrationWasRegisteredInActiveFed( BtcTransaction migrationTransaction, - List expectedOutputIndexes + List expectedOutputIndexes, + int btcBlockWithReleaseHeight ) throws IOException { List expectedUtxosRegistered = buildExpectedUtxosRegistered( migrationTransaction, segwitActiveFederation, - BTC_BLOCK_WITH_RELEASE_HEIGHT + btcBlockWithReleaseHeight ); assertUtxosAreEqual(expectedUtxosRegistered, federationSupport.getActiveFederationBtcUTXOs()); List migratedValues = migrationTransaction.getOutputs().stream() @@ -5658,7 +5872,8 @@ private void assertMigrationWasRegisteredInActiveFed( private void signAndRegisterReleaseTransaction( BtcTransaction releaseTransaction, Federation signingFederation, - List signingFederationKeys + List signingFederationKeys, + int btcBlockWithReleaseHeight ) throws BlockStoreException, BridgeIllegalArgumentException, IOException { signInputs( signingFederation, @@ -5668,7 +5883,7 @@ private void signAndRegisterReleaseTransaction( PartialMerkleTree pmtWithWitness = buildPMTAndRecreateChainForSegwitTransactionRegistration( bridgeStorageProvider, bridgeMainnetConstants, - BTC_BLOCK_WITH_RELEASE_HEIGHT, + btcBlockWithReleaseHeight, releaseTransaction, btcBlockStore ); @@ -5676,7 +5891,7 @@ private void signAndRegisterReleaseTransaction( bridgeSupport.registerBtcTransaction( rskTx, releaseTransaction.bitcoinSerialize(), - BTC_BLOCK_WITH_RELEASE_HEIGHT, + btcBlockWithReleaseHeight, pmtWithWitness.bitcoinSerialize() ); bridgeSupport.save(); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportSvpTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportSvpTest.java index d983a2821b8..7ed6252483a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportSvpTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportSvpTest.java @@ -70,7 +70,14 @@ class BridgeSupportSvpTest { private static final RskAddress bridgeContractAddress = PrecompiledContracts.BRIDGE_ADDR; private static final BridgeConstants bridgeMainNetConstants = BridgeMainNetConstants.getInstance(); private static final NetworkParameters btcMainnetParams = bridgeMainNetConstants.getBtcParams(); + // past the pegout index start, so releases are not identified by their inputs as legacy releases are + private static final int HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX = bridgeMainNetConstants.getBtcHeightWhenPegoutTxIndexActivates() + + bridgeMainNetConstants.getPegoutTxIndexGracePeriodInBtcBlocks(); + private static final int BTC_BLOCKS_BETWEEN_PEGOUT_INDEX_AND_FEDERATIONS_PENDING_BTC_UTXOS = 100; + private static final int HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS = HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX + BTC_BLOCKS_BETWEEN_PEGOUT_INDEX_AND_FEDERATIONS_PENDING_BTC_UTXOS; private static final FederationConstants federationMainNetConstants = bridgeMainNetConstants.getFederationConstants(); + private static final BtcLockSenderProvider btcLockSenderProvider = new BtcLockSenderProvider(); + private static final PeginInstructionsProvider peginInstructionsProvider = new PeginInstructionsProvider(); private static final List svpFundTxOutpointsValues = Arrays.asList( Coin.valueOf(1_000_000), Coin.valueOf(500_000), @@ -779,7 +786,7 @@ class FundTxRegistrationTests { @Test void registerBtcTransaction_forSvpFundTransactionChange_whenProposedFederationDoesNotExist_shouldRegisterTransactionButNotUpdateSvpFundTransactionValues() throws Exception { // arrange - arrangeSvpFundTransactionFromSegwitActiveFederationToBeRegistered(); + arrangeSvpFundTransactionCreatedForCardamomFromSegwitActiveFederationToBeRegistered(); federationStorageProvider.setProposedFederation(null); List activeFederationUtxosBeforeRegisteringTx = new ArrayList<>(federationSupport.getActiveFederationBtcUTXOs()); @@ -825,7 +832,7 @@ void registerBtcTransaction_forSvpFundTransactionChange_whenValidationPeriodEnde void registerBtcTransaction_forSvpFundTransactionChange_whenValidationPeriodEnded_shouldRegisterChangeUtxoButNotUpdateSvpFundTransactionValues() throws Exception { // arrange arrangeExecutionBlockIsAfterValidationPeriodEnded(); - arrangeSvpFundTransactionFromSegwitActiveFederationToBeRegistered(); + arrangeSvpFundTransactionCreatedForCardamomFromSegwitActiveFederationToBeRegistered(); List activeFederationUtxosBeforeRegisteringTx = new ArrayList<>(federationSupport.getActiveFederationBtcUTXOs()); // act @@ -837,10 +844,10 @@ void registerBtcTransaction_forSvpFundTransactionChange_whenValidationPeriodEnde } @Test - void registerBtcTransaction_forSvpFundTransactionChange_whenSvpValuesWereCleared_shouldRegisterChangeUtxo() throws Exception { + void registerBtcTransaction_forSvpFundTransactionChange_whenSvpValuesWereCleared_withFundTxCreatedForCardamom_shouldRegisterChangeUtxo() throws Exception { // arrange arrangeExecutionBlockIsAfterValidationPeriodEnded(); - arrangeSvpFundTransactionFromSegwitActiveFederationToBeRegistered(); + arrangeSvpFundTransactionCreatedForCardamomFromSegwitActiveFederationToBeRegistered(); arrangeSvpValuesWereClearedAfterValidationPeriodEnded(); List activeFederationUtxosBeforeRegisteringTx = new ArrayList<>(federationSupport.getActiveFederationBtcUTXOs()); @@ -868,6 +875,21 @@ void registerBtcTransaction_forSvpFundTransactionChange_whenSvpValuesWereCleared assertSvpFundTxChangeWasRegisteredForVetiver(activeFederationUtxosBeforeRegisteringTx); } + @Test + void registerBtcTransaction_forSvpFundTransactionChange_whenSvpValuesWereCleared_withFundTxCreatedForVetiver_shouldRegisterChangeUtxo() throws Exception { + // arrange + arrangeExecutionBlockIsAfterValidationPeriodEnded(); + arrangeSvpFundTransactionCreatedForVetiverFromSegwitActiveFederationToBeRegistered(); + arrangeSvpValuesWereClearedAfterValidationPeriodEnded(); + List activeFederationUtxosBeforeRegisteringTx = new ArrayList<>(federationSupport.getActiveFederationBtcUTXOs()); + + // act + registerBtcTransaction(svpFundTransaction); + + // assert + assertSvpFundTxChangeWasRegisteredInSegwitActiveFederation(activeFederationUtxosBeforeRegisteringTx); + } + @Test void registerBtcTransaction_forNormalPegout_whenSvpPeriodIsOngoing_forVetiver_shouldRegisterTransactionButNotUpdateSvpFundTransactionValues() throws Exception { // arrange @@ -881,7 +903,7 @@ void registerBtcTransaction_forNormalPegout_whenSvpPeriodIsOngoing_forVetiver_sh .build(); savePegoutIndex(pegout); - setUpForTransactionRegistration(pegout); + setUpForTransactionRegistration(pegout, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); setUpBridgeSupportForVetiver(); List activeFederationUtxosBeforeRegisteringTx = new ArrayList<>(federationSupport.getActiveFederationBtcUTXOs()); @@ -919,7 +941,7 @@ void registerBtcTransaction_forNormalPegout_whenSvpPeriodIsOngoing_shouldRegiste FEDERATIONS_PENDING_UTXO_HEIGHT ); federationSupport.storeFederationsPendingBtcUTXOs(pegout.getHash(), pegoutChangeUtxos); - setUpForTransactionRegistration(pegout); + setUpForTransactionRegistration(pegout, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); List activeFederationUtxosBeforeRegisteringTx = new ArrayList<>(federationSupport.getActiveFederationBtcUTXOs()); // act @@ -946,7 +968,7 @@ void registerBtcTransaction_forSvpFundTransactionWithoutChangeOutput_whenSvpPeri saveSvpFundTransactionHashUnsigned(svpFundTransaction.getHash()); signInputs(segwitActiveFederation, segwitActiveFederationKeys, svpFundTransaction); - setUpForTransactionRegistration(svpFundTransaction); + setUpForTransactionRegistration(svpFundTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); List activeFederationUtxosBeforeRegisteringTx = new ArrayList<>(federationSupport.getActiveFederationBtcUTXOs()); // act @@ -965,7 +987,7 @@ void registerBtcTransaction_forSvpFundTransactionWithoutChangeOutput_whenSvpPeri saveSvpFundTransactionUnsignedForVetiver(); signInputs(activeFederation, activeFederationKeys, svpFundTransaction); - setUpForTransactionRegistration(svpFundTransaction); + setUpForTransactionRegistration(svpFundTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); setUpBridgeSupportForVetiver(); List activeFederationUtxosBeforeRegisteringTx = new ArrayList<>(federationSupport.getActiveFederationBtcUTXOs()); @@ -992,9 +1014,9 @@ void registerBtcTransaction_forSvpFundTransactionChange_whenSvpPeriodIsOngoing_f } @Test - void registerBtcTransaction_forSvpFundTransactionChange_whenSvpPeriodIsOngoing_shouldRegisterTransactionAndUpdateSvpFundTransactionValues() throws Exception { + void registerBtcTransaction_forSvpFundTransactionChange_whenSvpPeriodIsOngoing_withFundTxCreatedForCardamom_shouldRegisterTransactionAndUpdateSvpFundTransactionValues() throws Exception { // arrange - arrangeSvpFundTransactionFromSegwitActiveFederationToBeRegistered(); + arrangeSvpFundTransactionCreatedForCardamomFromSegwitActiveFederationToBeRegistered(); List activeFederationUtxosBeforeRegisteringTx = new ArrayList<>(federationSupport.getActiveFederationBtcUTXOs()); // act @@ -1006,16 +1028,9 @@ void registerBtcTransaction_forSvpFundTransactionChange_whenSvpPeriodIsOngoing_s } @Test - void registerBtcTransaction_forSvpFundTransactionChange_withFundTxCreatedBeforeRSKIP643_shouldRegisterTransactionAndUpdateSvpFundTransactionValues() throws Exception { + void registerBtcTransaction_forSvpFundTransactionChange_whenSvpPeriodIsOngoing_withFundTxCreatedForVetiver_shouldRegisterTransactionAndUpdateSvpFundTransactionValues() throws Exception { // arrange - setupSegwitActiveFederationWithUtxos(); - // the fund tx was created before RSKIP643, so its pegout index was saved instead of its pending utxos - arrangeSvpFundTransactionUnsignedForVetiver(); - assertFalse(federationSupport.hasFederationsPendingBtcUTXOs(svpFundTransaction.getHash())); - - signInputs(segwitActiveFederation, segwitActiveFederationKeys, svpFundTransaction); - // and it is registered after RSKIP643 - setUpForTransactionRegistration(svpFundTransaction); + arrangeSvpFundTransactionCreatedForVetiverFromSegwitActiveFederationToBeRegistered(); List activeFederationUtxosBeforeRegisteringTx = new ArrayList<>(federationSupport.getActiveFederationBtcUTXOs()); // act @@ -1026,20 +1041,31 @@ void registerBtcTransaction_forSvpFundTransactionChange_withFundTxCreatedBeforeR assertSvpFundTransactionValuesWereUpdated(); } - private void arrangeSvpFundTransactionFromSegwitActiveFederationToBeRegistered() throws BlockStoreException { + private void arrangeSvpFundTransactionCreatedForCardamomFromSegwitActiveFederationToBeRegistered() throws BlockStoreException { setupSegwitActiveFederationWithUtxos(); arrangeSvpFundTransactionUnsigned(); assertTrue(federationSupport.hasFederationsPendingBtcUTXOs(svpFundTransaction.getHash())); signInputs(segwitActiveFederation, segwitActiveFederationKeys, svpFundTransaction); - setUpForTransactionRegistration(svpFundTransaction); + setUpForTransactionRegistration(svpFundTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); + } + + private void arrangeSvpFundTransactionCreatedForVetiverFromSegwitActiveFederationToBeRegistered() throws BlockStoreException { + setupSegwitActiveFederationWithUtxos(); + // the fund tx was created before RSKIP643, so its pegout index was saved instead of its pending utxos + arrangeSvpFundTransactionUnsignedForVetiver(); + assertFalse(federationSupport.hasFederationsPendingBtcUTXOs(svpFundTransaction.getHash())); + + signInputs(segwitActiveFederation, segwitActiveFederationKeys, svpFundTransaction); + // and it is registered after RSKIP643 + setUpForTransactionRegistration(svpFundTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); } private void arrangeSvpFundTransactionToBeRegisteredForVetiver() throws BlockStoreException { arrangeSvpFundTransactionUnsignedForVetiver(); signInputs(activeFederation, activeFederationKeys, svpFundTransaction); - setUpForTransactionRegistration(svpFundTransaction); + setUpForTransactionRegistration(svpFundTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); setUpBridgeSupportForVetiver(); } @@ -1402,7 +1428,7 @@ class SpendTxRegistrationTests { void registerBtcTransaction_forPegout_whenWaitingForSvpSpendTx_forVetiver_shouldProcessAndRegisterPegout_shouldNotProcessNorRegisterSpendTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange arrangeSvpSpendTransaction(); - setUpForTransactionRegistration(svpSpendTransaction); + setUpForTransactionRegistration(svpSpendTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); BtcTransaction pegout = PegoutTransactionBuilder.builder() .withActiveFederation(activeFederation) @@ -1412,7 +1438,7 @@ void registerBtcTransaction_forPegout_whenWaitingForSvpSpendTx_forVetiver_should .build(); savePegoutIndex(pegout); - setUpForTransactionRegistration(pegout); + setUpForTransactionRegistration(pegout, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); setUpBridgeSupportForVetiver(); List activeFederationUtxosBeforeRegisteringTx = new ArrayList<>(federationSupport.getActiveFederationBtcUTXOs()); @@ -1450,7 +1476,7 @@ void registerBtcTransaction_forPegout_whenWaitingForSvpSpendTx_shouldProcessAndR // arrange setupSegwitActiveFederationWithUtxos(); arrangeSvpSpendTransactionFromSegwitActiveFederation(); - setUpForTransactionRegistration(svpSpendTransaction); + setUpForTransactionRegistration(svpSpendTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); BtcTransaction pegout = PegoutTransactionBuilder.builder() .withActiveFederation(segwitActiveFederation) @@ -1465,7 +1491,7 @@ void registerBtcTransaction_forPegout_whenWaitingForSvpSpendTx_shouldProcessAndR FEDERATIONS_PENDING_UTXO_HEIGHT ); federationSupport.storeFederationsPendingBtcUTXOs(pegout.getHash(), pegoutChangeUtxos); - setUpForTransactionRegistration(pegout); + setUpForTransactionRegistration(pegout, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); List activeFederationUtxosBeforeRegisteringTx = new ArrayList<>(federationSupport.getActiveFederationBtcUTXOs()); Federation activeFederationBeforeRegisteringTx = federationSupport.getActiveFederation(); @@ -1502,7 +1528,7 @@ void registerBtcTransaction_forPegout_whenWaitingForSvpSpendTx_shouldProcessAndR void registerBtcTransaction_forLegacyPeginFromP2pkh_whenWaitingForSvpSpendTx_shouldProcessAndRegisterPegin_shouldNotProcessNorRegisterSpendTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange arrangeSvpSpendTransaction(); - setUpForTransactionRegistration(svpSpendTransaction); + setUpForTransactionRegistration(svpSpendTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); BtcTransaction pegin = new BtcTransaction(btcMainnetParams); BtcECKey senderPubKey = getBtcEcKeyFromSeed("legacy_pegin_sender"); @@ -1510,20 +1536,7 @@ void registerBtcTransaction_forLegacyPeginFromP2pkh_whenWaitingForSvpSpendTx_sho pegin.addInput(BitcoinTestUtils.createHash(1), 0, scriptSig); Coin amountToSend = Coin.COIN; pegin.addOutput(amountToSend, activeFederation.getAddress()); - setUpForTransactionRegistration(pegin); - - // recreate bridge support with real btcLockSenderProvider instead of a mock to be able to parse pegin - BtcLockSenderProvider btcLockSenderProvider = new BtcLockSenderProvider(); - bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeMainNetConstants) - .withProvider(bridgeStorageProvider) - .withEventLogger(bridgeEventLogger) - .withActivations(allActivations) - .withFederationSupport(federationSupport) - .withFeePerKbSupport(feePerKbSupport) - .withExecutionBlock(rskExecutionBlock) - .withBtcLockSenderProvider(btcLockSenderProvider) - .build(); + setUpForTransactionRegistration(pegin, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); int activeFederationUtxosSizeBeforeRegisteringTx = federationSupport.getActiveFederationBtcUTXOs().size(); Federation activeFederationBeforeRegisteringTx = federationSupport.getActiveFederation(); @@ -1560,7 +1573,7 @@ void registerBtcTransaction_forLegacyPeginFromP2pkh_whenWaitingForSvpSpendTx_sho void registerBtcTransaction_forLegacyPeginFromP2shP2wpkh_whenWaitingForSvpSpendTx_shouldProcessAndRegisterPegin_shouldNotProcessNorRegisterSpendTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange arrangeSvpSpendTransaction(); - setUpForTransactionRegistration(svpSpendTransaction); + setUpForTransactionRegistration(svpSpendTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); BtcTransaction pegin = new BtcTransaction(btcMainnetParams); BtcECKey senderPubKey = getBtcEcKeyFromSeed("legacy_pegin_p2shp2wpkh_sender"); @@ -1578,20 +1591,7 @@ void registerBtcTransaction_forLegacyPeginFromP2shP2wpkh_whenWaitingForSvpSpendT Coin amountToSend = Coin.COIN; pegin.addOutput(amountToSend, activeFederation.getAddress()); - setUpForTransactionRegistration(pegin); - - // recreate bridge support with real btcLockSenderProvider instead of a mock to be able to parse pegin - BtcLockSenderProvider btcLockSenderProvider = new BtcLockSenderProvider(); - bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeMainNetConstants) - .withProvider(bridgeStorageProvider) - .withEventLogger(bridgeEventLogger) - .withActivations(allActivations) - .withFederationSupport(federationSupport) - .withFeePerKbSupport(feePerKbSupport) - .withExecutionBlock(rskExecutionBlock) - .withBtcLockSenderProvider(btcLockSenderProvider) - .build(); + setUpForTransactionRegistration(pegin, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); int activeFederationUtxosSizeBeforeRegisteringTx = federationSupport.getActiveFederationBtcUTXOs().size(); Federation activeFederationBeforeRegisteringTx = federationSupport.getActiveFederation(); @@ -1628,7 +1628,7 @@ void registerBtcTransaction_forLegacyPeginFromP2shP2wpkh_whenWaitingForSvpSpendT void registerBtcTransaction_forLegacyPeginFromP2shMultisig_whenWaitingForSvpSpendTx_shouldProcessButNotRegisterPegin_shouldNotProcessNorRegisterSpendTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange arrangeSvpSpendTransaction(); - setUpForTransactionRegistration(svpSpendTransaction); + setUpForTransactionRegistration(svpSpendTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); BtcTransaction pegin = new BtcTransaction(btcMainnetParams); List pubKeys = Arrays.asList( @@ -1641,20 +1641,7 @@ void registerBtcTransaction_forLegacyPeginFromP2shMultisig_whenWaitingForSvpSpen Coin amountToSend = Coin.COIN; pegin.addOutput(amountToSend, activeFederation.getAddress()); - setUpForTransactionRegistration(pegin); - - // recreate bridge support with real btcLockSenderProvider instead of a mock to be able to parse pegin - BtcLockSenderProvider btcLockSenderProvider = new BtcLockSenderProvider(); - bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeMainNetConstants) - .withProvider(bridgeStorageProvider) - .withEventLogger(bridgeEventLogger) - .withActivations(allActivations) - .withFederationSupport(federationSupport) - .withFeePerKbSupport(feePerKbSupport) - .withExecutionBlock(rskExecutionBlock) - .withBtcLockSenderProvider(btcLockSenderProvider) - .build(); + setUpForTransactionRegistration(pegin, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); int activeFederationUtxosSizeBeforeRegisteringTx = federationSupport.getActiveFederationBtcUTXOs().size(); Federation activeFederationBeforeRegisteringTx = federationSupport.getActiveFederation(); @@ -1692,7 +1679,7 @@ void registerBtcTransaction_forLegacyPeginFromP2shMultisig_whenWaitingForSvpSpen void registerBtcTransaction_forLegacyPeginFromP2shP2wsh_whenWaitingForSvpSpendTx_shouldProcessButNotRegisterPegin_shouldNotProcessNorRegisterSpendTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange arrangeSvpSpendTransaction(); - setUpForTransactionRegistration(svpSpendTransaction); + setUpForTransactionRegistration(svpSpendTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); BtcTransaction pegin = new BtcTransaction(btcMainnetParams); List pubKeys = Arrays.asList( @@ -1714,20 +1701,7 @@ void registerBtcTransaction_forLegacyPeginFromP2shP2wsh_whenWaitingForSvpSpendTx Coin amountToSend = Coin.COIN; pegin.addOutput(amountToSend, activeFederation.getAddress()); - setUpForTransactionRegistration(pegin); - - // recreate bridge support with real btcLockSenderProvider instead of a mock to be able to parse pegin - BtcLockSenderProvider btcLockSenderProvider = new BtcLockSenderProvider(); - bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeMainNetConstants) - .withProvider(bridgeStorageProvider) - .withEventLogger(bridgeEventLogger) - .withActivations(allActivations) - .withFederationSupport(federationSupport) - .withFeePerKbSupport(feePerKbSupport) - .withExecutionBlock(rskExecutionBlock) - .withBtcLockSenderProvider(btcLockSenderProvider) - .build(); + setUpForTransactionRegistration(pegin, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); int activeFederationUtxosSizeBeforeRegisteringTx = federationSupport.getActiveFederationBtcUTXOs().size(); Federation activeFederationBeforeRegisteringTx = federationSupport.getActiveFederation(); @@ -1765,7 +1739,7 @@ void registerBtcTransaction_forLegacyPeginFromP2shP2wsh_whenWaitingForSvpSpendTx void registerBtcTransaction_forPeginV1_whenWaitingForSvpSpendTx_shouldProcessAndRegisterPegin_shouldNotProcessNorRegisterSpendTx() throws BlockStoreException, BridgeIllegalArgumentException, IOException, PeginInstructionsException { // arrange arrangeSvpSpendTransaction(); - setUpForTransactionRegistration(svpSpendTransaction); + setUpForTransactionRegistration(svpSpendTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); BtcTransaction pegin = new BtcTransaction(btcMainnetParams); BtcECKey senderPubKey = getBtcEcKeyFromSeed("legacy_pegin_sender"); @@ -1775,22 +1749,7 @@ void registerBtcTransaction_forPeginV1_whenWaitingForSvpSpendTx_shouldProcessAnd pegin.addOutput(amountToSend, activeFederation.getAddress()); Script opReturnScript = PegTestUtils.createOpReturnScriptForRsk(1, bridgeContractAddress, Optional.empty()); pegin.addOutput(Coin.ZERO, opReturnScript); - setUpForTransactionRegistration(pegin); - - // recreate bridge support with real btcLockSenderProvider and peginInstructionsProvider instead of a mock to be able to parse pegin v1 - BtcLockSenderProvider btcLockSenderProvider = new BtcLockSenderProvider(); - PeginInstructionsProvider peginInstructionsProvider = new PeginInstructionsProvider(); - bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeMainNetConstants) - .withProvider(bridgeStorageProvider) - .withEventLogger(bridgeEventLogger) - .withActivations(allActivations) - .withFederationSupport(federationSupport) - .withFeePerKbSupport(feePerKbSupport) - .withExecutionBlock(rskExecutionBlock) - .withBtcLockSenderProvider(btcLockSenderProvider) - .withPeginInstructionsProvider(peginInstructionsProvider) - .build(); + setUpForTransactionRegistration(pegin, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); int activeFederationUtxosSizeBeforeRegisteringTx = federationSupport.getActiveFederationBtcUTXOs().size(); Federation activeFederationBeforeRegisteringTx = federationSupport.getActiveFederation(); @@ -1832,7 +1791,7 @@ void registerBtcTransaction_forPeginV1_whenWaitingForSvpSpendTx_shouldProcessAnd void registerBtcTransaction_whenSpendTransactionHashIsNotSaved_shouldBeIdentifiedAsRejectedPeginAndMarkAsProcessed() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange recreateSvpSpendTransactionUnsigned(); - setUpForTransactionRegistration(svpSpendTransaction); + setUpForTransactionRegistration(svpSpendTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); int activeFederationUtxosSizeBeforeRegisteringTx = federationSupport.getActiveFederationBtcUTXOs().size(); Federation activeFederationBeforeRegisteringTx = federationSupport.getActiveFederation(); @@ -1866,7 +1825,7 @@ private void assertProposedFederationExists() { void registerBtcTransaction_whenIsTheSpendTransaction_shouldProcessSpendTxAndSvpSuccess() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange arrangeSvpSpendTransaction(); - setUpForTransactionRegistration(svpSpendTransaction); + setUpForTransactionRegistration(svpSpendTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); List activeFederationUtxosBeforeRegisteringTx = new ArrayList<>(federationSupport.getActiveFederationBtcUTXOs()); @@ -1888,7 +1847,7 @@ void registerBtcTransaction_whenIsTheSpendTransaction_shouldProcessSpendTxAndSvp void registerBtcTransaction_whenIsTheSpendTransaction_forVetiver_shouldRegisterSpendTxUtxoWithZeroHeight() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange arrangeSvpSpendTransaction(); - setUpForTransactionRegistration(svpSpendTransaction); + setUpForTransactionRegistration(svpSpendTransaction, HEIGHT_AT_WHICH_TO_START_USING_PEGOUT_INDEX); bridgeSupport = bridgeSupportBuilder .withActivations(vetiverActivations) .build(); @@ -1915,7 +1874,7 @@ void registerBtcTransaction_evenIfValidationPeriodEnded_shouldRegisterSpendTxAnd arrangeExecutionBlockIsAfterValidationPeriodEnded(); arrangeSvpSpendTransaction(); - setUpForTransactionRegistration(svpSpendTransaction); + setUpForTransactionRegistration(svpSpendTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); List activeFederationUtxosBeforeRegisteringTx = new ArrayList<>(federationSupport.getActiveFederationBtcUTXOs()); @@ -1943,7 +1902,7 @@ void registerBtcTransaction_whenIsTheSpendTransaction_withAmountBelowMinPeginVal addSpendTransactionOutput(amountToSend); saveSvpSpendTransactionValues(); - setUpForTransactionRegistration(svpSpendTransaction); + setUpForTransactionRegistration(svpSpendTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); List activeFederationUtxosBeforeRegisteringTx = new ArrayList<>(federationSupport.getActiveFederationBtcUTXOs()); @@ -1965,7 +1924,7 @@ void registerBtcTransaction_whenIsTheSpendTransaction_withAmountBelowMinPeginVal void registerBtcTransaction_twice_whenIsTheSpendTransaction_shouldRegisterItJustOnce() throws BlockStoreException, BridgeIllegalArgumentException, IOException { // arrange arrangeSvpSpendTransaction(); - setUpForTransactionRegistration(svpSpendTransaction); + setUpForTransactionRegistration(svpSpendTransaction, HEIGHT_TO_USE_FEDERATIONS_PENDING_BTC_UTXOS); List activeFederationUtxosBeforeRegisteringTx = new ArrayList<>(federationSupport.getActiveFederationBtcUTXOs()); @@ -2235,13 +2194,13 @@ private void saveSvpSpendTransactionValues() { bridgeStorageProvider.save(); } - private void setUpForTransactionRegistration(BtcTransaction transaction) throws BlockStoreException { + private void setUpForTransactionRegistration(BtcTransaction transaction, int btcBlockWithTransactionHeight) throws BlockStoreException { // recreate a valid chain that has the tx, so it passes the previous checks in registerBtcTransaction BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(btcMainnetParams, 100, 100); BtcBlockStoreWithCache btcBlockStoreWithCache = btcBlockStoreFactory.newInstance(repository, bridgeMainNetConstants, bridgeStorageProvider, allActivations); pmtWithTransactions = createValidPmtForTransactions(List.of(transaction), btcMainnetParams); - btcBlockWithPmtHeight = bridgeMainNetConstants.getBtcHeightWhenPegoutTxIndexActivates() + bridgeMainNetConstants.getPegoutTxIndexGracePeriodInBtcBlocks(); // we want pegout tx index to be activated + btcBlockWithPmtHeight = btcBlockWithTransactionHeight; int chainHeight = btcBlockWithPmtHeight + bridgeMainNetConstants.getBtc2RskMinimumAcceptableConfirmations(); recreateChainFromPmt(btcBlockStoreWithCache, chainHeight, pmtWithTransactions, btcBlockWithPmtHeight, btcMainnetParams); @@ -2256,6 +2215,8 @@ private void setUpForTransactionRegistration(BtcTransaction transaction) throws .withFeePerKbSupport(feePerKbSupport) .withExecutionBlock(rskExecutionBlock) .withBtcBlockStoreFactory(btcBlockStoreFactory) + .withBtcLockSenderProvider(btcLockSenderProvider) + .withPeginInstructionsProvider(peginInstructionsProvider) .withRepository(repository) .build(); } diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java index 53b88ba4984..fa6181f95f1 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java @@ -7,6 +7,7 @@ import co.rsk.peg.constants.BridgeConstants; import co.rsk.peg.constants.BridgeMainNetConstants; import co.rsk.peg.constants.BridgeTestNetConstants; +import co.rsk.RskTestUtils; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.bitcoin.BitcoinTestUtils; @@ -23,7 +24,11 @@ import java.util.List; import java.util.Optional; +import static co.rsk.RskTestUtils.generateAddress; import static co.rsk.peg.PegTestUtils.createFederation; +import static co.rsk.peg.PegTxType.PEGIN; +import static co.rsk.peg.PegTxType.PEGOUT_OR_MIGRATION; +import static co.rsk.peg.PegTxType.UNKNOWN; import static co.rsk.peg.PegUtils.*; import static co.rsk.peg.federation.FederationTestUtils.createP2shErpFederation; import static org.junit.jupiter.api.Assertions.*; @@ -35,7 +40,7 @@ class PegUtilsTest { private static final NetworkParameters btcMainnetParams = bridgeMainnetConstants.getBtcParams(); private static final FederationConstants federationMainNetConstants = bridgeMainnetConstants.getFederationConstants(); private static final Context context = new Context(bridgeMainnetConstants.getBtcParams()); - private static final ActivationConfig.ForBlock activations = ActivationConfigsForTest.all().forBlock(0); + private static final ActivationConfig.ForBlock allActivations = ActivationConfigsForTest.all().forBlock(0); private static final int FIRST_OUTPUT_INDEX = 0; private static final int FIRST_INPUT_INDEX = 0; @@ -65,7 +70,7 @@ void getFlyoverDerivationHash_returnsExpectedDerivationHash() { // arrange Address userRefundBtcAddress = BitcoinTestUtils.createP2PKHAddress(btcMainnetParams, "userRefundBtcAddress"); Address lpBtcAddress = BitcoinTestUtils.createP2PKHAddress(btcMainnetParams, "lpBtcAddress"); - Keccak256 derivationArgumentsHash = PegTestUtils.createHash3(5); + Keccak256 derivationArgumentsHash = RskTestUtils.createHash(5); RskAddress lbcAddress = new RskAddress("461750b4824b14c3d9b7702bc6fbb82469082b23"); // act @@ -74,7 +79,7 @@ void getFlyoverDerivationHash_returnsExpectedDerivationHash() { userRefundBtcAddress, lpBtcAddress, lbcAddress, - activations + allActivations ); // assert @@ -174,7 +179,12 @@ void test_getTransactionType_before_rskip379() { // Act IllegalStateException exception = assertThrows(IllegalStateException.class, () -> - PegUtils.getTransactionTypeUsingPegoutIndex(fingerrootActivations, provider, liveFederationWallet, btcTransaction) + PegUtils.getTransactionTypeUsingPegoutIndex( + fingerrootActivations, + provider, + liveFederationWallet, + btcTransaction + ) ); // Assert @@ -193,14 +203,14 @@ void test_getTransactionType_tx_sending_funds_to_unknown_address() { // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.UNKNOWN, pegTxType); + assertEquals(UNKNOWN, pegTxType); } @Test @@ -208,21 +218,21 @@ void test_getTransactionType_pegin_below_minimum_active_fed() { // Arrange Wallet liveFederationWallet = new BridgeBtcWallet(context, Collections.singletonList(activeFederation)); - Coin minimumPeginTxValue = bridgeMainnetConstants.getMinimumPeginTxValue(activations); + Coin minimumPeginTxValue = bridgeMainnetConstants.getMinimumPeginTxValue(allActivations); BtcTransaction btcTransaction = new BtcTransaction(btcMainnetParams); btcTransaction.addInput(BitcoinTestUtils.createHash(1), FIRST_OUTPUT_INDEX, new Script(new byte[]{})); btcTransaction.addOutput(minimumPeginTxValue.minus(Coin.SATOSHI), activeFederation.getAddress()); // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.PEGIN, pegTxType); + assertEquals(PEGIN, pegTxType); } @Test @@ -236,14 +246,14 @@ void test_getTransactionType_pegin_active_fed() { // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.PEGIN, pegTxType); + assertEquals(PEGIN, pegTxType); } @Test @@ -260,14 +270,14 @@ void test_getTransactionType_pegin_output_to_active_fed_and_other_addresses() { // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.PEGIN, pegTxType); + assertEquals(PEGIN, pegTxType); } @Test @@ -284,14 +294,14 @@ void test_getTransactionType_pegin_multiple_outputs_to_active_fed() { // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.PEGIN, pegTxType); + assertEquals(PEGIN, pegTxType); } @Test @@ -317,14 +327,14 @@ void test_getTransactionType_pegin_output_to_retiring_fed_and_other_addresses() // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.PEGIN, pegTxType); + assertEquals(PEGIN, pegTxType); } @Test @@ -338,14 +348,14 @@ void test_getTransactionType_pegin_retiring_fed() { // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.PEGIN, pegTxType); + assertEquals(PEGIN, pegTxType); } @Test @@ -362,14 +372,14 @@ void test_getTransactionType_pegin_multiple_outputs_to_retiring_fed() { // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.PEGIN, pegTxType); + assertEquals(PEGIN, pegTxType); } @Test @@ -385,14 +395,14 @@ void test_getTransactionType_pegin_outputs_to_active_and_retiring_fed() { // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.PEGIN, pegTxType); + assertEquals(PEGIN, pegTxType); } @Test @@ -410,14 +420,14 @@ void test_getTransactionType_pegin_outputs_to_active_and_retiring_fed_and_other_ // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.PEGIN, pegTxType); + assertEquals(PEGIN, pegTxType); } @Test @@ -445,14 +455,14 @@ void test_getTransactionType_pegout_no_change_output() { // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.PEGOUT_OR_MIGRATION, pegTxType); + assertEquals(PEGOUT_OR_MIGRATION, pegTxType); } @Test @@ -471,14 +481,14 @@ void test_getTransactionType_pegout_no_change_output_sighash_no_exists_in_provid // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.UNKNOWN, pegTxType); + assertEquals(UNKNOWN, pegTxType); } @Test @@ -507,14 +517,14 @@ void test_getTransactionType_standard_pegout() { // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.PEGOUT_OR_MIGRATION, pegTxType); + assertEquals(PEGOUT_OR_MIGRATION, pegTxType); } @Test @@ -534,14 +544,14 @@ void test_getTransactionType_standard_pegout_sighash_no_exists_in_provider() { // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.PEGIN, pegTxType); + assertEquals(PEGIN, pegTxType); } @Test @@ -570,14 +580,14 @@ void test_getTransactionType_migration() { // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.PEGOUT_OR_MIGRATION, pegTxType); + assertEquals(PEGOUT_OR_MIGRATION, pegTxType); } @Test @@ -598,14 +608,14 @@ void test_getTransactionType_migration_sighash_no_exists_in_provider() { // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.PEGIN, pegTxType); + assertEquals(PEGIN, pegTxType); } @Test @@ -634,14 +644,14 @@ void test_getTransactionType_migration_from_retired_fed() { // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.PEGOUT_OR_MIGRATION, pegTxType); + assertEquals(PEGOUT_OR_MIGRATION, pegTxType); } @Test @@ -651,15 +661,15 @@ void test_getTransactionType_flyover() { Address userRefundBtcAddress = BitcoinTestUtils.createP2PKHAddress(btcMainnetParams, "userRefundBtcAddress"); Address lpBtcAddress = BitcoinTestUtils.createP2PKHAddress(btcMainnetParams, "lpBtcAddress"); - Keccak256 derivationArgumentsHash = PegTestUtils.createHash3(0); - RskAddress lbcAddress = PegTestUtils.createRandomRskAddress(); + Keccak256 derivationArgumentsHash = RskTestUtils.createHash(0); + RskAddress lbcAddress = generateAddress("lbcAddress"); Keccak256 flyoverDerivationHash = PegUtils.getFlyoverDerivationHash( derivationArgumentsHash, userRefundBtcAddress, lpBtcAddress, lbcAddress, - activations + allActivations ); Address activeFederationAddress = PegTestUtils.getFlyoverAddressFromRedeemScript( @@ -678,14 +688,14 @@ void test_getTransactionType_flyover() { // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.UNKNOWN, pegTxType); + assertEquals(UNKNOWN, pegTxType); } @Test @@ -712,14 +722,14 @@ void test_getTransactionType_flyover_segwit() { // Act PegTxType pegTxType = PegUtils.getTransactionTypeUsingPegoutIndex( - activations, + allActivations, provider, liveFederationWallet, btcTransaction ); // Assert - assertEquals(PegTxType.UNKNOWN, pegTxType); + assertEquals(UNKNOWN, pegTxType); } @Test diff --git a/rskj-core/src/test/java/co/rsk/peg/constants/BridgeConstantsTest.java b/rskj-core/src/test/java/co/rsk/peg/constants/BridgeConstantsTest.java index 3bf8146cb15..34727a5f6ee 100644 --- a/rskj-core/src/test/java/co/rsk/peg/constants/BridgeConstantsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/constants/BridgeConstantsTest.java @@ -197,25 +197,6 @@ void getPegoutTxIndexGracePeriodInBtcBlocks(BridgeConstants bridgeConstants, int assertEquals(expectedValue, pegoutTxIndexGracePeriodInBtcBlocks); } - private static Stream getBtcHeightWhenFederationsPendingBtcUTXOsActivatesArgProvider() { - return Stream.of( - Arguments.of(BridgeMainNetConstants.getInstance(), 10_000_000), - Arguments.of(BridgeTestNetConstants.getInstance(), 10_000_000), - Arguments.of(BridgeTestNet2Constants.getInstance(), 10_000_000), - Arguments.of(new BridgeRegTestConstants(), 260) - ); - } - - @ParameterizedTest - @MethodSource("getBtcHeightWhenFederationsPendingBtcUTXOsActivatesArgProvider") - void getBtcHeightWhenFederationsPendingBtcUTXOsActivates_shouldReturnNetworkValue(BridgeConstants bridgeConstants, int expectedValue) { - // act - int btcHeightWhenFederationsPendingBtcUTXOsActivates = bridgeConstants.getBtcHeightWhenFederationsPendingBtcUTXOsActivates(); - - // assert - assertEquals(expectedValue, btcHeightWhenFederationsPendingBtcUTXOsActivates); - } - private static Stream getBtcHeightWhenBlockIndexActivatesArgProvider() { return Stream.of( Arguments.of(BridgeMainNetConstants.getInstance(), 696_022),