diff --git a/src/main/java/co/rsk/federate/BtcToRskClient.java b/src/main/java/co/rsk/federate/BtcToRskClient.java index d9194b18..b7359348 100644 --- a/src/main/java/co/rsk/federate/BtcToRskClient.java +++ b/src/main/java/co/rsk/federate/BtcToRskClient.java @@ -3,6 +3,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import co.rsk.bitcoinj.core.BtcTransaction; +import co.rsk.federate.config.FedNodeSystemProperties; import co.rsk.peg.constants.BridgeConstants; import co.rsk.federate.adapter.ThinConverter; import co.rsk.federate.bitcoin.BitcoinWrapper; @@ -77,12 +78,15 @@ public class BtcToRskClient implements BlockListener, TransactionListener { ScheduledExecutorService updateBridgeTimer; // Timer that updates the bridge periodically private int amountOfHeadersToSend; // Set amount of headers to inform in a single call private BtcToRskClientFileData fileData = new BtcToRskClientFileData(); + private boolean shouldUpdateBridgeBtcBlockchain; + private boolean shouldUpdateBridgeBtcCoinbaseTransactions; + private boolean shouldUpdateBridgeBtcTransactions; + private boolean shouldUpdateCollections; public BtcToRskClient() {} /// This constructor should only be used by tests. protected BtcToRskClient( - ActivationConfig activationConfig, BitcoinWrapper bitcoinWrapper, FederatorSupport federatorSupport, BridgeConstants bridgeConstants, @@ -90,10 +94,8 @@ protected BtcToRskClient( BtcLockSenderProvider btcLockSenderProvider, PeginInstructionsProvider peginInstructionsProvider, Federation federation, - boolean isUpdateBridgeTimerEnabled, - int amountOfHeadersToSend + FedNodeSystemProperties config ) throws Exception { - this.activationConfig = activationConfig; this.bitcoinWrapper = bitcoinWrapper; this.federatorSupport = federatorSupport; this.bridgeConstants = bridgeConstants; @@ -102,31 +104,25 @@ protected BtcToRskClient( this.btcLockSenderProvider = btcLockSenderProvider; this.peginInstructionsProvider = peginInstructionsProvider; this.federation = federation; - this.isUpdateBridgeTimerEnabled = isUpdateBridgeTimerEnabled; - this.amountOfHeadersToSend = amountOfHeadersToSend; + setConfigVariables(config); } public synchronized void setup( - ActivationConfig activationConfig, BitcoinWrapper bitcoinWrapper, BridgeConstants bridgeConstants, BtcToRskClientFileStorage btcToRskClientFileStorage, BtcLockSenderProvider btcLockSenderProvider, PeginInstructionsProvider peginInstructionsProvider, - boolean isUpdateBridgeTimerEnabled, - int amountOfHeadersToSend + FedNodeSystemProperties config ) throws Exception { - this.activationConfig = activationConfig; this.bridgeConstants = bridgeConstants; this.btcToRskClientFileStorage = btcToRskClientFileStorage; this.restoreFileData(); this.bitcoinWrapper = bitcoinWrapper; this.btcLockSenderProvider = btcLockSenderProvider; this.peginInstructionsProvider = peginInstructionsProvider; - this.isUpdateBridgeTimerEnabled = isUpdateBridgeTimerEnabled; bitcoinWrapper.addBlockListener(this); - this.isUpdateBridgeTimerEnabled = isUpdateBridgeTimerEnabled; - this.amountOfHeadersToSend = amountOfHeadersToSend; + setConfigVariables(config); } public void start(Federation federation) { @@ -204,41 +200,50 @@ public void updateBridge() { } logger.debug("[updateBridge] Updating bridge"); - // Call receiveHeaders - try { - int numberOfBlocksSent = updateBridgeBtcBlockchain(); - logger.debug("[updateBridge] Updated bridge blockchain with {} blocks", numberOfBlocksSent); - } catch (Exception e) { - logger.error(e.getMessage(), e); - panicProcessor.panic("btclock", e.getMessage()); + if(shouldUpdateBridgeBtcBlockchain) { + // Call receiveHeaders + try { + int numberOfBlocksSent = updateBridgeBtcBlockchain(); + logger.debug("[updateBridge] Updated bridge blockchain with {} blocks", numberOfBlocksSent); + } catch (Exception e) { + logger.error(e.getMessage(), e); + panicProcessor.panic("btclock", e.getMessage()); + } } - // Call registerBtcCoinbaseTransaction - try { - logger.debug("[updateBridge] Updating transactions and sending update"); - updateBridgeBtcCoinbaseTransactions(); - } catch (Exception e) { - logger.error(e.getMessage(), e); - panicProcessor.panic("btclock", e.getMessage()); + if(shouldUpdateBridgeBtcCoinbaseTransactions) { + // Call registerBtcCoinbaseTransaction + try { + logger.debug("[updateBridge] Updating transactions and sending update"); + updateBridgeBtcCoinbaseTransactions(); + } catch (Exception e) { + logger.error(e.getMessage(), e); + panicProcessor.panic("btclock", e.getMessage()); + } } - // Call registerBtcTransaction - try { - logger.debug("[updateBridge] Updating transactions and sending update"); - updateBridgeBtcTransactions(); - } catch (Exception e) { - logger.error(e.getMessage(), e); - panicProcessor.panic("btclock", e.getMessage()); + if(shouldUpdateBridgeBtcTransactions) { + // Call registerBtcTransaction + try { + logger.debug("[updateBridge] Updating transactions and sending update"); + updateBridgeBtcTransactions(); + } catch (Exception e) { + logger.error(e.getMessage(), e); + panicProcessor.panic("btclock", e.getMessage()); + } } - // Call updateCollections - try { - logger.debug("[updateBridge] Sending updateCollections"); - federatorSupport.sendUpdateCollections(); - } catch (Exception e) { - logger.error(e.getMessage(), e); - panicProcessor.panic("btclock", e.getMessage()); + if(shouldUpdateCollections) { + // Call updateCollections + try { + logger.debug("[updateBridge] Sending updateCollections"); + federatorSupport.sendUpdateCollections(); + } catch (Exception e) { + logger.error(e.getMessage(), e); + panicProcessor.panic("btclock", e.getMessage()); + } } + } @Override @@ -815,6 +820,17 @@ protected PartialMerkleTree generatePMT(Block block, Transaction transaction) { return generatePMT(block, transaction, transaction.hasWitnesses()); } + private void setConfigVariables(FedNodeSystemProperties config) { + this.activationConfig = config.getActivationConfig(); + this.isUpdateBridgeTimerEnabled = config.isUpdateBridgeTimerEnabled(); + this.isUpdateBridgeTimerEnabled = config.isUpdateBridgeTimerEnabled(); + this.amountOfHeadersToSend = config.getAmountOfHeadersToSend(); + this.shouldUpdateBridgeBtcBlockchain = config.shouldUpdateBridgeBtcBlockchain(); + this.shouldUpdateBridgeBtcCoinbaseTransactions = config.shouldUpdateBridgeBtcCoinbaseTransactions(); + this.shouldUpdateBridgeBtcTransactions = config.shouldUpdateBridgeBtcTransactions(); + this.shouldUpdateCollections = config.shouldUpdateCollections(); + } + public static class Factory { private final FederatorSupport federatorSupport; private final NodeBlockProcessor nodeBlockProcessor; diff --git a/src/main/java/co/rsk/federate/FedNodeRunner.java b/src/main/java/co/rsk/federate/FedNodeRunner.java index c5779913..f183d4c2 100644 --- a/src/main/java/co/rsk/federate/FedNodeRunner.java +++ b/src/main/java/co/rsk/federate/FedNodeRunner.java @@ -283,24 +283,20 @@ private void startFederate() throws Exception { bitcoinWrapper = createAndSetupBitcoinWrapper(btcLockSenderProvider, peginInstructionsProvider); btcToRskClientActive.setup( - config.getActivationConfig(), bitcoinWrapper, bridgeConstants, btcToRskClientFileStorage, btcLockSenderProvider, peginInstructionsProvider, - config.isUpdateBridgeTimerEnabled(), - config.getAmountOfHeadersToSend() + config ); btcToRskClientRetiring.setup( - config.getActivationConfig(), bitcoinWrapper, bridgeConstants, btcToRskClientFileStorage, btcLockSenderProvider, peginInstructionsProvider, - config.isUpdateBridgeTimerEnabled(), - config.getAmountOfHeadersToSend() + config ); BtcLogMonitor btcLogMonitor = new BtcLogMonitor(bitcoinWrapper, federateLogger); btcLogMonitor.start(); diff --git a/src/main/java/co/rsk/federate/config/FedNodeSystemProperties.java b/src/main/java/co/rsk/federate/config/FedNodeSystemProperties.java index 52e4f380..2e5b4519 100644 --- a/src/main/java/co/rsk/federate/config/FedNodeSystemProperties.java +++ b/src/main/java/co/rsk/federate/config/FedNodeSystemProperties.java @@ -97,4 +97,25 @@ public Duration getPegoutSignedCacheTtl() { return Duration.ofMinutes( getInt("federator.pegoutSignedCacheTtlInMinutes", 30)); } + + public boolean shouldUpdateBridgeBtcBlockchain() { + return configFromFiles.hasPath("federator.updateBridgeBtcBlockchain") && + configFromFiles.getBoolean("federator.updateBridgeBtcBlockchain"); + } + + public boolean shouldUpdateBridgeBtcCoinbaseTransactions() { + return configFromFiles.hasPath("federator.updateBridgeBtcCoinbaseTransactions") && + configFromFiles.getBoolean("federator.updateBridgeBtcCoinbaseTransactions"); + } + + public boolean shouldUpdateBridgeBtcTransactions() { + return configFromFiles.hasPath("federator.updateBridgeBtcTransactions") && + configFromFiles.getBoolean("federator.updateBridgeBtcTransactions"); + } + + public boolean shouldUpdateCollections() { + return !configFromFiles.hasPath("federator.updateCollections") || + configFromFiles.getBoolean("federator.updateCollections"); + } + } diff --git a/src/test/java/co/rsk/federate/BtcToRskClientBuilder.java b/src/test/java/co/rsk/federate/BtcToRskClientBuilder.java index d6d55100..20426558 100644 --- a/src/test/java/co/rsk/federate/BtcToRskClientBuilder.java +++ b/src/test/java/co/rsk/federate/BtcToRskClientBuilder.java @@ -5,6 +5,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import co.rsk.federate.config.FedNodeSystemProperties; import co.rsk.peg.constants.BridgeConstants; import co.rsk.federate.bitcoin.BitcoinWrapper; import co.rsk.federate.io.BtcToRskClientFileData; @@ -27,8 +28,7 @@ public class BtcToRskClientBuilder { private BtcLockSenderProvider btcLockSenderProvider; private PeginInstructionsProvider peginInstructionsProvider; private Federation federation; - private boolean isUpdateBridgeTimerEnabled; - private int amountOfHeadersToSend; + private FedNodeSystemProperties config; public BtcToRskClientBuilder() throws PeginInstructionsException, IOException { this.activationConfig = mock(ActivationConfig.class); @@ -39,13 +39,18 @@ public BtcToRskClientBuilder() throws PeginInstructionsException, IOException { this.btcLockSenderProvider = mock(BtcLockSenderProvider.class); this.peginInstructionsProvider = mock(PeginInstructionsProvider.class); this.federation = mock(Federation.class); - this.isUpdateBridgeTimerEnabled = true; - this.amountOfHeadersToSend = 100; + this.config = mock(FedNodeSystemProperties.class); when(activationConfig.forBlock(anyLong())).thenReturn(mock(ActivationConfig.ForBlock.class)); when(btcToRskClientFileStorage.read(any())).thenReturn(new BtcToRskClientFileReadResult(true, new BtcToRskClientFileData())); when(btcLockSenderProvider.tryGetBtcLockSender(any())).thenReturn(Optional.empty()); when(peginInstructionsProvider.buildPeginInstructions(any())).thenReturn(Optional.empty()); + when(config.getActivationConfig()).thenReturn(this.activationConfig); + when(config.shouldUpdateBridgeBtcBlockchain()).thenReturn(true); + when(config.shouldUpdateBridgeBtcTransactions()).thenReturn(true); + when(config.shouldUpdateBridgeBtcCoinbaseTransactions()).thenReturn(true); + when(config.isUpdateBridgeTimerEnabled()).thenReturn(true); + when(config.getAmountOfHeadersToSend()).thenReturn(100); } public BtcToRskClientBuilder withActivationConfig(ActivationConfig activationConfig) { @@ -88,19 +93,14 @@ public BtcToRskClientBuilder withFederation(Federation federation) { return this; } - public BtcToRskClientBuilder withUpdateBridgeTimerEnabled(boolean isUpdateBridgeTimerEnabled) { - this.isUpdateBridgeTimerEnabled = isUpdateBridgeTimerEnabled; - return this; - } - - public BtcToRskClientBuilder withAmountOfHeadersToSend(int amountOfHeadersToSend) { - this.amountOfHeadersToSend = amountOfHeadersToSend; + public BtcToRskClientBuilder withFedNodeSystemProperties(FedNodeSystemProperties config) { + this.config = config; return this; } public BtcToRskClient build () throws Exception { + when(config.getActivationConfig()).thenReturn(activationConfig); return new BtcToRskClient( - activationConfig, bitcoinWrapper, federatorSupport, bridgeConstants, @@ -108,8 +108,7 @@ public BtcToRskClient build () throws Exception { btcLockSenderProvider, peginInstructionsProvider, federation, - isUpdateBridgeTimerEnabled, - amountOfHeadersToSend + config ); } } diff --git a/src/test/java/co/rsk/federate/BtcToRskClientTest.java b/src/test/java/co/rsk/federate/BtcToRskClientTest.java index 20dcbf04..3542e24e 100644 --- a/src/test/java/co/rsk/federate/BtcToRskClientTest.java +++ b/src/test/java/co/rsk/federate/BtcToRskClientTest.java @@ -25,6 +25,11 @@ import co.rsk.bitcoinj.crypto.TransactionSignature; import co.rsk.bitcoinj.params.RegTestParams; import co.rsk.bitcoinj.script.ScriptBuilder; +import co.rsk.cli.CliArgs; +import co.rsk.config.ConfigLoader; +import co.rsk.config.NodeCliFlags; +import co.rsk.config.NodeCliOptions; +import co.rsk.federate.config.FedNodeSystemProperties; import co.rsk.federate.signing.utils.TestUtils; import co.rsk.peg.constants.BridgeConstants; import co.rsk.peg.constants.BridgeRegTestConstants; @@ -59,6 +64,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import static java.util.Objects.nonNull; import java.util.Optional; import java.util.Set; import java.util.stream.Stream; @@ -82,6 +88,7 @@ import org.ethereum.crypto.HashUtil; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.internal.util.MockUtil; import org.spongycastle.util.encoders.Hex; /** @@ -186,6 +193,9 @@ private BtcToRskClient createClientWithMocks( BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.P2PKH); int amountOfHeadersToSend = 100; + FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + when(config.getAmountOfHeadersToSend()).thenReturn(amountOfHeadersToSend); + return btcToRskClientBuilder .withActivationConfig(activationConfig) .withBitcoinWrapper(bitcoinWrapper) @@ -193,7 +203,7 @@ private BtcToRskClient createClientWithMocks( .withBridgeConstants(bridgeRegTestConstants) .withBtcLockSenderProvider(btcLockSenderProvider) .withFederation(activeFederation) - .withAmountOfHeadersToSend(amountOfHeadersToSend) + .withFedNodeSystemProperties(config) .build(); } @@ -205,6 +215,9 @@ private BtcToRskClient createClientWithMocksCustomFederation( BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.P2PKH); int amountOfHeadersToSend = 100; + FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + when(config.getAmountOfHeadersToSend()).thenReturn(amountOfHeadersToSend); + return btcToRskClientBuilder .withActivationConfig(activationConfig) .withBitcoinWrapper(bitcoinWrapper) @@ -212,7 +225,7 @@ private BtcToRskClient createClientWithMocksCustomFederation( .withBridgeConstants(bridgeRegTestConstants) .withBtcLockSenderProvider(btcLockSenderProvider) .withFederation(federation) - .withAmountOfHeadersToSend(amountOfHeadersToSend) + .withFedNodeSystemProperties(config) .build(); } @@ -525,7 +538,8 @@ void onBlock_including_segwit_tx_registers_coinbase() throws Exception { bridgeRegTestConstants, btcToRskClientFileStorageMock, mock(BtcLockSenderProvider.class), - mock(PeginInstructionsProvider.class) + mock(PeginInstructionsProvider.class), + null )); client.onBlock(block); @@ -811,6 +825,9 @@ void updateBlockchainWithBetterBlockchainInWalletBySixHundredBlocks_preRskip89() BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.P2PKH); int amountOfHeadersToSend = 345; + FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + when(config.getAmountOfHeadersToSend()).thenReturn(amountOfHeadersToSend); + BtcToRskClient client = btcToRskClientBuilder .withActivationConfig(activationConfig) .withBitcoinWrapper(bitcoinWrapper) @@ -818,7 +835,7 @@ void updateBlockchainWithBetterBlockchainInWalletBySixHundredBlocks_preRskip89() .withBridgeConstants(bridgeRegTestConstants) .withBtcLockSenderProvider(btcLockSenderProvider) .withFederation(activeFederation) - .withAmountOfHeadersToSend(amountOfHeadersToSend) + .withFedNodeSystemProperties(config) .build(); client.updateBridgeBtcBlockchain(); @@ -939,6 +956,9 @@ void updateBlockchainWithBetterBlockchainInWalletBySixHundredBlocks() throws Exc BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.P2PKH); int amountOfHeadersToSend = 345; + FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + when(config.getAmountOfHeadersToSend()).thenReturn(amountOfHeadersToSend); + BtcToRskClient client = btcToRskClientBuilder .withActivationConfig(activationConfig) .withBitcoinWrapper(bitcoinWrapper) @@ -946,7 +966,7 @@ void updateBlockchainWithBetterBlockchainInWalletBySixHundredBlocks() throws Exc .withBridgeConstants(bridgeRegTestConstants) .withBtcLockSenderProvider(btcLockSenderProvider) .withFederation(activeFederation) - .withAmountOfHeadersToSend(amountOfHeadersToSend) + .withFedNodeSystemProperties(config) .build(); client.updateBridgeBtcBlockchain(); @@ -982,6 +1002,9 @@ void updateBlockchainWithDeepFork() throws Exception { BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.P2PKH); int amountOfHeadersToSend = 215; + FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + when(config.getAmountOfHeadersToSend()).thenReturn(amountOfHeadersToSend); + BtcToRskClient client = btcToRskClientBuilder .withActivationConfig(activationConfig) .withBitcoinWrapper(bitcoinWrapper) @@ -989,7 +1012,7 @@ void updateBlockchainWithDeepFork() throws Exception { .withBridgeConstants(bridgeRegTestConstants) .withBtcLockSenderProvider(btcLockSenderProvider) .withFederation(activeFederation) - .withAmountOfHeadersToSend(amountOfHeadersToSend) + .withFedNodeSystemProperties(config) .build(); // Let's see what happens... @@ -1673,6 +1696,9 @@ void updateTransactionWithMultisig_before_rskip143() throws Exception { int amountOfHeadersToSend = 100; BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.P2SHMULTISIG); + FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + when(config.getAmountOfHeadersToSend()).thenReturn(amountOfHeadersToSend); + BtcToRskClient client = btcToRskClientBuilder .withActivationConfig(activationsConfig) .withBitcoinWrapper(bitcoinWrapper) @@ -1680,7 +1706,7 @@ void updateTransactionWithMultisig_before_rskip143() throws Exception { .withBridgeConstants(bridgeRegTestConstants) .withBtcLockSenderProvider(btcLockSenderProvider) .withFederation(activeFederation) - .withAmountOfHeadersToSend(amountOfHeadersToSend) + .withFedNodeSystemProperties(config) .build(); client.onTransaction(tx); @@ -1766,7 +1792,8 @@ void updateTransaction_with_release_before_rskip143() throws Exception { bridgeRegTestConstants, getMockedBtcToRskClientFileStorage(), new BtcLockSenderProvider(), - new PeginInstructionsProvider() + new PeginInstructionsProvider(), + null ); // Assign Federation to BtcToRskClient @@ -1816,6 +1843,9 @@ void updateTransactionWithSegwitCompatible_before_rskip143() throws Exception { BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.P2SHP2WPKH); int amountOfHeadersToSend = 100; + FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + when(config.getAmountOfHeadersToSend()).thenReturn(amountOfHeadersToSend); + BtcToRskClient client = btcToRskClientBuilder .withActivationConfig(activationsConfig) .withBitcoinWrapper(bitcoinWrapper) @@ -1823,7 +1853,7 @@ void updateTransactionWithSegwitCompatible_before_rskip143() throws Exception { .withBridgeConstants(bridgeRegTestConstants) .withBtcLockSenderProvider(btcLockSenderProvider) .withFederation(activeFederation) - .withAmountOfHeadersToSend(amountOfHeadersToSend) + .withFedNodeSystemProperties(config) .build(); client.onTransaction(tx); @@ -1867,6 +1897,9 @@ void updateTransactionWithSenderUnknown_before_rskip170() throws Exception { BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.UNKNOWN); int amountOfHeadersToSend = 100; + FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + when(config.getAmountOfHeadersToSend()).thenReturn(amountOfHeadersToSend); + BtcToRskClient client = btcToRskClientBuilder .withActivationConfig(activationsConfig) .withBitcoinWrapper(bitcoinWrapper) @@ -1874,7 +1907,7 @@ void updateTransactionWithSenderUnknown_before_rskip170() throws Exception { .withBridgeConstants(bridgeRegTestConstants) .withBtcLockSenderProvider(btcLockSenderProvider) .withFederation(activeFederation) - .withAmountOfHeadersToSend(amountOfHeadersToSend) + .withFedNodeSystemProperties(config) .build(); client.onTransaction(tx); @@ -2249,7 +2282,8 @@ void updateBridgeBtcCoinbaseTransactions_when_coinbase_map_has_readyToBeInformed bridgeRegTestConstants, btcToRskClientFileStorageMock, mock(BtcLockSenderProvider.class), - mock(PeginInstructionsProvider.class) + mock(PeginInstructionsProvider.class), + null ); client.updateBridgeBtcCoinbaseTransactions(); @@ -2288,7 +2322,8 @@ void updateBridgeBtcCoinbaseTransactions_when_coinbase_map_has_readyToBeInformed bridgeRegTestConstants, btcToRskClientFileStorageMock, mock(BtcLockSenderProvider.class), - mock(PeginInstructionsProvider.class) + mock(PeginInstructionsProvider.class), + null ); client.updateBridgeBtcCoinbaseTransactions(); @@ -2331,7 +2366,8 @@ void updateBridgeBtcCoinbaseTransactions_when_coinbase_map_has_readyToBeInformed bridgeRegTestConstants, btcToRskClientFileStorageMock, mock(BtcLockSenderProvider.class), - mock(PeginInstructionsProvider.class) + mock(PeginInstructionsProvider.class), + null ); // The first time the coinbase is not there yet, the second time it is @@ -2377,7 +2413,8 @@ void updateBridgeBtcCoinbaseTransactions_not_removing_from_storage_until_confirm bridgeRegTestConstants, btcToRskClientFileStorageMock, mock(BtcLockSenderProvider.class), - mock(PeginInstructionsProvider.class) + mock(PeginInstructionsProvider.class), + null ); // Calling updateBridgeBtcCoinbaseTransactions twice but failing to register it keeps the storage in place @@ -2421,7 +2458,8 @@ void updateBridge_when_does_not_hasBetterBlockToSync_updates_headers_coinbase_tr bridgeRegTestConstants, getMockedBtcToRskClientFileStorage(), mock(BtcLockSenderProvider.class), - mock(PeginInstructionsProvider.class) + mock(PeginInstructionsProvider.class), + null )); btcToRskClient.updateBridge(); @@ -2432,6 +2470,76 @@ void updateBridge_when_does_not_hasBetterBlockToSync_updates_headers_coinbase_tr verify(federatorSupport, times(1)).sendUpdateCollections(); } + @Test + void updateBridge_whenUpdateBridgeConfigAreFalse_shouldNotCallAny() throws Exception { + NodeBlockProcessor nodeBlockProcessor = mock(NodeBlockProcessor.class); + when(nodeBlockProcessor.hasBetterBlockToSync()).thenReturn(false); + + FederatorSupport federatorSupport = mock(FederatorSupport.class); + when(federatorSupport.getBtcBestBlockChainHeight()).thenReturn(1); + when(federatorSupport.getFederationMember()).thenReturn(fakeMember); + + BitcoinWrapper bitcoinWrapper = mock(BitcoinWrapper.class); + when(bitcoinWrapper.getBestChainHeight()).thenReturn(1); + + FedNodeSystemProperties config = getMockedFedNodeSystemProperties(false); + + BtcToRskClient btcToRskClient = spy(buildWithFactoryAndSetup( + federatorSupport, + nodeBlockProcessor, + activationConfig, + bitcoinWrapper, + bridgeRegTestConstants, + getMockedBtcToRskClientFileStorage(), + mock(BtcLockSenderProvider.class), + mock(PeginInstructionsProvider.class), + config + )); + + btcToRskClient.updateBridge(); + + verify(btcToRskClient, never()).updateBridgeBtcBlockchain(); + verify(btcToRskClient, never()).updateBridgeBtcCoinbaseTransactions(); + verify(btcToRskClient, never()).updateBridgeBtcTransactions(); + verify(federatorSupport, never()).sendUpdateCollections(); + } + + @Test + void updateBridge_noUpdateBridgeConfigDefined_shouldCallUpdatesBridgeMethods() throws Exception { + NodeBlockProcessor nodeBlockProcessor = mock(NodeBlockProcessor.class); + when(nodeBlockProcessor.hasBetterBlockToSync()).thenReturn(false); + + FederatorSupport federatorSupport = mock(FederatorSupport.class); + when(federatorSupport.getBtcBestBlockChainHeight()).thenReturn(1); + when(federatorSupport.getFederationMember()).thenReturn(fakeMember); + + BitcoinWrapper bitcoinWrapper = mock(BitcoinWrapper.class); + when(bitcoinWrapper.getBestChainHeight()).thenReturn(1); + + CliArgs cliArgs = CliArgs.empty(); + ConfigLoader configLoader = new ConfigLoader(cliArgs); + FedNodeSystemProperties config = new FedNodeSystemProperties(configLoader); + + BtcToRskClient btcToRskClient = spy(buildWithFactoryAndSetup( + federatorSupport, + nodeBlockProcessor, + activationConfig, + bitcoinWrapper, + bridgeRegTestConstants, + getMockedBtcToRskClientFileStorage(), + mock(BtcLockSenderProvider.class), + mock(PeginInstructionsProvider.class), + config + )); + + btcToRskClient.updateBridge(); + + verify(btcToRskClient, times(0)).updateBridgeBtcBlockchain(); + verify(btcToRskClient, times(0)).updateBridgeBtcCoinbaseTransactions(); + verify(btcToRskClient, times(0)).updateBridgeBtcTransactions(); + verify(federatorSupport, times(1)).sendUpdateCollections(); + } + @Test void updateBridgeBtcTransactions_tx_with_witness_already_informed() throws Exception { ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); @@ -2480,7 +2588,8 @@ void updateBridgeBtcTransactions_tx_with_witness_already_informed() throws Excep bridgeRegTestConstants, btcToRskClientFileStorageMock, btcLockSenderProvider, - peginInstructionsProvider + peginInstructionsProvider, + null )); btcToRskClient.updateBridge(); @@ -2513,19 +2622,25 @@ private BtcToRskClient buildWithFactoryAndSetup( BridgeConstants bridgeConstants, BtcToRskClientFileStorage btcToRskClientFileStorage, BtcLockSenderProvider btcLockSenderProvider, - PeginInstructionsProvider peginInstructionsProvider) throws Exception { + PeginInstructionsProvider peginInstructionsProvider, + FedNodeSystemProperties fedNodeSystemProperties + ) throws Exception { BtcToRskClient btcToRskClient = buildWithFactory(federatorSupport, nodeBlockProcessor); + FedNodeSystemProperties config = nonNull(fedNodeSystemProperties) ? fedNodeSystemProperties : getMockedFedNodeSystemProperties(true); + + if(MockUtil.isMock(config)) { + when(config.getActivationConfig()).thenReturn(activationConfig); + } + btcToRskClient.setup( - activationConfig, bitcoinWrapper, bridgeConstants, btcToRskClientFileStorage, btcLockSenderProvider, peginInstructionsProvider, - false, - 100 + config ); btcToRskClient.start(activeFederation); @@ -2704,4 +2819,19 @@ private BtcLockSenderProvider mockBtcLockSenderProvider(TxSenderAddressType txSe return btcLockSenderProvider; } + + private FedNodeSystemProperties getMockedFedNodeSystemProperties(boolean defaultBooleanConfigValue) { + + FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + when(config.getAmountOfHeadersToSend()).thenReturn(100); + when(config.isUpdateBridgeTimerEnabled()).thenReturn(defaultBooleanConfigValue); + when(config.shouldUpdateBridgeBtcBlockchain()).thenReturn(defaultBooleanConfigValue); + when(config.shouldUpdateBridgeBtcCoinbaseTransactions()).thenReturn(defaultBooleanConfigValue); + when(config.shouldUpdateBridgeBtcTransactions()).thenReturn(defaultBooleanConfigValue); + when(config.shouldUpdateCollections()).thenReturn(defaultBooleanConfigValue); + + return config; + + } + } diff --git a/src/test/java/co/rsk/federate/FedNodeSystemPropertiesTest.java b/src/test/java/co/rsk/federate/FedNodeSystemPropertiesTest.java index 4d03710a..4124fb69 100644 --- a/src/test/java/co/rsk/federate/FedNodeSystemPropertiesTest.java +++ b/src/test/java/co/rsk/federate/FedNodeSystemPropertiesTest.java @@ -177,4 +177,97 @@ void getPegoutSignedCacheTtl_whenConfigurationPathDoesNotExist_shouldUseDefaultT Duration.ofMinutes(defaultTtlInMinutes), fedNodeSystemProperties.getPegoutSignedCacheTtl()); } + + @Test + void shouldUpdateBridgeBtcBlockchain_whenConfigPathDoesNotExist_shouldReturnFalse() { + when(configLoader.getConfig()).thenReturn(config); + when(config.hasPath("federator.updateBridgeBtcBlockchain")).thenReturn(false); + when(config.root()).thenReturn(configObject); + + FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); + + assertFalse(fedNodeSystemProperties.shouldUpdateBridgeBtcBlockchain()); + } + + @Test + void shouldUpdateBridgeBtcBlockchain_whenConfigPathExists_shouldReturnConfigValue() { + when(configLoader.getConfig()).thenReturn(config); + when(config.hasPath("federator.updateBridgeBtcBlockchain")).thenReturn(true); + when(config.getBoolean("federator.updateBridgeBtcBlockchain")).thenReturn(true); + when(config.root()).thenReturn(configObject); + + FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); + + assertTrue(fedNodeSystemProperties.shouldUpdateBridgeBtcBlockchain()); + } + + @Test + void shouldUpdateBridgeBtcCoinbaseTransactions_whenConfigPathDoesNotExist_shouldReturnFalse() { + when(configLoader.getConfig()).thenReturn(config); + when(config.hasPath("federator.updateBridgeBtcCoinbaseTransactions")).thenReturn(false); + when(config.root()).thenReturn(configObject); + + FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); + + assertFalse(fedNodeSystemProperties.shouldUpdateBridgeBtcCoinbaseTransactions()); + } + + @Test + void shouldUpdateBridgeBtcCoinbaseTransactions_whenConfigPathExists_shouldReturnConfigValue() { + when(configLoader.getConfig()).thenReturn(config); + when(config.hasPath("federator.updateBridgeBtcCoinbaseTransactions")).thenReturn(true); + when(config.getBoolean("federator.updateBridgeBtcCoinbaseTransactions")).thenReturn(true); + when(config.root()).thenReturn(configObject); + + FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); + + assertTrue(fedNodeSystemProperties.shouldUpdateBridgeBtcCoinbaseTransactions()); + } + + @Test + void shouldUpdateBridgeBtcTransactions_whenConfigPathDoesNotExist_shouldReturnFalse() { + when(configLoader.getConfig()).thenReturn(config); + when(config.hasPath("federator.updateBridgeBtcTransactions")).thenReturn(false); + when(config.root()).thenReturn(configObject); + + FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); + + assertFalse(fedNodeSystemProperties.shouldUpdateBridgeBtcTransactions()); + } + + @Test + void shouldUpdateBridgeBtcTransactions_whenConfigPathExists_shouldReturnConfigValue() { + when(configLoader.getConfig()).thenReturn(config); + when(config.hasPath("federator.updateBridgeBtcTransactions")).thenReturn(true); + when(config.getBoolean("federator.updateBridgeBtcTransactions")).thenReturn(true); + when(config.root()).thenReturn(configObject); + + FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); + + assertTrue(fedNodeSystemProperties.shouldUpdateBridgeBtcTransactions()); + } + + @Test + void shouldUpdateCollections_whenConfigPathDoesNotExist_shouldReturnTrue() { + when(configLoader.getConfig()).thenReturn(config); + when(config.hasPath("federator.updateCollections")).thenReturn(false); + when(config.root()).thenReturn(configObject); + + FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); + + assertTrue(fedNodeSystemProperties.shouldUpdateCollections()); + } + + @Test + void shouldUpdateCollections_whenConfigPathExists_shouldReturnConfigValue() { + when(configLoader.getConfig()).thenReturn(config); + when(config.hasPath("federator.updateCollections")).thenReturn(true); + when(config.getBoolean("federator.updateCollections")).thenReturn(true); + when(config.root()).thenReturn(configObject); + + FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); + + assertTrue(fedNodeSystemProperties.shouldUpdateCollections()); + } + }