diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationSupportImpl.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationSupportImpl.java index 05c36ff4a6d..30dc4dcd2cf 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationSupportImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationSupportImpl.java @@ -604,7 +604,7 @@ private Integer addFederatorPublicKeyMultikey(boolean dryRun, BtcECKey btcKey, E * @return 1 upon success, -1 if there was no pending federation, -2 if the pending federation was incomplete, * -3 if the given hash doesn't match the current pending federation's hash. */ - private Integer commitFederation(boolean dryRun, Keccak256 hash, BridgeEventLogger eventLogger) { + protected Integer commitFederation(boolean dryRun, Keccak256 hash, BridgeEventLogger eventLogger) { PendingFederation currentPendingFederation = provider.getPendingFederation(); if (currentPendingFederation == null) { diff --git a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/PowpegMigrationTest.java similarity index 90% rename from rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java rename to rskj-core/src/test/java/co/rsk/peg/federation/PowpegMigrationTest.java index f90c618a714..ab16b475c98 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/PowpegMigrationTest.java @@ -1,21 +1,24 @@ -package co.rsk.peg; +package co.rsk.peg.federation; import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.script.*; import co.rsk.bitcoinj.store.BlockStoreException; import co.rsk.bitcoinj.store.BtcBlockStore; +import co.rsk.peg.*; import co.rsk.peg.constants.BridgeConstants; import co.rsk.peg.constants.BridgeMainNetConstants; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.db.MutableTrieCache; import co.rsk.db.MutableTrieImpl; +import co.rsk.peg.federation.constants.FederationConstants; import co.rsk.peg.feeperkb.FeePerKbSupport; +import co.rsk.peg.storage.BridgeStorageAccessorImpl; +import co.rsk.peg.storage.StorageAccessor; import co.rsk.peg.vote.ABICallSpec; import co.rsk.peg.bitcoin.BitcoinUtils; import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilder; import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; -import co.rsk.peg.federation.*; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; import co.rsk.peg.utils.BridgeEventLogger; import co.rsk.test.builders.BridgeSupportBuilder; @@ -63,7 +66,7 @@ class PowpegMigrationTest { * I can use this to validate that a certain redeemscript trying to spend this utxo generates the corresponding address */ private final Map whoCanSpendTheseUtxos = new HashMap<>(); - private final BridgeConstants bridgeConstants = BridgeMainNetConstants.getInstance(); + private final BridgeConstants bridgeMainnetConstants = BridgeMainNetConstants.getInstance(); private void testChangePowpeg( FederationType oldPowPegFederationType, @@ -77,13 +80,14 @@ private void testChangePowpeg( ActivationConfig.ForBlock activations, long migrationShouldFinishAfterThisAmountOfBlocks ) throws Exception { + NetworkParameters btcParams = bridgeConstants.getBtcParams(); Repository repository = new MutableRepository( new MutableTrieCache(new MutableTrieImpl(null, new Trie())) ); BridgeStorageProvider bridgeStorageProvider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants, + btcParams, activations ); @@ -91,7 +95,7 @@ private void testChangePowpeg( bridgeStorageProvider.setLockingCap(bridgeConstants.getMaxRbtc()); BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( - bridgeConstants.getBtcParams(), + btcParams, 100, 100 ); @@ -138,9 +142,8 @@ private void testChangePowpeg( theseKeys.getRight() ) ).collect(Collectors.toList()); - NetworkParameters btcParams = bridgeConstants.getBtcParams(); - List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); - long activationDelay = bridgeConstants.getErpFedActivationDelay(); + List erpPubKeys = bridgeConstants.getFederationConstants().getErpFedPubKeysList(); + long activationDelay = bridgeConstants.getFederationConstants().getErpFedActivationDelay(); Federation originalPowpeg; Instant creationTime = Instant.now(); @@ -166,9 +169,12 @@ private void testChangePowpeg( assertEquals(oldPowPegAddress, originalPowpeg.getAddress()); + StorageAccessor bridgeStorageAccessor = new BridgeStorageAccessorImpl(repository); + FederationStorageProvider federationStorageProvider = new FederationStorageProviderImpl(bridgeStorageAccessor); + // Set original powpeg information - bridgeStorageProvider.setNewFederation(originalPowpeg); - bridgeStorageProvider.getNewFederationBtcUTXOs().addAll(existingUtxos); + federationStorageProvider.setNewFederation(originalPowpeg); + federationStorageProvider.getNewFederationBtcUTXOs(btcParams, activations).addAll(existingUtxos); // Create Pending federation (doing this to avoid voting the pending Federation) List newPowpegMembers = newPowPegKeys.stream().map(newPowpegKey -> @@ -183,16 +189,17 @@ private void testChangePowpeg( Federation newFederation = pendingFederation.buildFederation( Instant.now(), 0, - bridgeConstants, + bridgeConstants.getFederationConstants(), activations ); // Set pending powpeg information - bridgeStorageProvider.setPendingFederation(pendingFederation); - bridgeStorageProvider.save(); + federationStorageProvider.setPendingFederation(pendingFederation); + federationStorageProvider.save(btcParams, activations); // Proceed with the powpeg change - bridgeSupport.commitFederation(false, pendingFederation.getHash()); + FederationSupportImpl federationSupport = new FederationSupportImpl(bridgeConstants.getFederationConstants(), federationStorageProvider, initialBlock, activations); + federationSupport.commitFederation(false, pendingFederation.getHash(), bridgeEventLogger); ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Federation.class); verify(bridgeEventLogger).logCommitFederation( @@ -223,18 +230,18 @@ private void testChangePowpeg( } // Verify UTXOs were moved to pending POWpeg - List utxosToMigrate = bridgeStorageProvider.getOldFederationBtcUTXOs(); + List utxosToMigrate = federationStorageProvider.getOldFederationBtcUTXOs(); for (UTXO utxo : existingUtxos) { assertTrue(utxosToMigrate.stream().anyMatch(storedUtxo -> storedUtxo.equals(utxo))); } - assertTrue(bridgeStorageProvider.getNewFederationBtcUTXOs().isEmpty()); + assertTrue(federationStorageProvider.getNewFederationBtcUTXOs(btcParams, activations).isEmpty()); // Trying to create a new powpeg again should fail // -2 corresponds to a new powpeg was elected and the Bridge is waiting for this new powpeg to activate attemptToCreateNewFederation(bridgeSupport, -2); // No change in active powpeg - assertEquals(oldPowPegAddress, bridgeSupport.getFederationAddress()); + assertEquals(oldPowPegAddress, bridgeSupport.getActiveFederationAddress()); assertNull(bridgeSupport.getRetiringFederationAddress()); // Update collections should not trigger migration @@ -248,7 +255,7 @@ private void testChangePowpeg( activations, bridgeSupport, bridgeConstants, - bridgeStorageProvider, + federationStorageProvider, btcBlockStore, oldPowPegAddress, newPowPegAddress, @@ -257,9 +264,11 @@ private void testChangePowpeg( ); testFlyoverPegins( + activations, bridgeSupport, bridgeConstants, bridgeStorageProvider, + federationStorageProvider, btcBlockStore, originalPowpeg, newFederation, @@ -273,6 +282,7 @@ private void testChangePowpeg( testPegouts( bridgeSupport, bridgeStorageProvider, + federationStorageProvider, bridgeConstants, activations, blockNumber, @@ -287,7 +297,7 @@ private void testChangePowpeg( */ // 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(activations); + blockNumber = initialBlock.getNumber() + bridgeConstants.getFederationConstants().getFederationActivationAge(activations); Block activationBlock = mock(Block.class); doReturn(blockNumber).when(activationBlock).getNumber(); @@ -297,7 +307,7 @@ private void testChangePowpeg( ActivationConfig.ForBlock activationsBeforeRSKIP383 = mock(ActivationConfig.ForBlock.class); when(activationsBeforeRSKIP383.isActive(ConsensusRule.RSKIP383)).thenReturn(false); - long legacyFedActivationBlockNumber = initialBlock.getNumber() + bridgeConstants.getFederationActivationAge(activationsBeforeRSKIP383); + long legacyFedActivationBlockNumber = initialBlock.getNumber() + bridgeConstants.getFederationConstants().getFederationActivationAge(activationsBeforeRSKIP383); Assertions.assertTrue(blockNumber > legacyFedActivationBlockNumber); Block legacyFedActivationBlock = mock(Block.class); @@ -315,7 +325,7 @@ private void testChangePowpeg( .withFeePerKbSupport(feePerKbSupport) .build(); - assertEquals(oldPowPegAddress, bridgeSupport.getFederationAddress()); + assertEquals(oldPowPegAddress, bridgeSupport.getActiveFederationAddress()); assertNull(bridgeSupport.getRetiringFederation()); } @@ -332,10 +342,10 @@ private void testChangePowpeg( .build(); // New active powpeg and retiring powpeg - assertEquals(newPowPegAddress, bridgeSupport.getFederationAddress()); + assertEquals(newPowPegAddress, bridgeSupport.getActiveFederationAddress()); assertEquals(oldPowPegAddress, bridgeSupport.getRetiringFederationAddress()); - if (bridgeConstants.getFundsMigrationAgeSinceActivationBegin() > 0) { + if (bridgeConstants.getFederationConstants().getFundsMigrationAgeSinceActivationBegin() > 0) { // No migration yet assertTrue(bridgeStorageProvider.getPegoutsWaitingForConfirmations().getEntries().isEmpty()); updateCollectionsTx = Transaction.builder().nonce(new BtcECKey().getPrivKey()).build(); @@ -352,7 +362,7 @@ private void testChangePowpeg( activations, bridgeSupport, bridgeConstants, - bridgeStorageProvider, + federationStorageProvider, btcBlockStore, oldPowPegAddress, newPowPegAddress, @@ -361,9 +371,11 @@ private void testChangePowpeg( ); testFlyoverPegins( + activations, bridgeSupport, bridgeConstants, bridgeStorageProvider, + federationStorageProvider, btcBlockStore, originalPowpeg, newFederation, @@ -376,7 +388,7 @@ private void testChangePowpeg( */ // Move the required blocks ahead for the new powpeg to start migrating - blockNumber = blockNumber + bridgeConstants.getFundsMigrationAgeSinceActivationBegin() + 1; + blockNumber = blockNumber + bridgeConstants.getFederationConstants().getFundsMigrationAgeSinceActivationBegin() + 1; Block migrationBlock = mock(Block.class); // Adding 1 as the migration is exclusive doReturn(blockNumber).when(migrationBlock).getNumber(); @@ -394,7 +406,7 @@ private void testChangePowpeg( .build(); // New active powpeg and retiring powpeg - assertEquals(newPowPegAddress, bridgeSupport.getFederationAddress()); + assertEquals(newPowPegAddress, bridgeSupport.getActiveFederationAddress()); assertEquals(oldPowPegAddress, bridgeSupport.getRetiringFederationAddress()); // Trying to create a new powpeg again should fail @@ -410,7 +422,7 @@ private void testChangePowpeg( : 1; // Migrate while there are still utxos to migrate - while (!bridgeStorageProvider.getOldFederationBtcUTXOs().isEmpty()) { + while (!federationStorageProvider.getOldFederationBtcUTXOs().isEmpty()) { updateCollectionsTx = Transaction.builder().nonce(new BtcECKey().getPrivKey()).build(); bridgeSupport.updateCollections(updateCollectionsTx); } @@ -441,14 +453,14 @@ private void testChangePowpeg( } } - verifyPegouts(bridgeStorageProvider); + verifyPegouts(bridgeStorageProvider, federationStorageProvider, bridgeConstants.getFederationConstants(), activations); // peg-in during migration testPegins( activations, bridgeSupport, bridgeConstants, - bridgeStorageProvider, + federationStorageProvider, btcBlockStore, oldPowPegAddress, newPowPegAddress, @@ -457,9 +469,11 @@ private void testChangePowpeg( ); testFlyoverPegins( + activations, bridgeSupport, bridgeConstants, bridgeStorageProvider, + federationStorageProvider, btcBlockStore, originalPowpeg, newFederation, @@ -469,11 +483,11 @@ private void testChangePowpeg( // Should be migrated int newlyAddedUtxos = activations.isActive(ConsensusRule.RSKIP294) ? - (int) Math.ceil((double) bridgeStorageProvider.getOldFederationBtcUTXOs().size() / bridgeConstants.getMaxInputsPerPegoutTransaction()) : + (int) Math.ceil((double) federationStorageProvider.getOldFederationBtcUTXOs().size() / bridgeConstants.getMaxInputsPerPegoutTransaction()) : 1; // Migrate while there are still utxos to migrate - while (!bridgeStorageProvider.getOldFederationBtcUTXOs().isEmpty()) { + while (!federationStorageProvider.getOldFederationBtcUTXOs().isEmpty()) { updateCollectionsTx = Transaction.builder().nonce(new BtcECKey().getPrivKey()).build(); bridgeSupport.updateCollections(updateCollectionsTx); } @@ -489,7 +503,7 @@ private void testChangePowpeg( .map(PegoutsWaitingForConfirmations.Entry::getBtcTransaction) .forEach(pegoutTx -> verifyPegoutTxSigHashIndex(activations, bridgeStorageProvider, pegoutTx)); - verifyPegouts(bridgeStorageProvider); + verifyPegouts(bridgeStorageProvider, federationStorageProvider, bridgeConstants.getFederationConstants(), activations); // peg-out during migration assertTrue(bridgeStorageProvider.getReleaseRequestQueue().getEntries().isEmpty()); @@ -497,6 +511,7 @@ private void testChangePowpeg( testPegouts( bridgeSupport, bridgeStorageProvider, + federationStorageProvider, bridgeConstants, activations, blockNumber, @@ -511,13 +526,13 @@ private void testChangePowpeg( */ // Move the height to the block previous to the migration finishing, it should keep on migrating - blockNumber = blockNumber + bridgeConstants.getFundsMigrationAgeSinceActivationEnd(activations) - 2; + blockNumber = blockNumber + bridgeConstants.getFederationConstants().getFundsMigrationAgeSinceActivationEnd(activations) - 2; Block migrationFinishingBlock = mock(Block.class); // Substracting 2 as the previous height was activation + 1 and migration is exclusive doReturn(blockNumber).when(migrationFinishingBlock).getNumber(); assertEquals( migrationShouldFinishAfterThisAmountOfBlocks, - bridgeConstants.getFundsMigrationAgeSinceActivationEnd(activations) + bridgeConstants.getFederationConstants().getFundsMigrationAgeSinceActivationEnd(activations) ); bridgeSupport = new BridgeSupportBuilder() @@ -533,7 +548,7 @@ private void testChangePowpeg( .build(); // New active powpeg and retiring powpeg is still there - assertEquals(newPowPegAddress, bridgeSupport.getFederationAddress()); + assertEquals(newPowPegAddress, bridgeSupport.getActiveFederationAddress()); assertEquals(oldPowPegAddress, bridgeSupport.getRetiringFederationAddress()); // Last update collections before the migration finishes @@ -541,7 +556,7 @@ private void testChangePowpeg( bridgeSupport.updateCollections(updateCollectionsTx); // New active powpeg and retiring powpeg is still there - assertEquals(newPowPegAddress, bridgeSupport.getFederationAddress()); + assertEquals(newPowPegAddress, bridgeSupport.getActiveFederationAddress()); assertEquals(oldPowPegAddress, bridgeSupport.getRetiringFederationAddress()); // Move the height to the block after the migration finishes @@ -550,7 +565,7 @@ private void testChangePowpeg( doReturn(blockNumber).when(migrationFinishedBlock).getNumber(); assertEquals( migrationShouldFinishAfterThisAmountOfBlocks, - bridgeConstants.getFundsMigrationAgeSinceActivationEnd(activations) + bridgeConstants.getFederationConstants().getFundsMigrationAgeSinceActivationEnd(activations) ); bridgeSupport = new BridgeSupportBuilder() @@ -566,7 +581,7 @@ private void testChangePowpeg( .build(); // New active powpeg and retiring powpeg is still there - assertEquals(newPowPegAddress, bridgeSupport.getFederationAddress()); + assertEquals(newPowPegAddress, bridgeSupport.getActiveFederationAddress()); assertEquals(oldPowPegAddress, bridgeSupport.getRetiringFederationAddress()); // The first update collections after the migration finished should get rid of the retiring powpeg @@ -574,7 +589,7 @@ private void testChangePowpeg( bridgeSupport.updateCollections(updateCollectionsTx); // New active powpeg still there, retiring powpeg no longer there - assertEquals(newPowPegAddress, bridgeSupport.getFederationAddress()); + assertEquals(newPowPegAddress, bridgeSupport.getActiveFederationAddress()); assertNull(bridgeSupport.getRetiringFederationAddress()); // peg-in after migration @@ -582,7 +597,7 @@ private void testChangePowpeg( activations, bridgeSupport, bridgeConstants, - bridgeStorageProvider, + federationStorageProvider, btcBlockStore, oldPowPegAddress, newPowPegAddress, @@ -591,9 +606,11 @@ private void testChangePowpeg( ); testFlyoverPegins( + activations, bridgeSupport, bridgeConstants, bridgeStorageProvider, + federationStorageProvider, btcBlockStore, originalPowpeg, newFederation, @@ -601,7 +618,7 @@ private void testChangePowpeg( true ); - Optional