diff --git a/src/main/java/co/rsk/federate/BridgeTransactionSender.java b/src/main/java/co/rsk/federate/BridgeTransactionSender.java index c346654e..c087d42b 100644 --- a/src/main/java/co/rsk/federate/BridgeTransactionSender.java +++ b/src/main/java/co/rsk/federate/BridgeTransactionSender.java @@ -4,7 +4,7 @@ import co.rsk.core.ReversibleTransactionExecutor; import co.rsk.core.RskAddress; import co.rsk.core.bc.PendingState; -import co.rsk.federate.config.FedNodeSystemProperties; +import co.rsk.federate.config.PowpegNodeSystemProperties; import co.rsk.federate.gas.GasPriceProviderFactory; import co.rsk.federate.gas.IGasPriceProvider; import co.rsk.federate.signing.ECDSASigner; @@ -20,7 +20,7 @@ import java.math.BigInteger; -import static co.rsk.federate.signing.PowPegNodeKeyId.RSK_KEY_ID; +import static co.rsk.federate.signing.PowPegNodeKeyId.RSK; public class BridgeTransactionSender { @@ -31,14 +31,14 @@ public class BridgeTransactionSender { private final TransactionPool transactionPool; private final ReversibleTransactionExecutor reversibleTransactionExecutor; private final Coin gasPrice; - private final FedNodeSystemProperties config; + private final PowpegNodeSystemProperties config; private final IGasPriceProvider gasPriceProvider; public BridgeTransactionSender(Ethereum ethereum, Blockchain blockchain, TransactionPool transactionPool, ReversibleTransactionExecutor reversibleTransactionExecutor, - FedNodeSystemProperties config) { + PowpegNodeSystemProperties config) { this.ethereum = ethereum; this.blockchain = blockchain; this.transactionPool = transactionPool; @@ -111,7 +111,7 @@ public synchronized void sendRskTx(RskAddress federatorAddress, functionArgs); try { SignerMessageV1 messageToSign = new SignerMessageV1(rskTx.getRawHash().getBytes()); - ECKey.ECDSASignature txSignature = signer.sign(RSK_KEY_ID.getKeyId(), messageToSign); + ECKey.ECDSASignature txSignature = signer.sign(RSK.getKeyId(), messageToSign); rskTx.setSignature(txSignature); LOGGER.debug("[tx={} | nonce={} | method={}] Submit to Bridge", rskTx.getHash(), nonce, function.name); ethereum.submitTransaction(rskTx); diff --git a/src/main/java/co/rsk/federate/BtcToRskClient.java b/src/main/java/co/rsk/federate/BtcToRskClient.java index b7359348..84a8c677 100644 --- a/src/main/java/co/rsk/federate/BtcToRskClient.java +++ b/src/main/java/co/rsk/federate/BtcToRskClient.java @@ -3,7 +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.federate.config.PowpegNodeSystemProperties; import co.rsk.peg.constants.BridgeConstants; import co.rsk.federate.adapter.ThinConverter; import co.rsk.federate.bitcoin.BitcoinWrapper; @@ -94,7 +94,7 @@ protected BtcToRskClient( BtcLockSenderProvider btcLockSenderProvider, PeginInstructionsProvider peginInstructionsProvider, Federation federation, - FedNodeSystemProperties config + PowpegNodeSystemProperties config ) throws Exception { this.bitcoinWrapper = bitcoinWrapper; this.federatorSupport = federatorSupport; @@ -113,7 +113,7 @@ public synchronized void setup( BtcToRskClientFileStorage btcToRskClientFileStorage, BtcLockSenderProvider btcLockSenderProvider, PeginInstructionsProvider peginInstructionsProvider, - FedNodeSystemProperties config + PowpegNodeSystemProperties config ) throws Exception { this.bridgeConstants = bridgeConstants; this.btcToRskClientFileStorage = btcToRskClientFileStorage; @@ -820,7 +820,7 @@ protected PartialMerkleTree generatePMT(Block block, Transaction transaction) { return generatePMT(block, transaction, transaction.hasWitnesses()); } - private void setConfigVariables(FedNodeSystemProperties config) { + private void setConfigVariables(PowpegNodeSystemProperties config) { this.activationConfig = config.getActivationConfig(); this.isUpdateBridgeTimerEnabled = config.isUpdateBridgeTimerEnabled(); this.isUpdateBridgeTimerEnabled = config.isUpdateBridgeTimerEnabled(); diff --git a/src/main/java/co/rsk/federate/FedNodeContext.java b/src/main/java/co/rsk/federate/FedNodeContext.java index d9f40529..88a76fe8 100644 --- a/src/main/java/co/rsk/federate/FedNodeContext.java +++ b/src/main/java/co/rsk/federate/FedNodeContext.java @@ -22,7 +22,7 @@ import co.rsk.config.ConfigLoader; import co.rsk.config.RskSystemProperties; import co.rsk.federate.btcreleaseclient.BtcReleaseClient; -import co.rsk.federate.config.FedNodeSystemProperties; +import co.rsk.federate.config.PowpegNodeSystemProperties; import co.rsk.federate.log.FederateLogger; import co.rsk.federate.log.RskLogMonitor; import co.rsk.federate.rpc.Web3FederateImpl; @@ -39,7 +39,7 @@ */ public class FedNodeContext extends RskContext { - private FedNodeSystemProperties fedNodeSystemProperties; + private PowpegNodeSystemProperties powpegNodeSystemProperties; private BtcToRskClient.Factory btcToRskClientFactory; private BtcToRskClient btcToRskClientActive; private BtcToRskClient btcToRskClientRetiring; @@ -59,7 +59,7 @@ public NodeRunner buildNodeRunner() { new BtcReleaseClient( getRsk(), getFederatorSupport(), - getFedNodeSystemProperties(), + getPowpegNodeSystemProperties(), getNodeBlockProcessor() ), getFederationWatcher(), @@ -67,7 +67,7 @@ public NodeRunner buildNodeRunner() { getFederateLogger(), new RskLogMonitor(getRsk(), getFederateLogger()), super.buildNodeRunner(), - getFedNodeSystemProperties(), + getPowpegNodeSystemProperties(), new HSMClientProtocolFactory(), new HSMBookKeepingClientProvider(), this @@ -76,7 +76,7 @@ public NodeRunner buildNodeRunner() { @Override public RskSystemProperties getRskSystemProperties() { - return getFedNodeSystemProperties(); + return getPowpegNodeSystemProperties(); } @Override @@ -175,11 +175,11 @@ private FederatorSupport getFederatorSupport() { getBlockchain(), getTransactionPool(), getReversibleTransactionExecutor(), - getFedNodeSystemProperties() + getPowpegNodeSystemProperties() ); federatorSupport = new FederatorSupport( getBlockchain(), - getFedNodeSystemProperties(), + getPowpegNodeSystemProperties(), bridgeTransactionSender ); } @@ -187,11 +187,11 @@ private FederatorSupport getFederatorSupport() { return federatorSupport; } - private FedNodeSystemProperties getFedNodeSystemProperties() { - if (fedNodeSystemProperties == null) { - fedNodeSystemProperties = new FedNodeSystemProperties(new ConfigLoader(getCliArgs())); + private PowpegNodeSystemProperties getPowpegNodeSystemProperties() { + if (powpegNodeSystemProperties == null) { + powpegNodeSystemProperties = new PowpegNodeSystemProperties(new ConfigLoader(getCliArgs())); } - return fedNodeSystemProperties; + return powpegNodeSystemProperties; } } diff --git a/src/main/java/co/rsk/federate/FedNodeRunner.java b/src/main/java/co/rsk/federate/FedNodeRunner.java index b7c96c8e..b5f876e8 100644 --- a/src/main/java/co/rsk/federate/FedNodeRunner.java +++ b/src/main/java/co/rsk/federate/FedNodeRunner.java @@ -17,8 +17,11 @@ */ package co.rsk.federate; +import static co.rsk.federate.signing.PowPegNodeKeyId.*; + import co.rsk.NodeRunner; import co.rsk.bitcoinj.core.BtcECKey; +import co.rsk.core.RskAddress; import co.rsk.federate.signing.hsm.HSMVersion; import co.rsk.peg.constants.BridgeConstants; import co.rsk.federate.adapter.ThinConverter; @@ -28,9 +31,10 @@ import co.rsk.federate.btcreleaseclient.BtcReleaseClient; import co.rsk.federate.btcreleaseclient.BtcReleaseClientStorageAccessor; import co.rsk.federate.btcreleaseclient.BtcReleaseClientStorageSynchronizer; -import co.rsk.federate.config.FedNodeSystemProperties; -import co.rsk.federate.config.PowHSMBookkeepingConfig; -import co.rsk.federate.config.SignerConfig; +import co.rsk.federate.config.PowpegNodeSystemProperties; +import co.rsk.federate.signing.config.SignerConfig; +import co.rsk.federate.signing.config.SignerType; +import co.rsk.federate.signing.hsm.config.PowHSMConfig; import co.rsk.federate.io.*; import co.rsk.federate.log.BtcLogMonitor; import co.rsk.federate.log.FederateLogger; @@ -57,7 +61,6 @@ import org.ethereum.crypto.ECKey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import javax.annotation.PreDestroy; import java.io.File; import java.net.UnknownHostException; @@ -66,14 +69,12 @@ import java.util.Optional; import java.util.stream.Stream; -import static co.rsk.federate.signing.PowPegNodeKeyId.*; - /** * Created by mario on 31/03/17. */ public class FedNodeRunner implements NodeRunner { - private static final Logger LOGGER = LoggerFactory.getLogger(FedNodeRunner.class); + private static final Logger logger = LoggerFactory.getLogger(FedNodeRunner.class); private final BtcToRskClient btcToRskClientActive; private final BtcToRskClient btcToRskClientRetiring; private final BtcReleaseClient btcReleaseClient; @@ -82,7 +83,7 @@ public class FedNodeRunner implements NodeRunner { private final FederateLogger federateLogger; private final RskLogMonitor rskLogMonitor; private final NodeRunner fullNodeRunner; - private final FedNodeSystemProperties config; + private final PowpegNodeSystemProperties config; private final FedNodeContext fedNodeContext; private final BridgeConstants bridgeConstants; private final HSMClientProtocolFactory hsmClientProtocolFactory; @@ -104,7 +105,7 @@ public FedNodeRunner( FederateLogger federateLogger, RskLogMonitor rskLogMonitor, NodeRunner fullNodeRunner, - FedNodeSystemProperties config, + PowpegNodeSystemProperties config, HSMClientProtocolFactory hsmClientProtocolFactory, HSMBookKeepingClientProvider hsmBookKeepingClientProvider, FedNodeContext fedNodeContext @@ -126,50 +127,57 @@ public FedNodeRunner( @Override public void run() throws Exception { - LOGGER.debug("[run] Starting RSK"); + logger.debug("[run] Starting RSK"); signer = buildSigner(); - SignerConfig signerConfig = this.config.signerConfig(BTC_KEY_ID.getId()); - if (signerConfig != null && "hsm".equals(signerConfig.getType())) { - PowHSMBookkeepingConfig bookKeepingConfig = new PowHSMBookkeepingConfig( - signerConfig, - bridgeConstants.getBtcParamsString() - ); - - HSMClientProtocol protocol = hsmClientProtocolFactory.buildHSMClientProtocolFromConfig(signerConfig); - int hsmVersion = protocol.getVersion(); - LOGGER.debug("[run] Using HSM version {}", hsmVersion); - if (HSMVersion.isPowHSM(hsmVersion)) { - hsmBookkeepingClient = buildBookKeepingClient(protocol, bookKeepingConfig); - hsmBookkeepingService = buildBookKeepingService( - hsmBookkeepingClient, - bookKeepingConfig - ); - } + SignerConfig btcSignerConfig = config.signerConfig(BTC.getId()); + if (btcSignerConfig != null && btcSignerConfig.getSignerType() == SignerType.HSM) { + startBookkeepingServices(); } - if(!this.checkFederateRequirements()) { - LOGGER.error("[run] Error validating Fed-Node Requirements"); + + if (!this.checkFederateRequirements()) { + logger.error("[run] Error validating Fed-Node Requirements"); return; } - LOGGER.info("[run] Signers: {}", signer.getVersionString()); + + logger.info("[run] Signers: {}", signer.getVersionString()); configureFederatorSupport(); fullNodeRunner.run(); startFederate(); - signer.addListener((l -> { - LOGGER.error("[run] Signer informed unrecoverable state, shutting down", l); + signer.addListener(l -> { + logger.error("[run] Signer informed unrecoverable state, shutting down", l); this.shutdown(); - })); + }); + + RskAddress pegnatoryRskAddress = new RskAddress(this.member.getRskPublicKey().getAddress()); + logger.info("[run] Federated node started"); + logger.info("[run] RSK address: {}", pegnatoryRskAddress); + } - LOGGER.info("[run] Federated node started"); - LOGGER.info("[run] RSK address: {}", Hex.toHexString(this.member.getRskPublicKey().getAddress())); + private void startBookkeepingServices() throws SignerException, HSMClientException { + PowHSMConfig powHsmConfig = new PowHSMConfig( + config.signerConfig(BTC.getId())); + + HSMClientProtocol protocol = + hsmClientProtocolFactory.buildHSMClientProtocolFromConfig(powHsmConfig); + + int hsmVersion = protocol.getVersion(); + logger.debug("[run] Using HSM version {}", hsmVersion); + + if (HSMVersion.isPowHSM(hsmVersion)) { + hsmBookkeepingClient = buildBookKeepingClient( + protocol, powHsmConfig); + hsmBookkeepingService = buildBookKeepingService( + hsmBookkeepingClient, powHsmConfig); + } } private void configureFederatorSupport() throws SignerException { - BtcECKey btcPublicKey = signer.getPublicKey(BTC_KEY_ID.getKeyId()).toBtcKey(); - ECKey rskPublicKey = signer.getPublicKey(RSK_KEY_ID.getKeyId()).toEthKey(); - ECKey mstKey = signer.getPublicKey(MST_KEY_ID.getKeyId()).toEthKey(); - LOGGER.info( + BtcECKey btcPublicKey = signer.getPublicKey(BTC.getKeyId()).toBtcKey(); + ECKey rskPublicKey = signer.getPublicKey(RSK.getKeyId()).toEthKey(); + ECKey mstKey = signer.getPublicKey(MST.getKeyId()).toEthKey(); + logger.info( "[configureFederatorSupport] BTC public key: {}. RSK public key: {}. MST public key: {}", btcPublicKey, rskPublicKey, @@ -189,52 +197,52 @@ private void configureFederatorSupport() throws SignerException { private ECDSASigner buildSigner() { ECDSACompositeSigner compositeSigner = new ECDSACompositeSigner(); - Stream.of(BTC_KEY_ID, RSK_KEY_ID, MST_KEY_ID).forEach(keyId -> { + Stream.of(BTC, RSK, MST).forEach(keyId -> { try { ECDSASigner createdSigner = buildSignerFromKey(keyId.getKeyId()); compositeSigner.addSigner(createdSigner); } catch (SignerException e) { - LOGGER.error("[buildSigner] Error trying to build signer with key id {}. Detail: {}", keyId, e.getMessage()); + logger.error("[buildSigner] Error trying to build signer with key id {}. Detail: {}", keyId, e.getMessage()); } catch (Exception e) { - LOGGER.error("[buildSigner] Error creating signer {}. Detail: {}", keyId, e.getMessage()); + logger.error("[buildSigner] Error creating signer {}. Detail: {}", keyId, e.getMessage()); throw e; } }); - LOGGER.debug("[buildSigner] Signers created"); + logger.debug("[buildSigner] Signers created"); return compositeSigner; } private HSMBookkeepingClient buildBookKeepingClient( HSMClientProtocol protocol, - PowHSMBookkeepingConfig bookKeepingConfig) throws HSMClientException { + PowHSMConfig powHsmConfig) throws HSMClientException { HSMBookkeepingClient bookKeepingClient = hsmBookKeepingClientProvider.getHSMBookKeepingClient(protocol); - bookKeepingClient.setMaxChunkSizeToHsm(bookKeepingConfig.getMaxChunkSizeToHsm()); - LOGGER.info("[buildBookKeepingClient] HSMBookkeeping client built for HSM version: {}", bookKeepingClient.getVersion()); + bookKeepingClient.setMaxChunkSizeToHsm(powHsmConfig.getMaxChunkSizeToHsm()); + logger.info("[buildBookKeepingClient] HSMBookkeeping client built for HSM version: {}", bookKeepingClient.getVersion()); return bookKeepingClient; } private HSMBookkeepingService buildBookKeepingService( HSMBookkeepingClient bookKeepingClient, - PowHSMBookkeepingConfig bookKeepingConfig) throws HSMClientException { + PowHSMConfig powHsmConfig) throws HSMClientException { HSMBookkeepingService service = new HSMBookkeepingService( fedNodeContext.getBlockStore(), bookKeepingClient, new ConfirmedBlocksProvider( - bookKeepingConfig.getDifficultyTarget(), - bookKeepingConfig.getMaxAmountBlockHeaders(), + powHsmConfig.getDifficultyTarget(bookKeepingClient), + powHsmConfig.getMaxAmountBlockHeaders(), fedNodeContext.getBlockStore(), - bookKeepingConfig.getDifficultyCap(), + powHsmConfig.getDifficultyCap(bridgeConstants.getBtcParamsString()), hsmBookkeepingClient.getVersion() ), fedNodeContext.getNodeBlockProcessor(), - bookKeepingConfig.getInformerInterval(), - bookKeepingConfig.isStopBookkeepingScheduler() + powHsmConfig.getInformerInterval(), + powHsmConfig.isStopBookkeepingScheduler() ); - LOGGER.info("[buildBookKeepingService] HSMBookkeeping Service built for HSM version: {}", bookKeepingClient.getVersion()); + logger.info("[buildBookKeepingService] HSMBookkeeping Service built for HSM version: {}", bookKeepingClient.getVersion()); return service; } @@ -255,7 +263,7 @@ private boolean checkFederateRequirements() { Federator federator = new Federator( signer, - Arrays.asList(BTC_KEY_ID.getKeyId(), RSK_KEY_ID.getKeyId()), + Arrays.asList(BTC.getKeyId(), RSK.getKeyId()), new FederatorPeersChecker( defaultPort, peers, @@ -268,7 +276,7 @@ private boolean checkFederateRequirements() { } private void startFederate() throws Exception { - LOGGER.debug("[startFederate] Starting Federation Behaviour"); + logger.debug("[startFederate] Starting Federation Behaviour"); if (config.isFederatorEnabled()) { // Set up a federation watcher to trigger starts and stops of the // btc to rsk client upon federation changes @@ -302,8 +310,8 @@ private void startFederate() throws Exception { btcLogMonitor.start(); rskLogMonitor.start(); if (hsmBookkeepingService != null) { - hsmBookkeepingService.addListener((e) -> { - LOGGER.error("[startFederate] HSM bookkeeping service informed unrecoverable state, shutting down", e); + hsmBookkeepingService.addListener(e -> { + logger.error("[startFederate] HSM bookkeeping service informed unrecoverable state, shutting down", e); this.shutdown(); }); hsmBookkeepingService.start(); @@ -342,7 +350,7 @@ private void startFederate() throws Exception { public void onActiveFederationChange(Optional oldFederation, Federation newFederation) { String oldFederationAddress = oldFederation.map(f -> f.getAddress().toString()).orElse("NONE"); String newFederationAddress = newFederation.getAddress().toString(); - LOGGER.debug(String.format("[onActiveFederationChange] Active federation change: from %s to %s", oldFederationAddress, newFederationAddress)); + logger.debug(String.format("[onActiveFederationChange] Active federation change: from %s to %s", oldFederationAddress, newFederationAddress)); triggerClientChange(btcToRskClientActive, Optional.of(newFederation)); } @@ -350,7 +358,7 @@ public void onActiveFederationChange(Optional oldFederation, Federat public void onRetiringFederationChange(Optional oldFederation, Optional newFederation) { String oldFederationAddress = oldFederation.map(f -> f.getAddress().toString()).orElse("NONE"); String newFederationAddress = newFederation.map(f -> f.getAddress().toString()).orElse("NONE"); - LOGGER.debug(String.format("[onRetiringFederationChange] Retiring federation change: from %s to %s", oldFederationAddress, newFederationAddress)); + logger.debug(String.format("[onRetiringFederationChange] Retiring federation change: from %s to %s", oldFederationAddress, newFederationAddress)); triggerClientChange(btcToRskClientRetiring, newFederation); } }); @@ -361,18 +369,18 @@ public void onRetiringFederationChange(Optional oldFederation, Optio @PreDestroy public void tearDown() { - LOGGER.debug("[tearDown] FederateRunner tearDown starting..."); + logger.debug("[tearDown] FederateRunner tearDown starting..."); this.stop(); - LOGGER.debug("[tearDown] FederateRunner tearDown finished."); + logger.debug("[tearDown] FederateRunner tearDown finished."); } private void shutdown() { try { this.tearDown(); } catch(Exception e){ - LOGGER.error("[shutdown] FederateRunner teardown failed", e); + logger.error("[shutdown] FederateRunner teardown failed", e); } System.exit(-1); } @@ -384,18 +392,18 @@ private void triggerClientChange(BtcToRskClient client, Optional fed // Only start if this federator is part of the new federation if (federation.isPresent() && federation.get().isMember(this.member)) { String federationAddress = federation.get().getAddress().toString(); - LOGGER.debug("[triggerClientChange] Starting lock and release clients since I belong to federation {}", federationAddress); - LOGGER.info("[triggerClientChange] Joined to {} federation", federationAddress); + logger.debug("[triggerClientChange] Starting lock and release clients since I belong to federation {}", federationAddress); + logger.info("[triggerClientChange] Joined to {} federation", federationAddress); client.start(federation.get()); btcReleaseClient.start(federation.get()); } else { - LOGGER.warn("[triggerClientChange] This federator node is not part of the new federation. Check your configuration for signers BTC, RSK and MST keys"); + logger.warn("[triggerClientChange] This federator node is not part of the new federation. Check your configuration for signers BTC, RSK and MST keys"); } } @Override public void stop() { - LOGGER.info("[stop] Shutting down Federation node"); + logger.info("[stop] Shutting down Federation node"); if (bitcoinWrapper != null) { bitcoinWrapper.stop(); } @@ -411,7 +419,7 @@ public void stop() { } fullNodeRunner.stop(); - LOGGER.info("[stop] Federation node Shut down."); + logger.info("[stop] Federation node Shut down."); } private BitcoinWrapper createAndSetupBitcoinWrapper( diff --git a/src/main/java/co/rsk/federate/FederatorSupport.java b/src/main/java/co/rsk/federate/FederatorSupport.java index bc275c68..47b746c6 100644 --- a/src/main/java/co/rsk/federate/FederatorSupport.java +++ b/src/main/java/co/rsk/federate/FederatorSupport.java @@ -6,7 +6,7 @@ import co.rsk.core.RskAddress; import co.rsk.federate.adapter.ThinConverter; import co.rsk.federate.bitcoin.BitcoinPeerFactory; -import co.rsk.federate.config.FedNodeSystemProperties; +import co.rsk.federate.config.PowpegNodeSystemProperties; import co.rsk.federate.signing.ECDSASigner; import co.rsk.peg.Bridge; import co.rsk.peg.federation.FederationMember; @@ -35,7 +35,7 @@ public class FederatorSupport { private static final Logger LOGGER = LoggerFactory.getLogger(FederatorSupport.class); private final Blockchain blockchain; - private final FedNodeSystemProperties config; + private final PowpegNodeSystemProperties config; private final NetworkParameters parameters; @@ -48,7 +48,7 @@ public class FederatorSupport { public FederatorSupport( Blockchain blockchain, - FedNodeSystemProperties config, + PowpegNodeSystemProperties config, BridgeTransactionSender bridgeTransactionSender) { this.blockchain = blockchain; this.config = config; diff --git a/src/main/java/co/rsk/federate/btcreleaseclient/BtcReleaseClient.java b/src/main/java/co/rsk/federate/btcreleaseclient/BtcReleaseClient.java index 2c283def..6ca154b3 100644 --- a/src/main/java/co/rsk/federate/btcreleaseclient/BtcReleaseClient.java +++ b/src/main/java/co/rsk/federate/btcreleaseclient/BtcReleaseClient.java @@ -14,7 +14,7 @@ import co.rsk.federate.adapter.ThinConverter; import co.rsk.federate.btcreleaseclient.cache.PegoutSignedCache; import co.rsk.federate.btcreleaseclient.cache.PegoutSignedCacheImpl; -import co.rsk.federate.config.FedNodeSystemProperties; +import co.rsk.federate.config.PowpegNodeSystemProperties; import co.rsk.federate.signing.ECDSASigner; import co.rsk.federate.signing.FederationCantSignException; import co.rsk.federate.signing.FederatorAlreadySignedException; @@ -70,7 +70,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static co.rsk.federate.signing.PowPegNodeKeyId.BTC_KEY_ID; +import static co.rsk.federate.signing.PowPegNodeKeyId.BTC; /** * Manages signing and broadcasting pegouts @@ -106,7 +106,7 @@ public class BtcReleaseClient { public BtcReleaseClient( Ethereum ethereum, FederatorSupport federatorSupport, - FedNodeSystemProperties systemProperties, + PowpegNodeSystemProperties systemProperties, NodeBlockProcessor nodeBlockProcessor ) { this.ethereum = ethereum; @@ -253,7 +253,7 @@ private BtcTransaction convertToBtcTxFromSolidityData(byte[] dataFromBtcReleaseT protected void processReleases(Set> pegouts) { try { logger.debug("[processReleases] Starting process with {} pegouts", pegouts.size()); - int version = signer.getVersionForKeyId(BTC_KEY_ID.getKeyId()); + int version = signer.getVersionForKeyId(BTC.getKeyId()); // Get pegout information and store it in a new list List pegoutsReadyToSign = new ArrayList<>(); for (Map.Entry pegout : pegouts) { @@ -346,7 +346,7 @@ void validateTxIsNotCached(Keccak256 pegoutCreationRskTxHash) throws FederatorAl protected void validateTxCanBeSigned(BtcTransaction pegoutBtcTx) throws FederatorAlreadySignedException, FederationCantSignException { try { - BtcECKey federatorPublicKey = signer.getPublicKey(BTC_KEY_ID.getKeyId()).toBtcKey(); + BtcECKey federatorPublicKey = signer.getPublicKey(BTC.getKeyId()).toBtcKey(); logger.trace("[validateTxCanBeSigned] Federator public key {}", federatorPublicKey); for (int inputIndex = 0; inputIndex < pegoutBtcTx.getInputs().size(); inputIndex++) { @@ -374,8 +374,8 @@ protected void validateTxCanBeSigned(BtcTransaction pegoutBtcTx) throws Federato // Check if any of the observed federations can sign the tx logger.trace("[validateTxCanBeSigned] Checking if any of the observed federations can sign the tx input {}", inputIndex); - observedFederations.stream() - .forEach(f -> logger.trace("[validateTxCanBeSigned] federation p2sh redeem script {}", f.getRedeemScript())); + observedFederations.forEach( + f -> logger.trace("[validateTxCanBeSigned] federation p2sh redeem script {}", f.getRedeemScript())); List spendingFedFilter = observedFederations.stream() .filter(f -> (extractDefaultRedeemScript(f)).equals(standardRedeemScript)).collect(Collectors.toList()); logger.debug("[validateTxCanBeSigned] spendingFedFilter size {}", spendingFedFilter.size()); @@ -410,7 +410,7 @@ protected void signRelease(int signerVersion, ReleaseCreationInformation pegoutC for (int inputIndex = 0; inputIndex < pegoutCreationInformation.getPegoutBtcTx().getInputs().size(); inputIndex++) { SignerMessage messageToSign = messageBuilder.buildMessageForIndex(inputIndex); logger.trace("[signRelease] Message to sign: {}", messageToSign.getClass()); - ECKey.ECDSASignature ethSig = signer.sign(BTC_KEY_ID.getKeyId(), messageToSign); + ECKey.ECDSASignature ethSig = signer.sign(BTC.getKeyId(), messageToSign); logger.debug("[signRelease] Message successfully signed"); BtcECKey.ECDSASignature sig = new BtcECKey.ECDSASignature(ethSig.r, ethSig.s); signatures.add(sig.encodeToDER()); diff --git a/src/main/java/co/rsk/federate/btcreleaseclient/BtcReleaseClientStorageAccessor.java b/src/main/java/co/rsk/federate/btcreleaseclient/BtcReleaseClientStorageAccessor.java index 036438da..4224ae0c 100644 --- a/src/main/java/co/rsk/federate/btcreleaseclient/BtcReleaseClientStorageAccessor.java +++ b/src/main/java/co/rsk/federate/btcreleaseclient/BtcReleaseClientStorageAccessor.java @@ -2,7 +2,7 @@ import co.rsk.bitcoinj.core.Sha256Hash; import co.rsk.crypto.Keccak256; -import co.rsk.federate.config.FedNodeSystemProperties; +import co.rsk.federate.config.PowpegNodeSystemProperties; import co.rsk.federate.io.btcreleaseclientstorage.BtcReleaseClientFileData; import co.rsk.federate.io.btcreleaseclientstorage.BtcReleaseClientFileReadResult; import co.rsk.federate.io.btcreleaseclientstorage.BtcReleaseClientFileStorage; @@ -31,7 +31,7 @@ public class BtcReleaseClientStorageAccessor { private ScheduledFuture task; private int delays; - public BtcReleaseClientStorageAccessor(FedNodeSystemProperties systemProperties) throws InvalidStorageFileException { + public BtcReleaseClientStorageAccessor(PowpegNodeSystemProperties systemProperties) throws InvalidStorageFileException { this( Executors.newSingleThreadScheduledExecutor(), new BtcReleaseClientFileStorageImpl( diff --git a/src/main/java/co/rsk/federate/config/FedNodeSystemProperties.java b/src/main/java/co/rsk/federate/config/FedNodeSystemProperties.java deleted file mode 100644 index 2e5b4519..00000000 --- a/src/main/java/co/rsk/federate/config/FedNodeSystemProperties.java +++ /dev/null @@ -1,121 +0,0 @@ -package co.rsk.federate.config; - -import co.rsk.config.ConfigLoader; -import co.rsk.config.RskSystemProperties; -import com.typesafe.config.Config; -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by mario on 04/04/17. - */ -public class FedNodeSystemProperties extends RskSystemProperties { - - public FedNodeSystemProperties(ConfigLoader loader) { - super(loader); - } - - public boolean isFederatorEnabled() { - return configFromFiles.hasPath("federator.enabled") && - configFromFiles.getBoolean("federator.enabled"); - } - - public boolean isPegoutEnabled() { - return !configFromFiles.hasPath("federator.pegout.enabled") || - configFromFiles.getBoolean("federator.pegout.enabled"); - } - - public boolean isUpdateBridgeTimerEnabled() { - return !this.netName().equals("regtest") || - (!configFromFiles.hasPath("federator.updateBridgeTimerEnabled") || - configFromFiles.getBoolean("federator.updateBridgeTimerEnabled")); - } - - public SignerConfig signerConfig(String key) { - Config signersConfigTree = signersConfigTree(); - if (signersConfigTree == null || !signersConfigTree.hasPath(key)) { - return null; - } - - Config signerConfigTree = signersConfigTree.getObject(key).toConfig(); - if (!signerConfigTree.hasPath("type")) { - return null; - } - - return new SignerConfig(key, signerConfigTree); - } - - private Config signersConfigTree() { - return configFromFiles.hasPath("federator.signers") ? - configFromFiles.getObject("federator.signers").toConfig() : - null; - } - - public List bitcoinPeerAddresses() { - return configFromFiles.hasPath("federator.bitcoinPeerAddresses") ? - configFromFiles.getStringList("federator.bitcoinPeerAddresses") : - new ArrayList<>(); - } - - public Long federatorGasPrice() { - return configFromFiles.hasPath("federator.gasPrice") ? - configFromFiles.getLong("federator.gasPrice") : - 0; - } - - public GasPriceProviderConfig gasPriceProviderConfig() { - return configFromFiles.hasPath("federator.gasPriceProvider") ? - new GasPriceProviderConfig(configFromFiles.getObject("federator.gasPriceProvider").toConfig()) : - null; - } - - public int getAmountOfHeadersToSend() { - return configFromFiles.hasPath("federator.amountOfHeadersToSend") ? - configFromFiles.getInt("federator.amountOfHeadersToSend") : - 25; - } - - // 6000 blocks is 150% the amount of blocks the Bridge waits before confirming a peg-out. - // If this powpeg-node was shutdown for 48hs this depth will be enough to resync all the information. - // If this powpeg-node was shutdown for longer periods, most likely the transaction was signed by other functionaries. - public int getBtcReleaseClientInitializationMaxDepth() { - return configFromFiles.hasPath("federator.pegoutStorageInitializationDepth") ? - configFromFiles.getInt("federator.pegoutStorageInitializationDepth") : - 6_000; - } - - /** - * Retrieves the time to live (TTL) duration for the pegout signed cache. - * The TTL duration specifies the validity period for cache entries. - * If the TTL value is not configured, a default value of 30 minutes is used. - * - * @return The time to live (TTL) duration for the pegout signed cache, - * or a default value of 30 minutes if not configured. - */ - 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/main/java/co/rsk/federate/config/PowHSMBookkeepingConfig.java b/src/main/java/co/rsk/federate/config/PowHSMBookkeepingConfig.java deleted file mode 100644 index baab4316..00000000 --- a/src/main/java/co/rsk/federate/config/PowHSMBookkeepingConfig.java +++ /dev/null @@ -1,87 +0,0 @@ -package co.rsk.federate.config; - -/** - * Represents the configuration for a signer. - * Mainly has an identifier for the signer, the - * type of signer and additional configuration options. - * - * @author Pamela Gonzalez - */ - -import co.rsk.bitcoinj.core.NetworkParameters; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.math.BigInteger; - -public class PowHSMBookkeepingConfig { - - private static final Logger logger = LoggerFactory.getLogger(PowHSMBookkeepingConfig.class); - public static final BigInteger DIFFICULTY_CAP_MAINNET = new BigInteger("7000000000000000000000"); - public static final BigInteger DIFFICULTY_CAP_TESTNET = BigInteger.valueOf(1000000000000000L); - public static final BigInteger DIFFICULTY_CAP_REGTEST = BigInteger.valueOf(20); - private final BigInteger difficultyCap; - private BigInteger difficultyTarget = BigInteger.valueOf(3); - private int maxAmountBlockHeaders = 7; - private long informerInterval = 2_000; - private boolean stopBookkeepingScheduler = false; - private int maxChunkSizeToHsm = 10; - - public PowHSMBookkeepingConfig(SignerConfig signerConfig, String networkParameter) { - if (signerConfig.getConfig().hasPath("bookkeeping.difficultyTarget")) { - this.difficultyTarget = new BigInteger(signerConfig.getConfig().getString("bookkeeping.difficultyTarget")); - } - if (signerConfig.getConfig().hasPath("bookkeeping.maxAmountBlockHeaders")) { - this.maxAmountBlockHeaders = signerConfig.getConfig().getInt("bookkeeping.maxAmountBlockHeaders"); - } - if (signerConfig.getConfig().hasPath("bookkeeping.informerInterval")) { - this.informerInterval = signerConfig.getConfig().getLong("bookkeeping.informerInterval"); - } - if (signerConfig.getConfig().hasPath("bookkeeping.stopBookkeepingScheduler")) { - this.stopBookkeepingScheduler = signerConfig.getConfig().getBoolean("bookkeeping.stopBookkeepingScheduler"); - } - if (signerConfig.getConfig().hasPath("bookkeeping.maxChunkSizeToHsm")) { - this.maxChunkSizeToHsm = signerConfig.getConfig().getInt("bookkeeping.maxChunkSizeToHsm"); - } - - switch (networkParameter) { - case NetworkParameters.ID_MAINNET: - this.difficultyCap = DIFFICULTY_CAP_MAINNET; - break; - case NetworkParameters.ID_TESTNET: - this.difficultyCap = DIFFICULTY_CAP_TESTNET; - break; - case NetworkParameters.ID_REGTEST: - this.difficultyCap = DIFFICULTY_CAP_REGTEST; - break; - default: - String message = "Invalid network specified for the Bookkeeping Config: " + networkParameter; - logger.error(message); - throw new IllegalArgumentException(message); - } - } - - public BigInteger getDifficultyTarget() { - return difficultyTarget; - } - - public int getMaxAmountBlockHeaders() { - return maxAmountBlockHeaders; - } - - public long getInformerInterval() { - return informerInterval; - } - - public boolean isStopBookkeepingScheduler() { - return stopBookkeepingScheduler; - } - - public int getMaxChunkSizeToHsm() { - return maxChunkSizeToHsm; - } - - public BigInteger getDifficultyCap() { - return difficultyCap; - } -} diff --git a/src/main/java/co/rsk/federate/config/PowpegNodeConfigParameter.java b/src/main/java/co/rsk/federate/config/PowpegNodeConfigParameter.java new file mode 100644 index 00000000..d57e7a18 --- /dev/null +++ b/src/main/java/co/rsk/federate/config/PowpegNodeConfigParameter.java @@ -0,0 +1,57 @@ +package co.rsk.federate.config; + +import java.util.Objects; +import java.util.function.Function; + +public enum PowpegNodeConfigParameter { + FEDERATOR_ENABLED("federator.enabled", Boolean.toString(true)), + PEGOUT_ENABLED("federator.pegout.enabled", Boolean.toString(true)), + UPDATE_BRIDGE_TIMER_ENABLED("federator.updateBridgeTimerEnabled", Boolean.toString(true)), + UPDATE_BRIDGE_BTC_BLOCKCHAIN("federator.updateBridgeBtcBlockchain", Boolean.toString(true)), + UPDATE_BRIDGE_BTC_COINBASE_TRANSACTIONS("federator.updateBridgeBtcCoinbaseTransactions", Boolean.toString(true)), + UPDATE_BRIDGE_BTC_TRANSACTIONS("federator.updateBridgeBtcTransactions", Boolean.toString(true)), + UPDATE_COLLECTIONS("federator.updateCollections", Boolean.toString(true)), + GAS_PRICE("federator.gasPrice", "0"), + GAS_PRICE_PROVIDER("federator.gasPriceProvider", ""), + AMOUNT_HEADERS("federator.amountOfHeadersToSend", "25"), + // 6000 blocks is 150% the amount of blocks the Bridge waits before confirming a + // peg-out. If this powpeg-node was shutdown for 48hs this depth will be enough + // to resync all the information. If this powpeg-node was shutdown for longer + // periods, most likely the transaction was signed by other pegnatories. + BTC_INIT_MAX_DEPTH("federator.pegoutStorageInitializationDepth", "6000"), + BTC_PEER_ADDRESSES("federator.bitcoinPeerAddresses", ""), + // The time to live (TTL) duration for the peg-out signed cache, + // specifies the validity period for the signed peg-outs. + PEGOUT_CACHE_TTL("federator.pegoutSignedCacheTtlInMinutes", "30"), + SIGNERS("federator.signers", ""); + + private final String path; + private final String defaultValue; + + PowpegNodeConfigParameter(String path, String defaultValue) { + this.path = path; + this.defaultValue = defaultValue; + } + + public String getPath() { + return path; + } + + public T getDefaultValue(Function parser) { + Objects.requireNonNull(parser); + + if (defaultValue.isEmpty()) { + throw new IllegalStateException( + "No Powpeg config default value present for: " + path); + } + return parser.apply(defaultValue); + } + + @Override + public String toString() { + return "PowpegNodeConfigParameter{" + + "path='" + path + '\'' + + ", defaultValue='" + defaultValue + '\'' + + '}'; + } +} diff --git a/src/main/java/co/rsk/federate/config/PowpegNodeSystemProperties.java b/src/main/java/co/rsk/federate/config/PowpegNodeSystemProperties.java new file mode 100644 index 00000000..e4e28200 --- /dev/null +++ b/src/main/java/co/rsk/federate/config/PowpegNodeSystemProperties.java @@ -0,0 +1,121 @@ +package co.rsk.federate.config; + +import static co.rsk.federate.config.PowpegNodeConfigParameter.*; + +import co.rsk.config.ConfigLoader; +import co.rsk.config.RskSystemProperties; +import co.rsk.federate.signing.config.SignerConfig; +import com.typesafe.config.Config; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; + +public class PowpegNodeSystemProperties extends RskSystemProperties { + + public static final String REGTEST = "regtest"; + + public PowpegNodeSystemProperties(ConfigLoader loader) { + super(loader); + } + + public boolean isFederatorEnabled() { + return getBoolean( + FEDERATOR_ENABLED.getPath(), + FEDERATOR_ENABLED.getDefaultValue(Boolean::parseBoolean)); + } + + public boolean isPegoutEnabled() { + return getBoolean( + PEGOUT_ENABLED.getPath(), + PEGOUT_ENABLED.getDefaultValue(Boolean::parseBoolean)); + } + + public boolean isUpdateBridgeTimerEnabled() { + return !netName().equals(REGTEST) || + getBoolean( + UPDATE_BRIDGE_TIMER_ENABLED.getPath(), + UPDATE_BRIDGE_TIMER_ENABLED.getDefaultValue(Boolean::parseBoolean)); + } + + public boolean shouldUpdateBridgeBtcBlockchain() { + return getBoolean( + UPDATE_BRIDGE_BTC_BLOCKCHAIN.getPath(), + UPDATE_BRIDGE_BTC_BLOCKCHAIN.getDefaultValue(Boolean::parseBoolean)); + } + + public boolean shouldUpdateBridgeBtcCoinbaseTransactions() { + return getBoolean( + UPDATE_BRIDGE_BTC_COINBASE_TRANSACTIONS.getPath(), + UPDATE_BRIDGE_BTC_COINBASE_TRANSACTIONS.getDefaultValue(Boolean::parseBoolean)); + } + + public boolean shouldUpdateBridgeBtcTransactions() { + return getBoolean( + UPDATE_BRIDGE_BTC_TRANSACTIONS.getPath(), + UPDATE_BRIDGE_BTC_TRANSACTIONS.getDefaultValue(Boolean::parseBoolean)); + } + + public boolean shouldUpdateCollections() { + return getBoolean( + UPDATE_COLLECTIONS.getPath(), + UPDATE_COLLECTIONS.getDefaultValue(Boolean::parseBoolean)); + } + + public int getAmountOfHeadersToSend() { + return getInt( + AMOUNT_HEADERS.getPath(), + AMOUNT_HEADERS.getDefaultValue(Integer::parseInt)); + } + + public int getBtcReleaseClientInitializationMaxDepth() { + return getInt( + BTC_INIT_MAX_DEPTH.getPath(), + BTC_INIT_MAX_DEPTH.getDefaultValue(Integer::parseInt)); + } + + public List bitcoinPeerAddresses() { + return configFromFiles.hasPath(BTC_PEER_ADDRESSES.getPath()) + ? configFromFiles.getStringList(BTC_PEER_ADDRESSES.getPath()) + : new ArrayList<>(); + } + + public Duration getPegoutSignedCacheTtl() { + return Duration.ofMinutes( + getInt( + PEGOUT_CACHE_TTL.getPath(), + PEGOUT_CACHE_TTL.getDefaultValue(Integer::parseInt))); + } + + public Long federatorGasPrice() { + return getLong( + GAS_PRICE.getPath(), + GAS_PRICE.getDefaultValue(Long::parseLong)); + } + + public GasPriceProviderConfig gasPriceProviderConfig() { + return configFromFiles.hasPath(GAS_PRICE_PROVIDER.getPath()) + ? new GasPriceProviderConfig( + configFromFiles.getObject(GAS_PRICE_PROVIDER.getPath()).toConfig()) + : null; + } + + public SignerConfig signerConfig(String key) { + Config signersConfigTree = signersConfigTree(); + if (signersConfigTree == null || !signersConfigTree.hasPath(key)) { + return null; + } + + Config signerConfigTree = signersConfigTree.getObject(key).toConfig(); + if (!signerConfigTree.hasPath("type")) { + return null; + } + + return new SignerConfig(key, signerConfigTree); + } + + private Config signersConfigTree() { + return configFromFiles.hasPath(SIGNERS.getPath()) + ? configFromFiles.getObject(SIGNERS.getPath()).toConfig() + : null; + } +} diff --git a/src/main/java/co/rsk/federate/config/SignerConfig.java b/src/main/java/co/rsk/federate/config/SignerConfig.java deleted file mode 100644 index 92152c43..00000000 --- a/src/main/java/co/rsk/federate/config/SignerConfig.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of RskJ - * Copyright (C) 2018 RSK Labs Ltd. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package co.rsk.federate.config; - -import com.typesafe.config.Config; - -/** - * Represents the configuration for a signer. - * Mainly has an identifier for the signer, the - * type of signer and additional configuration options. - * - * @author Ariel Mendelzon - */ -public class SignerConfig { - private final String id; - private final String type; - private final Config config; - - public SignerConfig(String keyId, Config config) { - this.id = keyId; - this.type = config.getString("type"); - this.config = config.withoutPath("type"); - } - - public String getId() { - return id; - } - - public String getType() { - return type; - } - - public Config getConfig() { - return config; - } -} diff --git a/src/main/java/co/rsk/federate/io/BtcToRskClientFileStorageInfo.java b/src/main/java/co/rsk/federate/io/BtcToRskClientFileStorageInfo.java index da15bc3d..18e9c82e 100644 --- a/src/main/java/co/rsk/federate/io/BtcToRskClientFileStorageInfo.java +++ b/src/main/java/co/rsk/federate/io/BtcToRskClientFileStorageInfo.java @@ -1,6 +1,6 @@ package co.rsk.federate.io; -import co.rsk.federate.config.FedNodeSystemProperties; +import co.rsk.federate.config.PowpegNodeSystemProperties; import java.io.File; @@ -10,7 +10,7 @@ public class BtcToRskClientFileStorageInfo implements FileStorageInfo { private String filePath; - public BtcToRskClientFileStorageInfo(FedNodeSystemProperties config) { + public BtcToRskClientFileStorageInfo(PowpegNodeSystemProperties config) { this.pegDirectoryPath = config.databaseDir() + File.separator + "peg"; this.filePath = this.pegDirectoryPath + File.separator + "btcToRskClient2.rlp"; } diff --git a/src/main/java/co/rsk/federate/io/btcreleaseclientstorage/BtcReleaseClientFileStorageInfo.java b/src/main/java/co/rsk/federate/io/btcreleaseclientstorage/BtcReleaseClientFileStorageInfo.java index 6fc31f39..c810c1b5 100644 --- a/src/main/java/co/rsk/federate/io/btcreleaseclientstorage/BtcReleaseClientFileStorageInfo.java +++ b/src/main/java/co/rsk/federate/io/btcreleaseclientstorage/BtcReleaseClientFileStorageInfo.java @@ -1,6 +1,6 @@ package co.rsk.federate.io.btcreleaseclientstorage; -import co.rsk.federate.config.FedNodeSystemProperties; +import co.rsk.federate.config.PowpegNodeSystemProperties; import co.rsk.federate.io.FileStorageInfo; import java.io.File; @@ -10,7 +10,7 @@ public class BtcReleaseClientFileStorageInfo implements FileStorageInfo { private String filePath; - public BtcReleaseClientFileStorageInfo(FedNodeSystemProperties config) { + public BtcReleaseClientFileStorageInfo(PowpegNodeSystemProperties config) { this.pegDirectoryPath = config.databaseDir() + File.separator + "peg"; this.filePath = this.pegDirectoryPath + File.separator + "btcReleaseClient.rlp"; } diff --git a/src/main/java/co/rsk/federate/signing/ECDSASignerFactory.java b/src/main/java/co/rsk/federate/signing/ECDSASignerFactory.java index 5dd71027..45348be6 100644 --- a/src/main/java/co/rsk/federate/signing/ECDSASignerFactory.java +++ b/src/main/java/co/rsk/federate/signing/ECDSASignerFactory.java @@ -18,7 +18,9 @@ package co.rsk.federate.signing; -import co.rsk.federate.config.SignerConfig; +import co.rsk.federate.signing.config.SignerConfig; +import co.rsk.federate.signing.config.SignerType; +import co.rsk.federate.signing.hsm.config.PowHSMConfig; import co.rsk.federate.signing.hsm.SignerException; import co.rsk.federate.signing.hsm.client.HSMClientProtocol; import co.rsk.federate.signing.hsm.client.HSMClientProtocolFactory; @@ -26,45 +28,42 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** - * Builds signers given configuration - * - * @author Ariel Mendelzon - */ public class ECDSASignerFactory { private static final Logger logger = LoggerFactory.getLogger(ECDSASignerFactory.class); - public static final int DEFAULT_SOCKET_TIMEOUT = 10_000; - public static final int DEFAULT_ATTEMPTS = 2; - public static final int DEFAULT_INTERVAL = 1000; public ECDSASigner buildFromConfig(SignerConfig config) throws SignerException { if (config == null) { throw new SignerException("'signers' entry not found in config file."); } - String type = config.getType(); + SignerType type = config.getSignerType(); logger.debug("[buildFromConfig] SignerConfig type {}", type); switch (type) { - case "keyFile": + case KEYFILE: return new ECDSASignerFromFileKey( - new KeyId(config.getId()), - config.getConfig().getString("path") + new KeyId(config.getId()), + config.getConfig().getString("path") ); - case "hsm": - try { - HSMClientProtocol hsmClientProtocol = new HSMClientProtocolFactory().buildHSMClientProtocolFromConfig(config); - HSMSigningClientProvider hsmSigningClientProvider = new HSMSigningClientProvider(hsmClientProtocol, config.getId()); - ECDSAHSMSigner signer = new ECDSAHSMSigner(hsmSigningClientProvider); - // Add the key mapping - String hsmKeyId = config.getConfig().getString("keyId"); - signer.addKeyMapping(new KeyId(config.getId()), hsmKeyId); - return signer; - } catch (Exception e) { - String message = "Something went wrong while trying to build HSM Signer"; - logger.debug("[buildFromConfig] {} - {}", message, e.getMessage()); - throw new RuntimeException(e.getMessage()); - } + case HSM: + return buildHSMFromConfig(config); default: - throw new RuntimeException(String.format("Unsupported signer type: %s", type)); + throw new IllegalArgumentException(String.format("Unsupported signer type: %s", type)); } } + + private ECDSAHSMSigner buildHSMFromConfig(SignerConfig config) throws SignerException { + PowHSMConfig powHSMConfig = new PowHSMConfig(config); + HSMClientProtocol hsmClientProtocol = new HSMClientProtocolFactory().buildHSMClientProtocolFromConfig( + powHSMConfig + ); + HSMSigningClientProvider hsmSigningClientProvider = new HSMSigningClientProvider( + hsmClientProtocol, + config.getId() + ); + ECDSAHSMSigner signer = new ECDSAHSMSigner(hsmSigningClientProvider); + // Add the key mapping + String hsmKeyId = config.getConfig().getString("keyId"); + signer.addKeyMapping(new KeyId(config.getId()), hsmKeyId); + + return signer; + } } diff --git a/src/main/java/co/rsk/federate/signing/PowPegNodeKeyId.java b/src/main/java/co/rsk/federate/signing/PowPegNodeKeyId.java index 518956c3..87e4a88e 100644 --- a/src/main/java/co/rsk/federate/signing/PowPegNodeKeyId.java +++ b/src/main/java/co/rsk/federate/signing/PowPegNodeKeyId.java @@ -4,9 +4,9 @@ * Created by Kelvin Isievwore on 23/05/2023. */ public enum PowPegNodeKeyId { - BTC_KEY_ID(new KeyId("BTC")), - RSK_KEY_ID(new KeyId("RSK")), - MST_KEY_ID(new KeyId("MST")); + BTC(new KeyId("BTC")), + RSK(new KeyId("RSK")), + MST(new KeyId("MST")); private final KeyId keyId; diff --git a/src/main/java/co/rsk/federate/signing/config/SignerConfig.java b/src/main/java/co/rsk/federate/signing/config/SignerConfig.java new file mode 100644 index 00000000..39bd33eb --- /dev/null +++ b/src/main/java/co/rsk/federate/signing/config/SignerConfig.java @@ -0,0 +1,30 @@ +package co.rsk.federate.signing.config; + +import com.typesafe.config.Config; + +public class SignerConfig { + + private static final String SIGNER_TYPE_PATH = "type"; + + private final String id; + private final SignerType type; + private final Config config; + + public SignerConfig(String keyId, Config config) { + this.id = keyId; + this.type = SignerType.fromConfigValue(config.getString(SIGNER_TYPE_PATH)); + this.config = config.withoutPath(SIGNER_TYPE_PATH); + } + + public String getId() { + return id; + } + + public SignerType getSignerType() { + return type; + } + + public Config getConfig() { + return config; + } +} diff --git a/src/main/java/co/rsk/federate/signing/config/SignerType.java b/src/main/java/co/rsk/federate/signing/config/SignerType.java new file mode 100644 index 00000000..295b74e0 --- /dev/null +++ b/src/main/java/co/rsk/federate/signing/config/SignerType.java @@ -0,0 +1,25 @@ +package co.rsk.federate.signing.config; + +public enum SignerType { + KEYFILE("keyFile"), + HSM("hsm"); + + private final String type; + + SignerType(String signerType) { + this.type = signerType; + } + + public static SignerType fromConfigValue(String configValue) { + for (SignerType signerType : values()) { + if (signerType.getType().equalsIgnoreCase(configValue)) { + return signerType; + } + } + throw new IllegalArgumentException(String.format("Unsupported signer type: %s", configValue)); + } + + public String getType() { + return type; + } +} diff --git a/src/main/java/co/rsk/federate/signing/hsm/client/HSMClientProtocolFactory.java b/src/main/java/co/rsk/federate/signing/hsm/client/HSMClientProtocolFactory.java index 1c6c0845..1e867682 100644 --- a/src/main/java/co/rsk/federate/signing/hsm/client/HSMClientProtocolFactory.java +++ b/src/main/java/co/rsk/federate/signing/hsm/client/HSMClientProtocolFactory.java @@ -1,48 +1,23 @@ package co.rsk.federate.signing.hsm.client; -import co.rsk.federate.config.SignerConfig; +import co.rsk.federate.signing.hsm.config.PowHSMConfig; import co.rsk.federate.rpc.SocketBasedJsonRpcClientProvider; -import co.rsk.federate.signing.hsm.HSMUnsupportedTypeException; import java.net.InetSocketAddress; public class HSMClientProtocolFactory { - public static final String HOST = "host"; - public static final String PORT = "port"; - public static final String SOCKET_TIMEOUT = "socketTimeout"; - public static final String MAX_ATTEMPTS = "maxAttempts"; - public static final String INTERVAL_BETWEEN_ATTEMPTS = "intervalBetweenAttempts"; - public static final String HSM_CONFIG_TYPE = "hsm"; + public HSMClientProtocol buildHSMClientProtocolFromConfig(PowHSMConfig config) { + InetSocketAddress hsmAddress = new InetSocketAddress( + config.getHost(), config.getPort()); - public static final int DEFAULT_SOCKET_TIMEOUT = 10_000; - public static final int DEFAULT_ATTEMPTS = 2; - public static final int DEFAULT_INTERVAL = 1000; - - public HSMClientProtocol buildHSMClientProtocolFromConfig(SignerConfig config) throws HSMUnsupportedTypeException { - if (!HSM_CONFIG_TYPE.equalsIgnoreCase(config.getType())) { - throw new HSMUnsupportedTypeException("Config type must be HSM"); - } - String host = config.getConfig().getString(HOST); - int port = config.getConfig().getInt(PORT); - InetSocketAddress hsmAddress = new InetSocketAddress(host, port); - - int socketTimeout = config.getConfig().hasPath(SOCKET_TIMEOUT) ? - config.getConfig().getInt(SOCKET_TIMEOUT) : - DEFAULT_SOCKET_TIMEOUT; - int maxAttempts = config.getConfig().hasPath(MAX_ATTEMPTS) ? - config.getConfig().getInt(MAX_ATTEMPTS) : - DEFAULT_ATTEMPTS; - int intervalBetweenAttempts = config.getConfig().hasPath(INTERVAL_BETWEEN_ATTEMPTS) ? - config.getConfig().getInt(INTERVAL_BETWEEN_ATTEMPTS) : - DEFAULT_INTERVAL; // Build the protocol - SocketBasedJsonRpcClientProvider socketRpcClientProvider = new SocketBasedJsonRpcClientProvider(hsmAddress); - socketRpcClientProvider.setSocketTimeout(socketTimeout); + SocketBasedJsonRpcClientProvider socketRpcClientProvider = + new SocketBasedJsonRpcClientProvider(hsmAddress); + socketRpcClientProvider.setSocketTimeout(config.getSocketTimeout()); return new HSMClientProtocol( socketRpcClientProvider, - maxAttempts, - intervalBetweenAttempts - ); + config.getMaxAttempts(), + config.getIntervalBetweenAttempts()); } } diff --git a/src/main/java/co/rsk/federate/signing/hsm/config/NetworkDifficultyCap.java b/src/main/java/co/rsk/federate/signing/hsm/config/NetworkDifficultyCap.java new file mode 100644 index 00000000..e88792d5 --- /dev/null +++ b/src/main/java/co/rsk/federate/signing/hsm/config/NetworkDifficultyCap.java @@ -0,0 +1,19 @@ +package co.rsk.federate.signing.hsm.config; + +import java.math.BigInteger; + +public enum NetworkDifficultyCap { + MAINNET(new BigInteger("7000000000000000000000")), + TESTNET(BigInteger.valueOf(1000000000000000L)), + REGTEST(BigInteger.valueOf(20L)); + + private final BigInteger difficultyCap; + + NetworkDifficultyCap(BigInteger difficultyCap) { + this.difficultyCap = difficultyCap; + } + + public BigInteger getDifficultyCap() { + return difficultyCap; + } +} diff --git a/src/main/java/co/rsk/federate/signing/hsm/config/PowHSMConfig.java b/src/main/java/co/rsk/federate/signing/hsm/config/PowHSMConfig.java new file mode 100644 index 00000000..228cd89c --- /dev/null +++ b/src/main/java/co/rsk/federate/signing/hsm/config/PowHSMConfig.java @@ -0,0 +1,150 @@ +package co.rsk.federate.signing.hsm.config; + +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.*; + +import co.rsk.federate.signing.hsm.SignerException; +import co.rsk.bitcoinj.core.NetworkParameters; +import co.rsk.federate.signing.config.SignerConfig; +import co.rsk.federate.signing.config.SignerType; +import co.rsk.federate.signing.hsm.HSMClientException; +import co.rsk.federate.signing.hsm.HSMUnsupportedTypeException; +import co.rsk.federate.signing.hsm.client.HSMBookkeepingClient; +import com.typesafe.config.Config; +import java.math.BigInteger; +import java.util.function.Function; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PowHSMConfig { + + private static final Logger logger = LoggerFactory.getLogger(PowHSMConfig.class); + + private final Config config; + + public PowHSMConfig(SignerConfig signerConfig) throws SignerException { + if (signerConfig == null || signerConfig.getSignerType() != SignerType.HSM) { + throw new SignerException("Signer config is not for PowHSM"); + } + + this.config = signerConfig.getConfig(); + } + + public String getHost() { + return config.hasPath(HOST.getPath()) + ? config.getString(HOST.getPath()) + : HOST.getDefaultValue(Function.identity()); + } + + public int getPort() { + return config.hasPath(PORT.getPath()) + ? config.getInt(PORT.getPath()) + : PORT.getDefaultValue(Integer::parseInt); + } + + public int getMaxAttempts() { + return config.hasPath(MAX_ATTEMPTS.getPath()) + ? config.getInt(MAX_ATTEMPTS.getPath()) + : MAX_ATTEMPTS.getDefaultValue(Integer::parseInt); + } + + public int getIntervalBetweenAttempts() { + return config.hasPath(INTERVAL_BETWEEN_ATTEMPTS.getPath()) + ? config.getInt(INTERVAL_BETWEEN_ATTEMPTS.getPath()) + : INTERVAL_BETWEEN_ATTEMPTS.getDefaultValue(Integer::parseInt); + } + + public int getSocketTimeout() { + return config.hasPath(SOCKET_TIMEOUT.getPath()) + ? config.getInt(SOCKET_TIMEOUT.getPath()) + : SOCKET_TIMEOUT.getDefaultValue(Integer::parseInt); + } + + public int getMaxAmountBlockHeaders() { + return config.hasPath(MAX_AMOUNT_BLOCK_HEADERS.getPath()) + ? config.getInt(MAX_AMOUNT_BLOCK_HEADERS.getPath()) + : MAX_AMOUNT_BLOCK_HEADERS.getDefaultValue(Integer::parseInt); + } + + public long getInformerInterval() { + return config.hasPath(INFORMER_INTERVAL.getPath()) + ? config.getLong(INFORMER_INTERVAL.getPath()) + : INFORMER_INTERVAL.getDefaultValue(Long::parseLong); + } + + public boolean isStopBookkeepingScheduler() { + return config.hasPath(STOP_BOOKKEEPING_SCHEDULER.getPath()) + ? config.getBoolean(STOP_BOOKKEEPING_SCHEDULER.getPath()) + : STOP_BOOKKEEPING_SCHEDULER.getDefaultValue(Boolean::parseBoolean); + } + + public int getMaxChunkSizeToHsm() { + return config.hasPath(MAX_CHUNK_SIZE_TO_HSM.getPath()) + ? config.getInt(MAX_CHUNK_SIZE_TO_HSM.getPath()) + : MAX_CHUNK_SIZE_TO_HSM.getDefaultValue(Integer::parseInt); + } + + /** + * Retrieves the difficulty target from either the PowHSM or the configuration + * file. The value represents the minimum cumulative block difficulty to + * consider a block sufficiently confirmed. + * + *

+ * This method first attempts to retrieve the difficulty target from the PowHSM + * using the provided {@link HSMBookkeepingClient}. If the PowHSM version is + * unsupported, it falls back to retrieving the difficulty target from the + * configuration file. + *

+ * + * @param hsmClient The client used to communicate with the PowHSM. + * @return The difficulty target as a {@link BigInteger}. + * @throws HSMClientException If there is an error communicating with the + * PowHSM. + */ + public BigInteger getDifficultyTarget(HSMBookkeepingClient hsmClient) throws HSMClientException { + try { + logger.trace("[getDifficultyTarget] Retrieve minimum difficulty target from the PowHSM"); + + return hsmClient.getBlockchainParameters().getMinimumDifficulty(); + } catch (HSMUnsupportedTypeException e) { + logger.trace( + "[getDifficultyTarget] Unsupported PowHSM version, retrieve difficulty target from config file", e); + + return new BigInteger(config.getString(DIFFICULTY_TARGET.getPath())); + } + } + + /** + * Retrieves the difficulty cap for a given network parameter. + * The difficulty cap is determined based on the network type (mainnet, testnet, + * or regtest). This value will be used to determine the maximum allowed + * difficulty for any given block. + * + * @param networkParameter the network parameter identifier, which can be one of + * the following: + *
    + *
  • {@link NetworkParameters#ID_MAINNET} - Mainnet + * network
  • + *
  • {@link NetworkParameters#ID_TESTNET} - Testnet + * network
  • + *
  • {@link NetworkParameters#ID_REGTEST} - Regtest + * network
  • + *
+ * @return the difficulty cap as a {@link BigInteger} for the specified network. + * @throws IllegalArgumentException if the provided network parameter is + * invalid. + */ + public BigInteger getDifficultyCap(String networkParameter) { + switch (networkParameter) { + case NetworkParameters.ID_MAINNET: + return NetworkDifficultyCap.MAINNET.getDifficultyCap(); + case NetworkParameters.ID_TESTNET: + return NetworkDifficultyCap.TESTNET.getDifficultyCap(); + case NetworkParameters.ID_REGTEST: + return NetworkDifficultyCap.REGTEST.getDifficultyCap(); + default: + String message = "Invalid network provided: " + networkParameter; + logger.error(message); + throw new IllegalArgumentException(message); + } + } +} diff --git a/src/main/java/co/rsk/federate/signing/hsm/config/PowHSMConfigParameter.java b/src/main/java/co/rsk/federate/signing/hsm/config/PowHSMConfigParameter.java new file mode 100644 index 00000000..f94e05fe --- /dev/null +++ b/src/main/java/co/rsk/federate/signing/hsm/config/PowHSMConfigParameter.java @@ -0,0 +1,49 @@ +package co.rsk.federate.signing.hsm.config; + +import java.util.Objects; +import java.util.function.Function; + +public enum PowHSMConfigParameter { + // general + HOST("host", ""), + PORT("port", ""), + INTERVAL_BETWEEN_ATTEMPTS("intervalBetweenAttempts", "1000"), + MAX_ATTEMPTS("maxAttempts", "2"), + SOCKET_TIMEOUT("socketTimeout", "20000"), + // bookkeeping + DIFFICULTY_TARGET("bookkeeping.difficultyTarget", ""), + INFORMER_INTERVAL("bookkeeping.informerInterval", "360000"), // 6 minutes in milliseconds + MAX_AMOUNT_BLOCK_HEADERS("bookkeeping.maxAmountBlockHeaders", "100"), + MAX_CHUNK_SIZE_TO_HSM("bookkeeping.maxChunkSizeToHsm", "100"), + STOP_BOOKKEEPING_SCHEDULER("bookkeeping.stopBookkeepingScheduler", Boolean.toString(false)); + + private final String path; + private final String defaultValue; + + PowHSMConfigParameter(String path, String defaultValue) { + this.path = path; + this.defaultValue = defaultValue; + } + + public String getPath() { + return path; + } + + public T getDefaultValue(Function parser) { + Objects.requireNonNull(parser); + + if (defaultValue.isEmpty()) { + throw new IllegalStateException( + "No PowHSM config default value present for: " + path); + } + return parser.apply(defaultValue); + } + + @Override + public String toString() { + return "PowHSMConfigParameter{" + + "path='" + path + '\'' + + ", defaultValue='" + defaultValue + '\'' + + '}'; + } +} diff --git a/src/main/java/co/rsk/federate/util/HSMChecker.java b/src/main/java/co/rsk/federate/util/HSMChecker.java index d4e2a800..b4bf0b55 100644 --- a/src/main/java/co/rsk/federate/util/HSMChecker.java +++ b/src/main/java/co/rsk/federate/util/HSMChecker.java @@ -20,17 +20,16 @@ import co.rsk.bitcoinj.core.Sha256Hash; import co.rsk.federate.rpc.SocketBasedJsonRpcClientProvider; -import co.rsk.federate.signing.*; import co.rsk.federate.signing.hsm.client.HSMSigningClient; import co.rsk.federate.signing.hsm.client.HSMClientProtocol; import co.rsk.federate.signing.hsm.client.HSMSigningClientProvider; +import co.rsk.federate.signing.hsm.config.PowHSMConfigParameter; import co.rsk.federate.signing.hsm.client.HSMSignature; import co.rsk.federate.signing.hsm.HSMClientException; import co.rsk.federate.signing.hsm.message.SignerMessage; import co.rsk.federate.signing.hsm.message.SignerMessageV1; import org.ethereum.crypto.ECKey; import org.bouncycastle.util.encoders.Hex; - import java.util.Arrays; import java.util.Random; @@ -66,8 +65,11 @@ public static void main(String[] args) { System.out.printf("Connecting to HSM @ %s:%d...\n", host, port); SocketBasedJsonRpcClientProvider jsonRpcClientProvider = SocketBasedJsonRpcClientProvider.fromHostPort(host, port); - jsonRpcClientProvider.setSocketTimeout(ECDSASignerFactory.DEFAULT_SOCKET_TIMEOUT); - HSMClientProtocol hsmClientProtocol = new HSMClientProtocol(jsonRpcClientProvider, ECDSASignerFactory.DEFAULT_ATTEMPTS, ECDSASignerFactory.DEFAULT_INTERVAL); + jsonRpcClientProvider.setSocketTimeout(PowHSMConfigParameter.SOCKET_TIMEOUT.getDefaultValue(Integer::parseInt)); + HSMClientProtocol hsmClientProtocol = new HSMClientProtocol( + jsonRpcClientProvider, + PowHSMConfigParameter.MAX_ATTEMPTS.getDefaultValue(Integer::parseInt), + PowHSMConfigParameter.INTERVAL_BETWEEN_ATTEMPTS.getDefaultValue(Integer::parseInt)); HSMSigningClientProvider hsmSigningClientProvider = new HSMSigningClientProvider(hsmClientProtocol, ""); HSMSigningClient client = hsmSigningClientProvider.getSigningClient(); System.out.printf("Connected. Testing.\n"); diff --git a/src/test/java/co/rsk/federate/BtcToRskClientBuilder.java b/src/test/java/co/rsk/federate/BtcToRskClientBuilder.java index 20426558..1cc7ec6c 100644 --- a/src/test/java/co/rsk/federate/BtcToRskClientBuilder.java +++ b/src/test/java/co/rsk/federate/BtcToRskClientBuilder.java @@ -5,7 +5,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import co.rsk.federate.config.FedNodeSystemProperties; +import co.rsk.federate.config.PowpegNodeSystemProperties; import co.rsk.peg.constants.BridgeConstants; import co.rsk.federate.bitcoin.BitcoinWrapper; import co.rsk.federate.io.BtcToRskClientFileData; @@ -28,7 +28,7 @@ public class BtcToRskClientBuilder { private BtcLockSenderProvider btcLockSenderProvider; private PeginInstructionsProvider peginInstructionsProvider; private Federation federation; - private FedNodeSystemProperties config; + private PowpegNodeSystemProperties config; public BtcToRskClientBuilder() throws PeginInstructionsException, IOException { this.activationConfig = mock(ActivationConfig.class); @@ -39,7 +39,7 @@ public BtcToRskClientBuilder() throws PeginInstructionsException, IOException { this.btcLockSenderProvider = mock(BtcLockSenderProvider.class); this.peginInstructionsProvider = mock(PeginInstructionsProvider.class); this.federation = mock(Federation.class); - this.config = mock(FedNodeSystemProperties.class); + this.config = mock(PowpegNodeSystemProperties.class); when(activationConfig.forBlock(anyLong())).thenReturn(mock(ActivationConfig.ForBlock.class)); when(btcToRskClientFileStorage.read(any())).thenReturn(new BtcToRskClientFileReadResult(true, new BtcToRskClientFileData())); @@ -93,7 +93,7 @@ public BtcToRskClientBuilder withFederation(Federation federation) { return this; } - public BtcToRskClientBuilder withFedNodeSystemProperties(FedNodeSystemProperties config) { + public BtcToRskClientBuilder withFedNodeSystemProperties(PowpegNodeSystemProperties config) { this.config = config; return this; } diff --git a/src/test/java/co/rsk/federate/BtcToRskClientTest.java b/src/test/java/co/rsk/federate/BtcToRskClientTest.java index 72ea9dd9..4e4be033 100644 --- a/src/test/java/co/rsk/federate/BtcToRskClientTest.java +++ b/src/test/java/co/rsk/federate/BtcToRskClientTest.java @@ -29,7 +29,7 @@ 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.config.PowpegNodeSystemProperties; import co.rsk.federate.signing.utils.TestUtils; import co.rsk.peg.constants.BridgeConstants; import co.rsk.peg.constants.BridgeRegTestConstants; @@ -191,7 +191,7 @@ private BtcToRskClient createClientWithMocks( BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.P2PKH); int amountOfHeadersToSend = 100; - FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + PowpegNodeSystemProperties config = mock(PowpegNodeSystemProperties.class); when(config.getAmountOfHeadersToSend()).thenReturn(amountOfHeadersToSend); return btcToRskClientBuilder @@ -213,7 +213,7 @@ private BtcToRskClient createClientWithMocksCustomFederation( BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.P2PKH); int amountOfHeadersToSend = 100; - FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + PowpegNodeSystemProperties config = mock(PowpegNodeSystemProperties.class); when(config.getAmountOfHeadersToSend()).thenReturn(amountOfHeadersToSend); return btcToRskClientBuilder @@ -823,7 +823,7 @@ void updateBlockchainWithBetterBlockchainInWalletBySixHundredBlocks_preRskip89() BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.P2PKH); int amountOfHeadersToSend = 345; - FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + PowpegNodeSystemProperties config = mock(PowpegNodeSystemProperties.class); when(config.getAmountOfHeadersToSend()).thenReturn(amountOfHeadersToSend); BtcToRskClient client = btcToRskClientBuilder @@ -954,7 +954,7 @@ void updateBlockchainWithBetterBlockchainInWalletBySixHundredBlocks() throws Exc BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.P2PKH); int amountOfHeadersToSend = 345; - FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + PowpegNodeSystemProperties config = mock(PowpegNodeSystemProperties.class); when(config.getAmountOfHeadersToSend()).thenReturn(amountOfHeadersToSend); BtcToRskClient client = btcToRskClientBuilder @@ -1000,7 +1000,7 @@ void updateBlockchainWithDeepFork() throws Exception { BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.P2PKH); int amountOfHeadersToSend = 215; - FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + PowpegNodeSystemProperties config = mock(PowpegNodeSystemProperties.class); when(config.getAmountOfHeadersToSend()).thenReturn(amountOfHeadersToSend); BtcToRskClient client = btcToRskClientBuilder @@ -1694,7 +1694,7 @@ void updateTransactionWithMultisig_before_rskip143() throws Exception { int amountOfHeadersToSend = 100; BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.P2SHMULTISIG); - FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + PowpegNodeSystemProperties config = mock(PowpegNodeSystemProperties.class); when(config.getAmountOfHeadersToSend()).thenReturn(amountOfHeadersToSend); BtcToRskClient client = btcToRskClientBuilder @@ -1841,7 +1841,7 @@ void updateTransactionWithSegwitCompatible_before_rskip143() throws Exception { BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.P2SHP2WPKH); int amountOfHeadersToSend = 100; - FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + PowpegNodeSystemProperties config = mock(PowpegNodeSystemProperties.class); when(config.getAmountOfHeadersToSend()).thenReturn(amountOfHeadersToSend); BtcToRskClient client = btcToRskClientBuilder @@ -1895,7 +1895,7 @@ void updateTransactionWithSenderUnknown_before_rskip170() throws Exception { BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.UNKNOWN); int amountOfHeadersToSend = 100; - FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + PowpegNodeSystemProperties config = mock(PowpegNodeSystemProperties.class); when(config.getAmountOfHeadersToSend()).thenReturn(amountOfHeadersToSend); BtcToRskClient client = btcToRskClientBuilder @@ -2480,7 +2480,7 @@ void updateBridge_whenUpdateBridgeConfigAreFalse_shouldNotCallAny() throws Excep BitcoinWrapper bitcoinWrapper = mock(BitcoinWrapper.class); when(bitcoinWrapper.getBestChainHeight()).thenReturn(1); - FedNodeSystemProperties config = getMockedFedNodeSystemProperties(false); + PowpegNodeSystemProperties config = getMockedFedNodeSystemProperties(false); BtcToRskClient btcToRskClient = spy(buildWithFactoryAndSetup( federatorSupport, @@ -2503,7 +2503,7 @@ void updateBridge_whenUpdateBridgeConfigAreFalse_shouldNotCallAny() throws Excep } @Test - void updateBridge_noUpdateBridgeConfigDefined_shouldOnlyCallSendUpdateCollections() throws Exception { + void updateBridge_noUpdateBridgeConfigDefined_shouldTriggerBridgeUpdates() throws Exception { NodeBlockProcessor nodeBlockProcessor = mock(NodeBlockProcessor.class); when(nodeBlockProcessor.hasBetterBlockToSync()).thenReturn(false); @@ -2516,7 +2516,7 @@ void updateBridge_noUpdateBridgeConfigDefined_shouldOnlyCallSendUpdateCollection CliArgs cliArgs = CliArgs.empty(); ConfigLoader configLoader = new ConfigLoader(cliArgs); - FedNodeSystemProperties config = new FedNodeSystemProperties(configLoader); + PowpegNodeSystemProperties config = new PowpegNodeSystemProperties(configLoader); BtcToRskClient btcToRskClient = spy(buildWithFactoryAndSetup( federatorSupport, @@ -2532,10 +2532,10 @@ void updateBridge_noUpdateBridgeConfigDefined_shouldOnlyCallSendUpdateCollection btcToRskClient.updateBridge(); - verify(btcToRskClient, times(0)).updateBridgeBtcBlockchain(); - verify(btcToRskClient, times(0)).updateBridgeBtcCoinbaseTransactions(); - verify(btcToRskClient, times(0)).updateBridgeBtcTransactions(); - verify(federatorSupport, times(1)).sendUpdateCollections(); + verify(btcToRskClient).updateBridgeBtcBlockchain(); + verify(btcToRskClient).updateBridgeBtcCoinbaseTransactions(); + verify(btcToRskClient).updateBridgeBtcTransactions(); + verify(federatorSupport).sendUpdateCollections(); } @Test @@ -2621,12 +2621,12 @@ private BtcToRskClient buildWithFactoryAndSetup( BtcToRskClientFileStorage btcToRskClientFileStorage, BtcLockSenderProvider btcLockSenderProvider, PeginInstructionsProvider peginInstructionsProvider, - FedNodeSystemProperties fedNodeSystemProperties + PowpegNodeSystemProperties fedNodeSystemProperties ) throws Exception { BtcToRskClient btcToRskClient = buildWithFactory(federatorSupport, nodeBlockProcessor); - FedNodeSystemProperties config = nonNull(fedNodeSystemProperties) ? fedNodeSystemProperties : getMockedFedNodeSystemProperties(true); + PowpegNodeSystemProperties config = nonNull(fedNodeSystemProperties) ? fedNodeSystemProperties : getMockedFedNodeSystemProperties(true); if(MockUtil.isMock(config)) { when(config.getActivationConfig()).thenReturn(activationConfig); @@ -2818,9 +2818,9 @@ private BtcLockSenderProvider mockBtcLockSenderProvider(TxSenderAddressType txSe return btcLockSenderProvider; } - private FedNodeSystemProperties getMockedFedNodeSystemProperties(boolean defaultBooleanConfigValue) { + private PowpegNodeSystemProperties getMockedFedNodeSystemProperties(boolean defaultBooleanConfigValue) { - FedNodeSystemProperties config = mock(FedNodeSystemProperties.class); + PowpegNodeSystemProperties config = mock(PowpegNodeSystemProperties.class); when(config.getAmountOfHeadersToSend()).thenReturn(100); when(config.isUpdateBridgeTimerEnabled()).thenReturn(defaultBooleanConfigValue); when(config.shouldUpdateBridgeBtcBlockchain()).thenReturn(defaultBooleanConfigValue); diff --git a/src/test/java/co/rsk/federate/FedNodeRunnerTest.java b/src/test/java/co/rsk/federate/FedNodeRunnerTest.java index 249dd3eb..93ade646 100644 --- a/src/test/java/co/rsk/federate/FedNodeRunnerTest.java +++ b/src/test/java/co/rsk/federate/FedNodeRunnerTest.java @@ -1,13 +1,15 @@ package co.rsk.federate; -import static co.rsk.federate.signing.PowPegNodeKeyId.BTC_KEY_ID; -import static co.rsk.federate.signing.PowPegNodeKeyId.MST_KEY_ID; -import static co.rsk.federate.signing.PowPegNodeKeyId.RSK_KEY_ID; +import static co.rsk.federate.signing.PowPegNodeKeyId.BTC; +import static co.rsk.federate.signing.PowPegNodeKeyId.MST; +import static co.rsk.federate.signing.PowPegNodeKeyId.RSK; +import static co.rsk.federate.signing.utils.TestUtils.createHash; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; @@ -18,23 +20,29 @@ import co.rsk.federate.signing.hsm.HSMVersion; import co.rsk.peg.constants.BridgeConstants; import co.rsk.federate.btcreleaseclient.BtcReleaseClient; -import co.rsk.federate.config.FedNodeSystemProperties; -import co.rsk.federate.config.SignerConfig; +import co.rsk.federate.config.PowpegNodeSystemProperties; +import co.rsk.federate.config.SignerConfigBuilder; +import co.rsk.federate.signing.config.SignerConfig; import co.rsk.federate.log.FederateLogger; import co.rsk.federate.log.RskLogMonitor; import co.rsk.federate.signing.ECDSACompositeSigner; import co.rsk.federate.signing.ECDSAHSMSigner; import co.rsk.federate.signing.ECDSASigner; import co.rsk.federate.signing.ECDSASignerFromFileKey; +import co.rsk.federate.signing.PowPegNodeKeyId; import co.rsk.federate.signing.hsm.HSMClientException; +import co.rsk.federate.signing.hsm.HSMUnsupportedTypeException; import co.rsk.federate.signing.hsm.advanceblockchain.HSMBookKeepingClientProvider; import co.rsk.federate.signing.hsm.advanceblockchain.HSMBookkeepingService; import co.rsk.federate.signing.hsm.client.HSMBookkeepingClient; import co.rsk.federate.signing.hsm.client.HSMClientProtocol; import co.rsk.federate.signing.hsm.client.HSMClientProtocolFactory; +import co.rsk.federate.signing.hsm.message.PowHSMBlockchainParameters; import co.rsk.federate.signing.utils.TestUtils; import com.typesafe.config.Config; +import com.typesafe.config.ConfigException; import java.io.IOException; +import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.attribute.PosixFilePermissions; @@ -45,13 +53,13 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -/** - * Created by Kelvin Isievwore on 24/04/2023. - */ class FedNodeRunnerTest { + private FedNodeRunner fedNodeRunner; - private FedNodeSystemProperties fedNodeSystemProperties; + private PowpegNodeSystemProperties fedNodeSystemProperties; private Config keyFileConfig; + private Path keyFilePath; + private HSMBookkeepingClient hsmBookkeepingClient; @TempDir public Path temporaryFolder; @@ -59,7 +67,7 @@ class FedNodeRunnerTest { @BeforeEach void setUp() throws IOException, HSMClientException { // Create temp key file - Path keyFilePath = temporaryFolder.resolve("reg1.key"); + keyFilePath = temporaryFolder.resolve("reg1.key"); Files.write(keyFilePath, Collections.singletonList("45c5b07fc1a6f58892615b7c31dca6c96db58c4bbc538a6b8a22999aaa860c32")); Files.setPosixFilePermissions(keyFilePath, PosixFilePermissions.fromString("r--------")); // Add only read permission @@ -68,7 +76,7 @@ void setUp() throws IOException, HSMClientException { BridgeConstants bridgeConstants = mock(BridgeConstants.class); Constants constants = mock(Constants.class); - fedNodeSystemProperties = mock(FedNodeSystemProperties.class); + fedNodeSystemProperties = mock(PowpegNodeSystemProperties.class); when(fedNodeSystemProperties.getNetworkConstants()).thenReturn(constants); when(constants.getBridgeConstants()).thenReturn(bridgeConstants); when(bridgeConstants.getBtcParamsString()).thenReturn(NetworkParameters.ID_REGTEST); @@ -79,7 +87,7 @@ void setUp() throws IOException, HSMClientException { HSMClientProtocolFactory hsmClientProtocolFactory = mock(HSMClientProtocolFactory.class); when(hsmClientProtocolFactory.buildHSMClientProtocolFromConfig(any())).thenReturn(protocol); - HSMBookkeepingClient hsmBookkeepingClient = mock(HSMBookkeepingClient.class); + hsmBookkeepingClient = mock(HSMBookkeepingClient.class); when(hsmBookkeepingClient.getVersion()).thenReturn(hsmVersion); HSMBookKeepingClientProvider hsmBookKeepingClientProvider = mock(HSMBookKeepingClientProvider.class); when(hsmBookKeepingClientProvider.getHSMBookKeepingClient(any())).thenReturn(hsmBookkeepingClient); @@ -105,17 +113,17 @@ void test_with_hsm_v2_config_Ok() throws Exception { SignerConfig btcSignerConfig = getHSMBTCSignerConfig(HSMVersion.V2); SignerConfig rskSignerConfig = getHSMRSKSignerConfig(); SignerConfig mstSignerConfig = getHSMMSTSignerConfig(); - when(fedNodeSystemProperties.signerConfig(BTC_KEY_ID.getId())).thenReturn(btcSignerConfig); - when(fedNodeSystemProperties.signerConfig(RSK_KEY_ID.getId())).thenReturn(rskSignerConfig); - when(fedNodeSystemProperties.signerConfig(MST_KEY_ID.getId())).thenReturn(mstSignerConfig); + when(fedNodeSystemProperties.signerConfig(BTC.getId())).thenReturn(btcSignerConfig); + when(fedNodeSystemProperties.signerConfig(RSK.getId())).thenReturn(rskSignerConfig); + when(fedNodeSystemProperties.signerConfig(MST.getId())).thenReturn(mstSignerConfig); fedNodeRunner.run(); ECDSASigner signer = TestUtils.getInternalState(fedNodeRunner, "signer"); assertNotNull(signer); - assertTrue(signer.canSignWith(BTC_KEY_ID.getKeyId())); - assertTrue(signer.canSignWith(RSK_KEY_ID.getKeyId())); - assertTrue(signer.canSignWith(MST_KEY_ID.getKeyId())); + assertTrue(signer.canSignWith(BTC.getKeyId())); + assertTrue(signer.canSignWith(RSK.getKeyId())); + assertTrue(signer.canSignWith(MST.getKeyId())); assertInstanceOf(ECDSACompositeSigner.class, signer); ECDSACompositeSigner compositeSigner = (ECDSACompositeSigner) signer; @@ -123,8 +131,8 @@ void test_with_hsm_v2_config_Ok() throws Exception { assertEquals(3, signers.size()); signers.forEach(hsmSigner -> assertInstanceOf(ECDSAHSMSigner.class, hsmSigner)); - HSMBookkeepingClient hsmBookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); - assertNotNull(hsmBookkeepingClient); + HSMBookkeepingClient bookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); + assertNotNull(bookkeepingClient); HSMBookkeepingService hsmBookkeepingService = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingService"); assertNotNull(hsmBookkeepingService); @@ -135,9 +143,9 @@ void test_with_hsm_v1_config() throws Exception { SignerConfig btcSignerConfig = getHSMBTCSignerConfig(HSMVersion.V1); SignerConfig rskSignerConfig = getHSMRSKSignerConfig(); SignerConfig mstSignerConfig = getHSMMSTSignerConfig(); - when(fedNodeSystemProperties.signerConfig(BTC_KEY_ID.getId())).thenReturn(btcSignerConfig); - when(fedNodeSystemProperties.signerConfig(RSK_KEY_ID.getId())).thenReturn(rskSignerConfig); - when(fedNodeSystemProperties.signerConfig(MST_KEY_ID.getId())).thenReturn(mstSignerConfig); + when(fedNodeSystemProperties.signerConfig(BTC.getId())).thenReturn(btcSignerConfig); + when(fedNodeSystemProperties.signerConfig(RSK.getId())).thenReturn(rskSignerConfig); + when(fedNodeSystemProperties.signerConfig(MST.getId())).thenReturn(mstSignerConfig); HSMClientProtocol protocol = mock(HSMClientProtocol.class); when(protocol.getVersion()).thenReturn(1); @@ -163,9 +171,9 @@ void test_with_hsm_v1_config() throws Exception { ECDSASigner signer = TestUtils.getInternalState(fedNodeRunner, "signer"); assertNotNull(signer); - assertTrue(signer.canSignWith(BTC_KEY_ID.getKeyId())); - assertTrue(signer.canSignWith(RSK_KEY_ID.getKeyId())); - assertTrue(signer.canSignWith(MST_KEY_ID.getKeyId())); + assertTrue(signer.canSignWith(BTC.getKeyId())); + assertTrue(signer.canSignWith(RSK.getKeyId())); + assertTrue(signer.canSignWith(MST.getKeyId())); assertInstanceOf(ECDSACompositeSigner.class, signer); ECDSACompositeSigner compositeSigner = (ECDSACompositeSigner) signer; @@ -184,16 +192,16 @@ void test_with_hsm_v1_config() throws Exception { void test_with_hsm_config_without_btc() throws Exception { SignerConfig rskSignerConfig = getHSMRSKSignerConfig(); SignerConfig mstSignerConfig = getHSMMSTSignerConfig(); - when(fedNodeSystemProperties.signerConfig(RSK_KEY_ID.getId())).thenReturn(rskSignerConfig); - when(fedNodeSystemProperties.signerConfig(MST_KEY_ID.getId())).thenReturn(mstSignerConfig); + when(fedNodeSystemProperties.signerConfig(RSK.getId())).thenReturn(rskSignerConfig); + when(fedNodeSystemProperties.signerConfig(MST.getId())).thenReturn(mstSignerConfig); fedNodeRunner.run(); ECDSASigner signer = TestUtils.getInternalState(fedNodeRunner, "signer"); assertNotNull(signer); - assertFalse(signer.canSignWith(BTC_KEY_ID.getKeyId())); - assertTrue(signer.canSignWith(RSK_KEY_ID.getKeyId())); - assertTrue(signer.canSignWith(MST_KEY_ID.getKeyId())); + assertFalse(signer.canSignWith(BTC.getKeyId())); + assertTrue(signer.canSignWith(RSK.getKeyId())); + assertTrue(signer.canSignWith(MST.getKeyId())); assertInstanceOf(ECDSACompositeSigner.class, signer); ECDSACompositeSigner compositeSigner = (ECDSACompositeSigner) signer; @@ -201,8 +209,8 @@ void test_with_hsm_config_without_btc() throws Exception { assertEquals(2, signers.size()); signers.forEach(hsmSigner -> assertInstanceOf(ECDSAHSMSigner.class, hsmSigner)); - HSMBookkeepingClient hsmBookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); - assertNull(hsmBookkeepingClient); + HSMBookkeepingClient bookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); + assertNull(bookkeepingClient); HSMBookkeepingService hsmBookkeepingService = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingService"); assertNull(hsmBookkeepingService); @@ -212,16 +220,16 @@ void test_with_hsm_config_without_btc() throws Exception { void test_with_hsm_v2_config_without_rsk() throws Exception { SignerConfig btcSignerConfig = getHSMBTCSignerConfig(HSMVersion.V2); SignerConfig mstSignerConfig = getHSMMSTSignerConfig(); - when(fedNodeSystemProperties.signerConfig(BTC_KEY_ID.getId())).thenReturn(btcSignerConfig); - when(fedNodeSystemProperties.signerConfig(MST_KEY_ID.getId())).thenReturn(mstSignerConfig); + when(fedNodeSystemProperties.signerConfig(BTC.getId())).thenReturn(btcSignerConfig); + when(fedNodeSystemProperties.signerConfig(MST.getId())).thenReturn(mstSignerConfig); fedNodeRunner.run(); ECDSASigner signer = TestUtils.getInternalState(fedNodeRunner, "signer"); assertNotNull(signer); - assertTrue(signer.canSignWith(BTC_KEY_ID.getKeyId())); - assertFalse(signer.canSignWith(RSK_KEY_ID.getKeyId())); - assertTrue(signer.canSignWith(MST_KEY_ID.getKeyId())); + assertTrue(signer.canSignWith(BTC.getKeyId())); + assertFalse(signer.canSignWith(RSK.getKeyId())); + assertTrue(signer.canSignWith(MST.getKeyId())); assertInstanceOf(ECDSACompositeSigner.class, signer); ECDSACompositeSigner compositeSigner = (ECDSACompositeSigner) signer; @@ -229,8 +237,8 @@ void test_with_hsm_v2_config_without_rsk() throws Exception { assertEquals(2, signers.size()); signers.forEach(hsmSigner -> assertInstanceOf(ECDSAHSMSigner.class, hsmSigner)); - HSMBookkeepingClient hsmBookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); - assertNotNull(hsmBookkeepingClient); + HSMBookkeepingClient bookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); + assertNotNull(bookkeepingClient); HSMBookkeepingService hsmBookkeepingService = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingService"); assertNotNull(hsmBookkeepingService); @@ -240,16 +248,16 @@ void test_with_hsm_v2_config_without_rsk() throws Exception { void test_with_hsm_v2_config_without_mst() throws Exception { SignerConfig btcSignerConfig = getHSMBTCSignerConfig(HSMVersion.V2); SignerConfig rskSignerConfig = getHSMRSKSignerConfig(); - when(fedNodeSystemProperties.signerConfig(BTC_KEY_ID.getId())).thenReturn(btcSignerConfig); - when(fedNodeSystemProperties.signerConfig(RSK_KEY_ID.getId())).thenReturn(rskSignerConfig); + when(fedNodeSystemProperties.signerConfig(BTC.getId())).thenReturn(btcSignerConfig); + when(fedNodeSystemProperties.signerConfig(RSK.getId())).thenReturn(rskSignerConfig); fedNodeRunner.run(); ECDSASigner signer = TestUtils.getInternalState(fedNodeRunner, "signer"); assertNotNull(signer); - assertTrue(signer.canSignWith(BTC_KEY_ID.getKeyId())); - assertTrue(signer.canSignWith(RSK_KEY_ID.getKeyId())); - assertFalse(signer.canSignWith(MST_KEY_ID.getKeyId())); + assertTrue(signer.canSignWith(BTC.getKeyId())); + assertTrue(signer.canSignWith(RSK.getKeyId())); + assertFalse(signer.canSignWith(MST.getKeyId())); assertInstanceOf(ECDSACompositeSigner.class, signer); ECDSACompositeSigner compositeSigner = (ECDSACompositeSigner) signer; @@ -257,8 +265,8 @@ void test_with_hsm_v2_config_without_mst() throws Exception { assertEquals(2, signers.size()); signers.forEach(hsmSigner -> assertInstanceOf(ECDSAHSMSigner.class, hsmSigner)); - HSMBookkeepingClient hsmBookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); - assertNotNull(hsmBookkeepingClient); + HSMBookkeepingClient bookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); + assertNotNull(bookkeepingClient); HSMBookkeepingService hsmBookkeepingService = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingService"); assertNotNull(hsmBookkeepingService); @@ -266,36 +274,36 @@ void test_with_hsm_v2_config_without_mst() throws Exception { @Test void test_with_KeyFile_config_Ok() throws Exception { - SignerConfig btcSignerConfig = getBTCSignerConfig(); - SignerConfig rskSignerConfig = getRSKSignerConfig(); - SignerConfig mstSignerConfig = getMSTSignerConfig(); - when(fedNodeSystemProperties.signerConfig(BTC_KEY_ID.getId())).thenReturn(btcSignerConfig); - when(fedNodeSystemProperties.signerConfig(RSK_KEY_ID.getId())).thenReturn(rskSignerConfig); - when(fedNodeSystemProperties.signerConfig(MST_KEY_ID.getId())).thenReturn(mstSignerConfig); + SignerConfig btcSignerConfig = getBTCSignerConfig(keyFilePath.toString()); + SignerConfig rskSignerConfig = getRSKSignerConfig(keyFilePath.toString()); + SignerConfig mstSignerConfig = getMSTSignerConfig(keyFilePath.toString()); + when(fedNodeSystemProperties.signerConfig(BTC.getId())).thenReturn(btcSignerConfig); + when(fedNodeSystemProperties.signerConfig(RSK.getId())).thenReturn(rskSignerConfig); + when(fedNodeSystemProperties.signerConfig(MST.getId())).thenReturn(mstSignerConfig); fedNodeRunner.run(); ECDSASigner signer = TestUtils.getInternalState(fedNodeRunner, "signer"); assertNotNull(signer); - assertTrue(signer.canSignWith(BTC_KEY_ID.getKeyId())); - assertTrue(signer.canSignWith(RSK_KEY_ID.getKeyId())); - assertTrue(signer.canSignWith(MST_KEY_ID.getKeyId())); + assertTrue(signer.canSignWith(BTC.getKeyId())); + assertTrue(signer.canSignWith(RSK.getKeyId())); + assertTrue(signer.canSignWith(MST.getKeyId())); assertInstanceOf(ECDSACompositeSigner.class, signer); ECDSACompositeSigner compositeSigner = (ECDSACompositeSigner) signer; List signers = TestUtils.getInternalState(compositeSigner, "signers"); assertEquals(3, signers.size()); - assertEquals(1, signers.get(0).getVersionForKeyId(BTC_KEY_ID.getKeyId())); - assertEquals(1, signers.get(1).getVersionForKeyId(RSK_KEY_ID.getKeyId())); - assertEquals(1, signers.get(2).getVersionForKeyId(MST_KEY_ID.getKeyId())); + assertEquals(1, signers.get(0).getVersionForKeyId(BTC.getKeyId())); + assertEquals(1, signers.get(1).getVersionForKeyId(RSK.getKeyId())); + assertEquals(1, signers.get(2).getVersionForKeyId(MST.getKeyId())); signers.forEach(keyFileSigner -> { assertInstanceOf(ECDSASignerFromFileKey.class, keyFileSigner); assertTrue(keyFileSigner.check().wasSuccessful()); assertTrue(keyFileSigner.check().getMessages().isEmpty()); }); - HSMBookkeepingClient hsmBookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); - assertNull(hsmBookkeepingClient); + HSMBookkeepingClient bookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); + assertNull(bookkeepingClient); HSMBookkeepingService hsmBookkeepingService = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingService"); assertNull(hsmBookkeepingService); @@ -303,28 +311,28 @@ void test_with_KeyFile_config_Ok() throws Exception { @Test void test_with_KeyFile_config_without_btc() throws Exception { - SignerConfig rskSignerConfig = getRSKSignerConfig(); - SignerConfig mstSignerConfig = getMSTSignerConfig(); - when(fedNodeSystemProperties.signerConfig(RSK_KEY_ID.getId())).thenReturn(rskSignerConfig); - when(fedNodeSystemProperties.signerConfig(MST_KEY_ID.getId())).thenReturn(mstSignerConfig); + SignerConfig rskSignerConfig = getRSKSignerConfig(keyFilePath.toString()); + SignerConfig mstSignerConfig = getMSTSignerConfig(keyFilePath.toString()); + when(fedNodeSystemProperties.signerConfig(RSK.getId())).thenReturn(rskSignerConfig); + when(fedNodeSystemProperties.signerConfig(MST.getId())).thenReturn(mstSignerConfig); fedNodeRunner.run(); ECDSASigner signer = TestUtils.getInternalState(fedNodeRunner, "signer"); assertNotNull(signer); - assertFalse(signer.canSignWith(BTC_KEY_ID.getKeyId())); - assertTrue(signer.canSignWith(RSK_KEY_ID.getKeyId())); - assertTrue(signer.canSignWith(MST_KEY_ID.getKeyId())); + assertFalse(signer.canSignWith(BTC.getKeyId())); + assertTrue(signer.canSignWith(RSK.getKeyId())); + assertTrue(signer.canSignWith(MST.getKeyId())); assertInstanceOf(ECDSACompositeSigner.class, signer); ECDSACompositeSigner compositeSigner = (ECDSACompositeSigner) signer; List signers = TestUtils.getInternalState(compositeSigner, "signers"); assertEquals(2, signers.size()); - assertEquals(1, signers.get(0).getVersionForKeyId(RSK_KEY_ID.getKeyId())); - assertEquals(1, signers.get(1).getVersionForKeyId(MST_KEY_ID.getKeyId())); + assertEquals(1, signers.get(0).getVersionForKeyId(RSK.getKeyId())); + assertEquals(1, signers.get(1).getVersionForKeyId(MST.getKeyId())); - HSMBookkeepingClient hsmBookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); - assertNull(hsmBookkeepingClient); + HSMBookkeepingClient bookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); + assertNull(bookkeepingClient); HSMBookkeepingService hsmBookkeepingService = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingService"); assertNull(hsmBookkeepingService); @@ -332,28 +340,28 @@ void test_with_KeyFile_config_without_btc() throws Exception { @Test void test_with_KeyFile_config_without_rsk() throws Exception { - SignerConfig btcSignerConfig = getBTCSignerConfig(); - SignerConfig mstSignerConfig = getMSTSignerConfig(); - when(fedNodeSystemProperties.signerConfig(BTC_KEY_ID.getId())).thenReturn(btcSignerConfig); - when(fedNodeSystemProperties.signerConfig(MST_KEY_ID.getId())).thenReturn(mstSignerConfig); + SignerConfig btcSignerConfig = getBTCSignerConfig(keyFilePath.toString()); + SignerConfig mstSignerConfig = getMSTSignerConfig(keyFilePath.toString()); + when(fedNodeSystemProperties.signerConfig(BTC.getId())).thenReturn(btcSignerConfig); + when(fedNodeSystemProperties.signerConfig(MST.getId())).thenReturn(mstSignerConfig); fedNodeRunner.run(); ECDSASigner signer = TestUtils.getInternalState(fedNodeRunner, "signer"); assertNotNull(signer); - assertTrue(signer.canSignWith(BTC_KEY_ID.getKeyId())); - assertFalse(signer.canSignWith(RSK_KEY_ID.getKeyId())); - assertTrue(signer.canSignWith(MST_KEY_ID.getKeyId())); + assertTrue(signer.canSignWith(BTC.getKeyId())); + assertFalse(signer.canSignWith(RSK.getKeyId())); + assertTrue(signer.canSignWith(MST.getKeyId())); assertInstanceOf(ECDSACompositeSigner.class, signer); ECDSACompositeSigner compositeSigner = (ECDSACompositeSigner) signer; List signers = TestUtils.getInternalState(compositeSigner, "signers"); assertEquals(2, signers.size()); - assertEquals(1, signers.get(0).getVersionForKeyId(BTC_KEY_ID.getKeyId())); - assertEquals(1, signers.get(1).getVersionForKeyId(MST_KEY_ID.getKeyId())); + assertEquals(1, signers.get(0).getVersionForKeyId(BTC.getKeyId())); + assertEquals(1, signers.get(1).getVersionForKeyId(MST.getKeyId())); - HSMBookkeepingClient hsmBookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); - assertNull(hsmBookkeepingClient); + HSMBookkeepingClient bookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); + assertNull(bookkeepingClient); HSMBookkeepingService hsmBookkeepingService = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingService"); assertNull(hsmBookkeepingService); @@ -361,28 +369,28 @@ void test_with_KeyFile_config_without_rsk() throws Exception { @Test void test_with_KeyFile_config_without_mst() throws Exception { - SignerConfig btcSignerConfig = getBTCSignerConfig(); - SignerConfig rskSignerConfig = getRSKSignerConfig(); - when(fedNodeSystemProperties.signerConfig(BTC_KEY_ID.getId())).thenReturn(btcSignerConfig); - when(fedNodeSystemProperties.signerConfig(RSK_KEY_ID.getId())).thenReturn(rskSignerConfig); + SignerConfig btcSignerConfig = getBTCSignerConfig(keyFilePath.toString()); + SignerConfig rskSignerConfig = getRSKSignerConfig(keyFilePath.toString()); + when(fedNodeSystemProperties.signerConfig(BTC.getId())).thenReturn(btcSignerConfig); + when(fedNodeSystemProperties.signerConfig(RSK.getId())).thenReturn(rskSignerConfig); fedNodeRunner.run(); ECDSASigner signer = TestUtils.getInternalState(fedNodeRunner, "signer"); assertNotNull(signer); - assertTrue(signer.canSignWith(BTC_KEY_ID.getKeyId())); - assertTrue(signer.canSignWith(RSK_KEY_ID.getKeyId())); - assertFalse(signer.canSignWith(MST_KEY_ID.getKeyId())); + assertTrue(signer.canSignWith(BTC.getKeyId())); + assertTrue(signer.canSignWith(RSK.getKeyId())); + assertFalse(signer.canSignWith(MST.getKeyId())); assertInstanceOf(ECDSACompositeSigner.class, signer); ECDSACompositeSigner compositeSigner = (ECDSACompositeSigner) signer; List signers = TestUtils.getInternalState(compositeSigner, "signers"); assertEquals(2, signers.size()); - assertEquals(1, signers.get(0).getVersionForKeyId(BTC_KEY_ID.getKeyId())); - assertEquals(1, signers.get(1).getVersionForKeyId(RSK_KEY_ID.getKeyId())); + assertEquals(1, signers.get(0).getVersionForKeyId(BTC.getKeyId())); + assertEquals(1, signers.get(1).getVersionForKeyId(RSK.getKeyId())); - HSMBookkeepingClient hsmBookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); - assertNull(hsmBookkeepingClient); + HSMBookkeepingClient bookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); + assertNull(bookkeepingClient); HSMBookkeepingService hsmBookkeepingService = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingService"); assertNull(hsmBookkeepingService); @@ -390,17 +398,12 @@ void test_with_KeyFile_config_without_mst() throws Exception { @Test void test_KeyFile_config_with_no_path() throws Exception { - Config mockConfig = mock(Config.class); - when(mockConfig.getString("path")).thenReturn(""); - SignerConfig btcSignerConfig = getBTCSignerConfig(); - when(btcSignerConfig.getConfig()).thenReturn(mockConfig); - SignerConfig rskSignerConfig = getRSKSignerConfig(); - when(rskSignerConfig.getConfig()).thenReturn(mockConfig); - SignerConfig mstSignerConfig = getMSTSignerConfig(); - when(mstSignerConfig.getConfig()).thenReturn(mockConfig); - when(fedNodeSystemProperties.signerConfig(BTC_KEY_ID.getId())).thenReturn(btcSignerConfig); - when(fedNodeSystemProperties.signerConfig(RSK_KEY_ID.getId())).thenReturn(rskSignerConfig); - when(fedNodeSystemProperties.signerConfig(MST_KEY_ID.getId())).thenReturn(mstSignerConfig); + SignerConfig btcSignerConfig = getBTCSignerConfig(""); + SignerConfig rskSignerConfig = getRSKSignerConfig(""); + SignerConfig mstSignerConfig = getMSTSignerConfig(""); + when(fedNodeSystemProperties.signerConfig(BTC.getId())).thenReturn(btcSignerConfig); + when(fedNodeSystemProperties.signerConfig(RSK.getId())).thenReturn(rskSignerConfig); + when(fedNodeSystemProperties.signerConfig(MST.getId())).thenReturn(mstSignerConfig); fedNodeRunner.run(); @@ -421,99 +424,87 @@ void test_with_no_config() throws Exception { ECDSASigner signer = TestUtils.getInternalState(fedNodeRunner, "signer"); assertNotNull(signer); - assertFalse(signer.canSignWith(BTC_KEY_ID.getKeyId())); - assertFalse(signer.canSignWith(RSK_KEY_ID.getKeyId())); - assertFalse(signer.canSignWith(MST_KEY_ID.getKeyId())); + assertFalse(signer.canSignWith(BTC.getKeyId())); + assertFalse(signer.canSignWith(RSK.getKeyId())); + assertFalse(signer.canSignWith(MST.getKeyId())); assertInstanceOf(ECDSACompositeSigner.class, signer); ECDSACompositeSigner compositeSigner = (ECDSACompositeSigner) signer; List signers = TestUtils.getInternalState(compositeSigner, "signers"); assertEquals(0, signers.size()); - HSMBookkeepingClient hsmBookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); - assertNull(hsmBookkeepingClient); + HSMBookkeepingClient bookkeepingClient = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingClient"); + assertNull(bookkeepingClient); HSMBookkeepingService hsmBookkeepingService = TestUtils.getInternalState(fedNodeRunner, "hsmBookkeepingService"); assertNull(hsmBookkeepingService); } - private SignerConfig getBTCSignerConfig() { - SignerConfig btcSignerConfig = mock(SignerConfig.class); - when(btcSignerConfig.getId()).thenReturn("BTC"); - when(btcSignerConfig.getType()).thenReturn("keyFile"); - when(btcSignerConfig.getConfig()).thenReturn(keyFileConfig); - return btcSignerConfig; + @Test + void run_whenHsmVersionIsLowerThanThreeAndDifficultyTargetConfigIsNotPresent_shouldThrowException() throws Exception { + int version = 2; + when(hsmBookkeepingClient.getVersion()).thenReturn(version); + when(hsmBookkeepingClient.getBlockchainParameters()).thenThrow( + new HSMUnsupportedTypeException("PowHSM version: " + version)); + SignerConfig btcSignerConfig = SignerConfigBuilder.builder() + .withHsmSigner("m/44'/0'/0'/0/0") + .withHsmBookkeepingInfo(null, 500000L, 1000, 100, true) + .build(PowPegNodeKeyId.BTC); + when(fedNodeSystemProperties.signerConfig(BTC.getId())).thenReturn(btcSignerConfig); + + assertThrows(ConfigException.class, () -> fedNodeRunner.run()); } - private SignerConfig getRSKSignerConfig() { - SignerConfig rskSignerConfig = mock(SignerConfig.class); - when(rskSignerConfig.getId()).thenReturn("RSK"); - when(rskSignerConfig.getType()).thenReturn("keyFile"); - when(rskSignerConfig.getConfig()).thenReturn(keyFileConfig); - return rskSignerConfig; + private SignerConfig getBTCSignerConfig(String path) { + return SignerConfigBuilder.builder() + .withKeyFileSigner(path) + .build(PowPegNodeKeyId.BTC); } - private SignerConfig getMSTSignerConfig() { - SignerConfig mstSignerConfig = mock(SignerConfig.class); - when(mstSignerConfig.getId()).thenReturn("MST"); - when(mstSignerConfig.getType()).thenReturn("keyFile"); - when(mstSignerConfig.getConfig()).thenReturn(keyFileConfig); - return mstSignerConfig; + private SignerConfig getRSKSignerConfig(String path) { + return SignerConfigBuilder.builder() + .withKeyFileSigner(path) + .build(PowPegNodeKeyId.RSK); } - private SignerConfig getHSMBTCSignerConfig(HSMVersion version) { - SignerConfig btcSignerConfig = mock(SignerConfig.class); - Config hsmConfig = mock(Config.class); - when(btcSignerConfig.getId()).thenReturn("BTC"); - when(btcSignerConfig.getType()).thenReturn("hsm"); - when(btcSignerConfig.getConfig()).thenReturn(hsmConfig); - when(hsmConfig.getString("host")).thenReturn("127.0.0.1"); - when(hsmConfig.getInt("port")).thenReturn(9999); - when(hsmConfig.getString("keyId")).thenReturn("m/44'/0'/0'/0/0"); - - if (HSMVersion.isPowHSM(version)) { - when(hsmConfig.hasPath("socketTimeout")).thenReturn(true); - when(hsmConfig.getInt("socketTimeout")).thenReturn(20000); - when(hsmConfig.hasPath("maxAttempts")).thenReturn(true); - when(hsmConfig.getInt("maxAttempts")).thenReturn(3); - when(hsmConfig.hasPath("intervalBetweenAttempts")).thenReturn(true); - when(hsmConfig.getInt("intervalBetweenAttempts")).thenReturn(2000); - when(hsmConfig.hasPath("bookkeeping.difficultyTarget")).thenReturn(true); - when(hsmConfig.getString("bookkeeping.difficultyTarget")).thenReturn("4405500"); - when(hsmConfig.hasPath("bookkeeping.informerInterval")).thenReturn(true); - when(hsmConfig.getLong("bookkeeping.informerInterval")).thenReturn(500000L); - when(hsmConfig.hasPath("bookkeeping.maxAmountBlockHeaders")).thenReturn(true); - when(hsmConfig.getInt("bookkeeping.maxAmountBlockHeaders")).thenReturn(1000); - when(hsmConfig.hasPath("bookkeeping.maxChunkSizeToHsm")).thenReturn(true); - when(hsmConfig.getInt("bookkeeping.maxChunkSizeToHsm")).thenReturn(100); - when(hsmConfig.hasPath("bookkeeping.stopBookkeepingScheduler")).thenReturn(true); - when(hsmConfig.getBoolean("bookkeeping.stopBookkeepingScheduler")).thenReturn(true); + private SignerConfig getMSTSignerConfig(String path) { + return SignerConfigBuilder.builder() + .withKeyFileSigner(path) + .build(PowPegNodeKeyId.MST); + } + + private SignerConfig getHSMBTCSignerConfig(HSMVersion version) throws HSMClientException { + when(hsmBookkeepingClient.getVersion()).thenReturn(version.getNumber()); + SignerConfigBuilder configBuilder = SignerConfigBuilder.builder() + .withHsmSigner("m/44'/0'/0'/0/0"); + + if (version.getNumber() >= 2) { + when(hsmBookkeepingClient.getBlockchainParameters()).thenThrow( + new HSMUnsupportedTypeException("PowHSM version: " + version)); + configBuilder = configBuilder.withHsmBookkeepingInfo( + new BigInteger("4405500"), 500000L, 1000, 100, true); + } + + if (version.getNumber() >= 3) { + when(hsmBookkeepingClient.getBlockchainParameters()).thenReturn( + new PowHSMBlockchainParameters( + createHash(1).toHexString(), + new BigInteger("4405500"), + NetworkParameters.ID_UNITTESTNET.toString())); } - return btcSignerConfig; + return configBuilder.build(PowPegNodeKeyId.BTC); } private SignerConfig getHSMRSKSignerConfig() { - SignerConfig rskSignerConfig = mock(SignerConfig.class); - Config hsmConfig = mock(Config.class); - when(rskSignerConfig.getId()).thenReturn("RSK"); - when(rskSignerConfig.getType()).thenReturn("hsm"); - when(rskSignerConfig.getConfig()).thenReturn(hsmConfig); - when(hsmConfig.getString("host")).thenReturn("127.0.0.1"); - when(hsmConfig.getInt("port")).thenReturn(9999); - when(hsmConfig.getString("keyId")).thenReturn("m/44'/137'/0'/0/0"); - return rskSignerConfig; + return SignerConfigBuilder.builder() + .withHsmSigner("m/44'/137'/0'/0/0") + .build(PowPegNodeKeyId.RSK); } private SignerConfig getHSMMSTSignerConfig() { - Config hsmConfig = mock(Config.class); - SignerConfig mstSignerConfig = mock(SignerConfig.class); - when(mstSignerConfig.getId()).thenReturn("MST"); - when(mstSignerConfig.getType()).thenReturn("hsm"); - when(mstSignerConfig.getConfig()).thenReturn(hsmConfig); - when(hsmConfig.getString("host")).thenReturn("127.0.0.1"); - when(hsmConfig.getInt("port")).thenReturn(9999); - when(hsmConfig.getString("keyId")).thenReturn("m/44'/137'/1'/0/0"); - return mstSignerConfig; + return SignerConfigBuilder.builder() + .withHsmSigner("m/44'/137'/1'/0/0") + .build(PowPegNodeKeyId.MST); } } diff --git a/src/test/java/co/rsk/federate/FedNodeSystemPropertiesTest.java b/src/test/java/co/rsk/federate/FedNodeSystemPropertiesTest.java deleted file mode 100644 index 4124fb69..00000000 --- a/src/test/java/co/rsk/federate/FedNodeSystemPropertiesTest.java +++ /dev/null @@ -1,273 +0,0 @@ -package co.rsk.federate; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.time.Duration; -import co.rsk.config.ConfigLoader; -import co.rsk.federate.config.FedNodeSystemProperties; -import com.typesafe.config.Config; -import com.typesafe.config.ConfigObject; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -class FedNodeSystemPropertiesTest { - - private ConfigLoader configLoader; - private Config config; - private ConfigObject configObject; - - @BeforeEach - void setUp() { - configLoader = mock(ConfigLoader.class); - config = mock(Config.class); - configObject = mock(ConfigObject.class); - } - - @Test - void updateBridgeTimer_disabled_regtest() { - when(configLoader.getConfig()).thenReturn(config); - when(config.hasPath("federator.updateBridgeTimerEnabled")).thenReturn(true); - when(config.getString("blockchain.config.name")).thenReturn("regtest"); - when(config.getBoolean("federator.updateBridgeTimerEnabled")).thenReturn(false); - when(config.root()).thenReturn(configObject); - - FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); - - //updateBridgeTimer can only be disabled on regtest - assertFalse(fedNodeSystemProperties.isUpdateBridgeTimerEnabled()); - } - - @Test - void updateBridgeTimer_has_path_and_true_value_regtest() { - when(configLoader.getConfig()).thenReturn(config); - when(config.hasPath("federator.updateBridgeTimerEnabled")).thenReturn(true); - when(config.getString("blockchain.config.name")).thenReturn("regtest"); - when(config.getBoolean("federator.updateBridgeTimerEnabled")).thenReturn(true); - when(config.root()).thenReturn(configObject); - - FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); - - assertTrue(fedNodeSystemProperties.isUpdateBridgeTimerEnabled()); - } - - @Test - void updateBridgeTimer_enabled_regtest() { - when(configLoader.getConfig()).thenReturn(config); - when(config.hasPath("federator.updateBridgeTimerEnabled")).thenReturn(false); - when(config.getString("blockchain.config.name")).thenReturn("regtest"); - when(config.root()).thenReturn(configObject); - - FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); - - assertTrue(fedNodeSystemProperties.isUpdateBridgeTimerEnabled()); - } - - @Test - void updateBridgeTimer_disable_on_tesnet_not_work() { - when(configLoader.getConfig()).thenReturn(config); - when(config.hasPath("federator.updateBridgeTimerEnabled")).thenReturn(true); - when(config.getString("blockchain.config.name")).thenReturn("testnet"); - when(config.getBoolean("federator.updateBridgeTimerEnabled")).thenReturn(false); - when(config.root()).thenReturn(configObject); - - FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); - - //updateBridgeTimer can only be disabled on regtest - assertTrue(fedNodeSystemProperties.isUpdateBridgeTimerEnabled()); - } - - @Test - void updateBridgeTimer_has_path_and_true_value_on_tesnet() { - when(configLoader.getConfig()).thenReturn(config); - when(config.hasPath("federator.updateBridgeTimerEnabled")).thenReturn(true); - when(config.getString("blockchain.config.name")).thenReturn("testnet"); - when(config.getBoolean("federator.updateBridgeTimerEnabled")).thenReturn(true); - when(config.root()).thenReturn(configObject); - - FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); - - //updateBridgeTimer can only be disabled on regtest - assertTrue(fedNodeSystemProperties.isUpdateBridgeTimerEnabled()); - } - - @Test - void updateBridgeTimer_enabled_testnet() { - when(configLoader.getConfig()).thenReturn(config); - when(config.hasPath("federator.updateBridgeTimerEnabled")).thenReturn(false); - when(config.getString("blockchain.config.name")).thenReturn("testnet"); - when(config.root()).thenReturn(configObject); - - FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); - - assertTrue(fedNodeSystemProperties.isUpdateBridgeTimerEnabled()); - } - - @Test - void updateBridgeTimer_disable_on_mainnet_not_work() { - when(configLoader.getConfig()).thenReturn(config); - when(config.hasPath("federator.updateBridgeTimerEnabled")).thenReturn(true); - when(config.getString("blockchain.config.name")).thenReturn("mainnet"); - when(config.getBoolean("federator.updateBridgeTimerEnabled")).thenReturn(false); - when(config.root()).thenReturn(configObject); - - FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); - - //updateBridgeTimer can only be disabled on regtest - assertTrue(fedNodeSystemProperties.isUpdateBridgeTimerEnabled()); - } - - @Test - void updateBridgeTimer_has_path_and_true_value_on_mainnet() { - when(configLoader.getConfig()).thenReturn(config); - when(config.hasPath("federator.updateBridgeTimerEnabled")).thenReturn(true); - when(config.getString("blockchain.config.name")).thenReturn("mainnet"); - when(config.getBoolean("federator.updateBridgeTimerEnabled")).thenReturn(true); - when(config.root()).thenReturn(configObject); - - FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); - - //updateBridgeTimer can only be disabled on regtest - assertTrue(fedNodeSystemProperties.isUpdateBridgeTimerEnabled()); - } - - @Test - void updateBridgeTimer_enabled_mainnet() { - when(configLoader.getConfig()).thenReturn(config); - when(config.hasPath("federator.updateBridgeTimerEnabled")).thenReturn(false); - when(config.getString("blockchain.config.name")).thenReturn("mainnet"); - when(config.root()).thenReturn(configObject); - - FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); - - assertTrue(fedNodeSystemProperties.isUpdateBridgeTimerEnabled()); - } - - @Test - void getPegoutSignedCacheTtl_whenConfigurationPathExists_shouldUseCustomTtl() { - int customTtlInMinutes = 10; - when(configLoader.getConfig()).thenReturn(config); - when(config.hasPath( - "federator.pegoutSignedCacheTtlInMinutes")).thenReturn(true); - when(config.getInt( - "federator.pegoutSignedCacheTtlInMinutes")).thenReturn(customTtlInMinutes); - when(config.root()).thenReturn(configObject); - - FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); - - assertEquals( - Duration.ofMinutes(customTtlInMinutes), - fedNodeSystemProperties.getPegoutSignedCacheTtl()); - } - - @Test - void getPegoutSignedCacheTtl_whenConfigurationPathDoesNotExist_shouldUseDefaultTtl() { - int defaultTtlInMinutes = 30; - when(configLoader.getConfig()).thenReturn(config); - when(config.hasPath( - "federator.pegoutSignedCacheTtlInMinutes")).thenReturn(false); - when(config.root()).thenReturn(configObject); - - FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); - - assertEquals( - 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()); - } - -} diff --git a/src/test/java/co/rsk/federate/btcreleaseclient/BtcReleaseClientTest.java b/src/test/java/co/rsk/federate/btcreleaseclient/BtcReleaseClientTest.java index 3395a4b5..5ecb22ba 100644 --- a/src/test/java/co/rsk/federate/btcreleaseclient/BtcReleaseClientTest.java +++ b/src/test/java/co/rsk/federate/btcreleaseclient/BtcReleaseClientTest.java @@ -1,6 +1,6 @@ package co.rsk.federate.btcreleaseclient; -import static co.rsk.federate.signing.PowPegNodeKeyId.BTC_KEY_ID; +import static co.rsk.federate.signing.PowPegNodeKeyId.BTC; import static co.rsk.federate.signing.utils.TestUtils.createHash; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -38,7 +38,7 @@ import co.rsk.federate.FederatorSupport; import co.rsk.federate.btcreleaseclient.cache.PegoutSignedCache; import co.rsk.federate.btcreleaseclient.cache.PegoutSignedCacheImpl; -import co.rsk.federate.config.FedNodeSystemProperties; +import co.rsk.federate.config.PowpegNodeSystemProperties; import co.rsk.federate.mock.SimpleEthereumImpl; import co.rsk.federate.signing.ECDSASigner; import co.rsk.federate.signing.ECPublicKey; @@ -117,15 +117,15 @@ void setup() { @Test void if_start_not_called_rsk_blockchain_not_listened() { Ethereum ethereum = mock(Ethereum.class); - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - Mockito.doReturn(Constants.regtest()).when(fedNodeSystemProperties).getNetworkConstants(); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + Mockito.doReturn(Constants.regtest()).when(powpegNodeSystemProperties).getNetworkConstants(); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); new BtcReleaseClient( ethereum, mock(FederatorSupport.class), - fedNodeSystemProperties, + powpegNodeSystemProperties, mock(NodeBlockProcessor.class) ); @@ -135,15 +135,15 @@ void if_start_not_called_rsk_blockchain_not_listened() { @Test void when_start_called_rsk_blockchain_is_listened() { Ethereum ethereum = mock(Ethereum.class); - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - Mockito.doReturn(Constants.regtest()).when(fedNodeSystemProperties).getNetworkConstants(); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + Mockito.doReturn(Constants.regtest()).when(powpegNodeSystemProperties).getNetworkConstants(); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); BtcReleaseClient btcReleaseClient = new BtcReleaseClient( ethereum, mock(FederatorSupport.class), - fedNodeSystemProperties, + powpegNodeSystemProperties, mock(NodeBlockProcessor.class) ); @@ -159,15 +159,15 @@ void when_start_called_rsk_blockchain_is_listened() { @Test void if_stop_called_with_just_one_federation_rsk_blockchain_is_still_listened() { Ethereum ethereum = mock(Ethereum.class); - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - Mockito.doReturn(Constants.regtest()).when(fedNodeSystemProperties).getNetworkConstants(); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + Mockito.doReturn(Constants.regtest()).when(powpegNodeSystemProperties).getNetworkConstants(); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); BtcReleaseClient btcReleaseClient = new BtcReleaseClient( ethereum, mock(FederatorSupport.class), - fedNodeSystemProperties, + powpegNodeSystemProperties, mock(NodeBlockProcessor.class) ); @@ -186,15 +186,15 @@ void if_stop_called_with_just_one_federation_rsk_blockchain_is_still_listened() @Test void if_stop_called_with_federations_rsk_blockchain_is_not_listened() { Ethereum ethereum = mock(Ethereum.class); - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - Mockito.doReturn(Constants.regtest()).when(fedNodeSystemProperties).getNetworkConstants(); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + Mockito.doReturn(Constants.regtest()).when(powpegNodeSystemProperties).getNetworkConstants(); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); BtcReleaseClient btcReleaseClient = new BtcReleaseClient( ethereum, mock(FederatorSupport.class), - fedNodeSystemProperties, + powpegNodeSystemProperties, mock(NodeBlockProcessor.class) ); @@ -230,13 +230,13 @@ void processReleases_ok() throws Exception { ECKey.ECDSASignature ethSig = new ECKey.ECDSASignature(BigInteger.ONE, BigInteger.TEN); ECDSASigner signer = mock(ECDSASigner.class); - when(signer.getPublicKey(BTC_KEY_ID.getKeyId())).thenReturn(signerPublicKey); - when(signer.getVersionForKeyId(BTC_KEY_ID.getKeyId())).thenReturn(1); - when(signer.sign(eq(BTC_KEY_ID.getKeyId()), ArgumentMatchers.any())).thenReturn(ethSig); + when(signer.getPublicKey(BTC.getKeyId())).thenReturn(signerPublicKey); + when(signer.getVersionForKeyId(BTC.getKeyId())).thenReturn(1); + when(signer.sign(eq(BTC.getKeyId()), ArgumentMatchers.any())).thenReturn(ethSig); - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - when(fedNodeSystemProperties.getNetworkConstants()).thenReturn(Constants.regtest()); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + when(powpegNodeSystemProperties.getNetworkConstants()).thenReturn(Constants.regtest()); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); SignerMessageBuilder messageBuilder = new SignerMessageBuilderV1(releaseTx); @@ -248,7 +248,7 @@ void processReleases_ok() throws Exception { BtcReleaseClient client = new BtcReleaseClient( mock(Ethereum.class), mock(FederatorSupport.class), - fedNodeSystemProperties, + powpegNodeSystemProperties, mock(NodeBlockProcessor.class) ); @@ -289,7 +289,7 @@ void processReleases_ok() throws Exception { // Assert Mockito.verify(signer, Mockito.times(amountOfInputs)) - .sign(eq(BTC_KEY_ID.getKeyId()), any(SignerMessage.class)); + .sign(eq(BTC.getKeyId()), any(SignerMessage.class)); } @Test @@ -329,14 +329,14 @@ void having_two_pegouts_signs_only_one() throws Exception { ECPublicKey signerPublicKey = new ECPublicKey(fedKey.getPubKey()); ECDSASigner signer = mock(ECDSASigner.class); - doReturn(signerPublicKey).when(signer).getPublicKey(BTC_KEY_ID.getKeyId()); + doReturn(signerPublicKey).when(signer).getPublicKey(BTC.getKeyId()); doReturn(1).when(signer).getVersionForKeyId(ArgumentMatchers.any(KeyId.class)); doReturn(ethSig).when(signer).sign(any(KeyId.class), any(SignerMessage.class)); - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - doReturn(Constants.regtest()).when(fedNodeSystemProperties).getNetworkConstants(); - doReturn(true).when(fedNodeSystemProperties).isPegoutEnabled(); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + doReturn(Constants.regtest()).when(powpegNodeSystemProperties).getNetworkConstants(); + doReturn(true).when(powpegNodeSystemProperties).isPegoutEnabled(); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); SignerMessageBuilderFactory signerMessageBuilderFactory = new SignerMessageBuilderFactory( @@ -377,7 +377,7 @@ void having_two_pegouts_signs_only_one() throws Exception { BtcReleaseClient btcReleaseClient = new BtcReleaseClient( ethereum, federatorSupport, - fedNodeSystemProperties, + powpegNodeSystemProperties, mock(NodeBlockProcessor.class) ); @@ -426,14 +426,14 @@ void onBestBlock_whenPegoutTxIsCached_shouldNotSignSamePegoutTxAgain() throws Ex ECPublicKey signerPublicKey = new ECPublicKey(fedKey.getPubKey()); ECDSASigner signer = mock(ECDSASigner.class); - doReturn(signerPublicKey).when(signer).getPublicKey(BTC_KEY_ID.getKeyId()); + doReturn(signerPublicKey).when(signer).getPublicKey(BTC.getKeyId()); doReturn(1).when(signer).getVersionForKeyId(ArgumentMatchers.any(KeyId.class)); doReturn(ecKey.doSign(new byte[]{})).when(signer).sign(any(KeyId.class), any(SignerMessage.class)); - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - doReturn(Constants.regtest()).when(fedNodeSystemProperties).getNetworkConstants(); - doReturn(true).when(fedNodeSystemProperties).isPegoutEnabled(); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + doReturn(Constants.regtest()).when(powpegNodeSystemProperties).getNetworkConstants(); + doReturn(true).when(powpegNodeSystemProperties).isPegoutEnabled(); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); SignerMessageBuilderFactory signerMessageBuilderFactory = new SignerMessageBuilderFactory( @@ -465,7 +465,7 @@ void onBestBlock_whenPegoutTxIsCached_shouldNotSignSamePegoutTxAgain() throws Ex BtcReleaseClient btcReleaseClient = new BtcReleaseClient( ethereum, federatorSupport, - fedNodeSystemProperties, + powpegNodeSystemProperties, mock(NodeBlockProcessor.class) ); @@ -529,14 +529,14 @@ void onBestBlock_whenPegoutTxIsCachedWithInvalidTimestamp_shouldSignSamePegoutTx ECPublicKey signerPublicKey = new ECPublicKey(fedKey.getPubKey()); ECDSASigner signer = mock(ECDSASigner.class); - doReturn(signerPublicKey).when(signer).getPublicKey(BTC_KEY_ID.getKeyId()); + doReturn(signerPublicKey).when(signer).getPublicKey(BTC.getKeyId()); doReturn(1).when(signer).getVersionForKeyId(ArgumentMatchers.any(KeyId.class)); doReturn(ecKey.doSign(new byte[]{})).when(signer).sign(any(KeyId.class), any(SignerMessage.class)); - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - doReturn(Constants.regtest()).when(fedNodeSystemProperties).getNetworkConstants(); - doReturn(true).when(fedNodeSystemProperties).isPegoutEnabled(); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + doReturn(Constants.regtest()).when(powpegNodeSystemProperties).getNetworkConstants(); + doReturn(true).when(powpegNodeSystemProperties).isPegoutEnabled(); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); SignerMessageBuilderFactory signerMessageBuilderFactory = new SignerMessageBuilderFactory( @@ -568,7 +568,7 @@ void onBestBlock_whenPegoutTxIsCachedWithInvalidTimestamp_shouldSignSamePegoutTx BtcReleaseClient btcReleaseClient = new BtcReleaseClient( ethereum, federatorSupport, - fedNodeSystemProperties, + powpegNodeSystemProperties, mock(NodeBlockProcessor.class) ); @@ -629,10 +629,10 @@ void onBestBlock_return_when_node_is_syncing() throws BtcReleaseClientException FederatorSupport federatorSupport = mock(FederatorSupport.class); - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - doReturn(Constants.regtest()).when(fedNodeSystemProperties).getNetworkConstants(); - doReturn(true).when(fedNodeSystemProperties).isPegoutEnabled(); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + doReturn(Constants.regtest()).when(powpegNodeSystemProperties).getNetworkConstants(); + doReturn(true).when(powpegNodeSystemProperties).isPegoutEnabled(); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); NodeBlockProcessor nodeBlockProcessor = mock(NodeBlockProcessor.class); @@ -641,7 +641,7 @@ void onBestBlock_return_when_node_is_syncing() throws BtcReleaseClientException BtcReleaseClient btcReleaseClient = new BtcReleaseClient( ethereum, federatorSupport, - fedNodeSystemProperties, + powpegNodeSystemProperties, nodeBlockProcessor ); btcReleaseClient.setup( @@ -677,10 +677,10 @@ void onBestBlock_return_when_pegout_is_disabled() throws BtcReleaseClientExcepti FederatorSupport federatorSupport = mock(FederatorSupport.class); - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - doReturn(Constants.regtest()).when(fedNodeSystemProperties).getNetworkConstants(); - doReturn(false).when(fedNodeSystemProperties).isPegoutEnabled(); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + doReturn(Constants.regtest()).when(powpegNodeSystemProperties).getNetworkConstants(); + doReturn(false).when(powpegNodeSystemProperties).isPegoutEnabled(); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); NodeBlockProcessor nodeBlockProcessor = mock(NodeBlockProcessor.class); @@ -689,7 +689,7 @@ void onBestBlock_return_when_pegout_is_disabled() throws BtcReleaseClientExcepti BtcReleaseClient btcReleaseClient = new BtcReleaseClient( ethereum, federatorSupport, - fedNodeSystemProperties, + powpegNodeSystemProperties, nodeBlockProcessor ); btcReleaseClient.setup( @@ -725,10 +725,10 @@ void onBlock_return_when_node_is_syncing() { FederatorSupport federatorSupport = mock(FederatorSupport.class); - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - doReturn(Constants.regtest()).when(fedNodeSystemProperties).getNetworkConstants(); - doReturn(true).when(fedNodeSystemProperties).isPegoutEnabled(); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + doReturn(Constants.regtest()).when(powpegNodeSystemProperties).getNetworkConstants(); + doReturn(true).when(powpegNodeSystemProperties).isPegoutEnabled(); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); NodeBlockProcessor nodeBlockProcessor = mock(NodeBlockProcessor.class); @@ -737,7 +737,7 @@ void onBlock_return_when_node_is_syncing() { BtcReleaseClient btcReleaseClient = new BtcReleaseClient( ethereum, federatorSupport, - fedNodeSystemProperties, + powpegNodeSystemProperties, nodeBlockProcessor ); btcReleaseClient.start(federation); @@ -769,10 +769,10 @@ void onBlock_return_when_pegout_is_disabled() { FederatorSupport federatorSupport = mock(FederatorSupport.class); - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - doReturn(Constants.regtest()).when(fedNodeSystemProperties).getNetworkConstants(); - doReturn(false).when(fedNodeSystemProperties).isPegoutEnabled(); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + doReturn(Constants.regtest()).when(powpegNodeSystemProperties).getNetworkConstants(); + doReturn(false).when(powpegNodeSystemProperties).isPegoutEnabled(); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); NodeBlockProcessor nodeBlockProcessor = mock(NodeBlockProcessor.class); @@ -781,7 +781,7 @@ void onBlock_return_when_pegout_is_disabled() { BtcReleaseClient btcReleaseClient = new BtcReleaseClient( ethereum, federatorSupport, - fedNodeSystemProperties, + powpegNodeSystemProperties, nodeBlockProcessor ); btcReleaseClient.start(federation); @@ -880,9 +880,9 @@ void validateTxCanBeSigned_federatorAlreadySigned() throws Exception { inputScript = ScriptBuilder.updateScriptWithSignature(inputScript, txSigEncoded, sigIndex, 1, 1); releaseInput.setScriptSig(inputScript); - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - when(fedNodeSystemProperties.getNetworkConstants()).thenReturn(Constants.regtest()); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + when(powpegNodeSystemProperties.getNetworkConstants()).thenReturn(Constants.regtest()); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); ECPublicKey signerPublicKey = new ECPublicKey(federator1PrivKey.getPubKey()); @@ -892,7 +892,7 @@ void validateTxCanBeSigned_federatorAlreadySigned() throws Exception { BtcReleaseClient client = new BtcReleaseClient( mock(Ethereum.class), mock(FederatorSupport.class), - fedNodeSystemProperties, + powpegNodeSystemProperties, mock(NodeBlockProcessor.class) ); client.setup( @@ -920,9 +920,9 @@ void validateTxCanBeSigned_federationCantSign() throws Exception { TransactionInput releaseInput = TestUtils.createTransactionInput(params, releaseTx, federation); releaseTx.addInput(releaseInput); - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - when(fedNodeSystemProperties.getNetworkConstants()).thenReturn(Constants.regtest()); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + when(powpegNodeSystemProperties.getNetworkConstants()).thenReturn(Constants.regtest()); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); BtcECKey fed1Key = federation.getBtcPublicKeys().get(0); @@ -933,7 +933,7 @@ void validateTxCanBeSigned_federationCantSign() throws Exception { BtcReleaseClient client = new BtcReleaseClient( mock(Ethereum.class), mock(FederatorSupport.class), - fedNodeSystemProperties, + powpegNodeSystemProperties, mock(NodeBlockProcessor.class) ); client.setup( @@ -983,15 +983,15 @@ void removeSignaturesFromTransaction() { inputScript = ScriptBuilder.updateScriptWithSignature(inputScript, txSigEncoded, sigIndex, 1, 1); releaseInput.setScriptSig(inputScript); - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - when(fedNodeSystemProperties.getNetworkConstants()).thenReturn(Constants.regtest()); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + when(powpegNodeSystemProperties.getNetworkConstants()).thenReturn(Constants.regtest()); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); BtcReleaseClient client = new BtcReleaseClient( mock(Ethereum.class), mock(FederatorSupport.class), - fedNodeSystemProperties, + powpegNodeSystemProperties, mock(NodeBlockProcessor.class) ); @@ -1061,9 +1061,9 @@ private void test_validateTxCanBeSigned( BtcTransaction releaseTx, ECPublicKey signerPublicKey ) throws Exception { - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - when(fedNodeSystemProperties.getNetworkConstants()).thenReturn(Constants.regtest()); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + when(powpegNodeSystemProperties.getNetworkConstants()).thenReturn(Constants.regtest()); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); ECDSASigner signer = mock(ECDSASigner.class); @@ -1072,7 +1072,7 @@ private void test_validateTxCanBeSigned( BtcReleaseClient client = new BtcReleaseClient( mock(Ethereum.class), mock(FederatorSupport.class), - fedNodeSystemProperties, + powpegNodeSystemProperties, mock(NodeBlockProcessor.class) ); client.setup( @@ -1094,15 +1094,15 @@ private void test_extractStandardRedeemScript( Script expectedRedeemScript, Script redeemScriptToExtract) { - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - when(fedNodeSystemProperties.getNetworkConstants()).thenReturn(Constants.regtest()); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + when(powpegNodeSystemProperties.getNetworkConstants()).thenReturn(Constants.regtest()); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); BtcReleaseClient client = new BtcReleaseClient( mock(Ethereum.class), mock(FederatorSupport.class), - fedNodeSystemProperties, + powpegNodeSystemProperties, mock(NodeBlockProcessor.class) ); @@ -1166,10 +1166,10 @@ private void testUsageOfStorageWhenSigning(boolean shouldHaveDataInFile) throws BtcReleaseClientException, SignerException, HSMReleaseCreationInformationException, ReleaseRequirementsEnforcerException, HSMUnsupportedVersionException, SignerMessageBuilderException { - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - when(fedNodeSystemProperties.getNetworkConstants()).thenReturn(Constants.regtest()); - when(fedNodeSystemProperties.isPegoutEnabled()).thenReturn(true); - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + when(powpegNodeSystemProperties.getNetworkConstants()).thenReturn(Constants.regtest()); + when(powpegNodeSystemProperties.isPegoutEnabled()).thenReturn(true); + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); NodeBlockProcessor nodeBlockProcessor = mock(NodeBlockProcessor.class); @@ -1234,7 +1234,7 @@ private void testUsageOfStorageWhenSigning(boolean shouldHaveDataInFile) BtcReleaseClient btcReleaseClient = new BtcReleaseClient( ethereumImpl, federatorSupport, - fedNodeSystemProperties, + powpegNodeSystemProperties, nodeBlockProcessor ); @@ -1273,16 +1273,16 @@ private void testUsageOfStorageWhenSigning(boolean shouldHaveDataInFile) } private BtcReleaseClient createBtcClient() { - FedNodeSystemProperties fedNodeSystemProperties = mock(FedNodeSystemProperties.class); - when(fedNodeSystemProperties.getNetworkConstants()).thenReturn(Constants.regtest()); - when(fedNodeSystemProperties.isPegoutEnabled()).thenReturn(true); // Enabled by default - when(fedNodeSystemProperties.getPegoutSignedCacheTtl()) + PowpegNodeSystemProperties powpegNodeSystemProperties = mock(PowpegNodeSystemProperties.class); + when(powpegNodeSystemProperties.getNetworkConstants()).thenReturn(Constants.regtest()); + when(powpegNodeSystemProperties.isPegoutEnabled()).thenReturn(true); // Enabled by default + when(powpegNodeSystemProperties.getPegoutSignedCacheTtl()) .thenReturn(PEGOUT_SIGNED_CACHE_TTL); return new BtcReleaseClient( mock(Ethereum.class), mock(FederatorSupport.class), - fedNodeSystemProperties, + powpegNodeSystemProperties, mock(NodeBlockProcessor.class) ); } diff --git a/src/test/java/co/rsk/federate/config/FedNodeSystemPropertiesTest.java b/src/test/java/co/rsk/federate/config/FedNodeSystemPropertiesTest.java deleted file mode 100644 index 08f711e2..00000000 --- a/src/test/java/co/rsk/federate/config/FedNodeSystemPropertiesTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package co.rsk.federate.config; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import co.rsk.config.ConfigLoader; -import com.typesafe.config.Config; -import com.typesafe.config.ConfigObject; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -class FedNodeSystemPropertiesTest { - - private ConfigLoader configLoader; - private Config config; - private ConfigObject configObject; - - @BeforeEach - void setUp() { - configLoader = mock(ConfigLoader.class); - config = mock(Config.class); - configObject = mock(ConfigObject.class); - } - - @Test - void amountOfHeadersToSend_default_value() { - when(configLoader.getConfig()).thenReturn(config); - when(config.hasPath("federator.amountOfHeadersToSend")).thenReturn(false); - when(config.root()).thenReturn(configObject); - - FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); - - assertEquals(25, fedNodeSystemProperties.getAmountOfHeadersToSend()); - } - - @Test - void amountOfHeadersToSend_config_value() { - when(configLoader.getConfig()).thenReturn(config); - when(config.hasPath("federator.amountOfHeadersToSend")).thenReturn(true); - when(config.getInt("federator.amountOfHeadersToSend")).thenReturn(10); - when(config.root()).thenReturn(configObject); - - FedNodeSystemProperties fedNodeSystemProperties = new FedNodeSystemProperties(configLoader); - - assertEquals(10, fedNodeSystemProperties.getAmountOfHeadersToSend()); - } -} diff --git a/src/test/java/co/rsk/federate/config/PowHSMBookkeepingConfigTest.java b/src/test/java/co/rsk/federate/config/PowHSMBookkeepingConfigTest.java deleted file mode 100644 index efde4cf6..00000000 --- a/src/test/java/co/rsk/federate/config/PowHSMBookkeepingConfigTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package co.rsk.federate.config; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import co.rsk.bitcoinj.core.NetworkParameters; -import com.typesafe.config.Config; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -/** - * Test class for PowHSMBookkeepingConfig. - * - * @author kelvin.isievwore - */ - -class PowHSMBookkeepingConfigTest { - - private PowHSMBookkeepingConfig powHsmBookkeepingConfig; - private SignerConfig signerConfigMock; - private Config configMock; - - @BeforeEach - void setup() { - signerConfigMock = mock(SignerConfig.class); - configMock = mock(Config.class); - } - - @Test - void testGetDifficultyCapForMainnet() { - when(signerConfigMock.getConfig()).thenReturn(configMock); - powHsmBookkeepingConfig = new PowHSMBookkeepingConfig(signerConfigMock, NetworkParameters.ID_MAINNET); - assertEquals(PowHSMBookkeepingConfig.DIFFICULTY_CAP_MAINNET, powHsmBookkeepingConfig.getDifficultyCap()); - } - - @Test - void testGetDifficultyCapForTestnet() { - when(signerConfigMock.getConfig()).thenReturn(configMock); - powHsmBookkeepingConfig = new PowHSMBookkeepingConfig(signerConfigMock, NetworkParameters.ID_TESTNET); - assertEquals(PowHSMBookkeepingConfig.DIFFICULTY_CAP_TESTNET, powHsmBookkeepingConfig.getDifficultyCap()); - } - - @Test - void testGetDifficultyCapForRegtest() { - when(signerConfigMock.getConfig()).thenReturn(configMock); - powHsmBookkeepingConfig = new PowHSMBookkeepingConfig(signerConfigMock, NetworkParameters.ID_REGTEST); - assertEquals(PowHSMBookkeepingConfig.DIFFICULTY_CAP_REGTEST, powHsmBookkeepingConfig.getDifficultyCap()); - } - - @Test - void testGetDifficultyCapForInvalidNetwork() { - when(signerConfigMock.getConfig()).thenReturn(configMock); - assertThrows(IllegalArgumentException.class, () -> new PowHSMBookkeepingConfig(signerConfigMock, NetworkParameters.ID_UNITTESTNET)); - } -} diff --git a/src/test/java/co/rsk/federate/config/PowpegNodeSystemPropertiesTest.java b/src/test/java/co/rsk/federate/config/PowpegNodeSystemPropertiesTest.java new file mode 100644 index 00000000..be880c4d --- /dev/null +++ b/src/test/java/co/rsk/federate/config/PowpegNodeSystemPropertiesTest.java @@ -0,0 +1,364 @@ +package co.rsk.federate.config; + +import static co.rsk.federate.config.PowpegNodeConfigParameter.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import co.rsk.federate.signing.config.SignerType; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Stream; +import co.rsk.config.ConfigLoader; +import co.rsk.federate.signing.config.SignerConfig; +import com.typesafe.config.Config; +import com.typesafe.config.ConfigObject; +import org.bitcoinj.core.NetworkParameters; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class PowpegNodeSystemPropertiesTest { + + private final ConfigLoader configLoader = mock(ConfigLoader.class); + private final Config config = mock(Config.class); + private final ConfigObject configObject = mock(ConfigObject.class); + + private PowpegNodeSystemProperties powpegNodeSystemProperties; + + @BeforeEach + void setUp() { + when(config.root()).thenReturn(configObject); + when(configLoader.getConfig()).thenReturn(config); + powpegNodeSystemProperties = new PowpegNodeSystemProperties(configLoader); + } + + @Test + void isUpdateBridgeTimerEnabled_whenRegtestAndCustomConfigDisabledValue_shouldReturnCustomConfigDisabledValue() { + when(config.getString("blockchain.config.name")).thenReturn("regtest"); + when(config.hasPath(UPDATE_BRIDGE_TIMER_ENABLED.getPath())).thenReturn(true); + when(config.getBoolean(UPDATE_BRIDGE_TIMER_ENABLED.getPath())).thenReturn(false); + + // updateBridgeTimer can only be disabled on regtest + assertFalse(powpegNodeSystemProperties.isUpdateBridgeTimerEnabled()); + } + + @ParameterizedTest + @MethodSource("updateBridgeTimerEnabledProvider") + void isUpdateBridgeTimerEnabled_whenGivenNetworkConfigNameAndCustomConfigVariations_shouldReturnEnabled( + String networkConfigName, boolean hasPath, boolean customValue) { + when(config.getString("blockchain.config.name")).thenReturn(networkConfigName); + when(config.hasPath(UPDATE_BRIDGE_TIMER_ENABLED.getPath())).thenReturn(hasPath); + if (hasPath) { + when(config.getBoolean(UPDATE_BRIDGE_TIMER_ENABLED.getPath())).thenReturn(customValue); + } + + assertTrue(powpegNodeSystemProperties.isUpdateBridgeTimerEnabled()); + } + + private static Stream updateBridgeTimerEnabledProvider() { + return Stream.of( + Arguments.of("regtest", true, true), + Arguments.of("testnet", true, false), + Arguments.of("testnet", true, true), + Arguments.of("mainnet", true, false), + Arguments.of("mainnet", true, true), + Arguments.of("mainnet", false, false), + Arguments.of("regtest", false, false), + Arguments.of("testnet", false, false)); + } + + @Test + void getPegoutSignedCacheTtl_whenCustomConfigIsAvailable_shouldUseCustomConfig() { + int customValue = 10; + when(config.hasPath(PEGOUT_CACHE_TTL.getPath())).thenReturn(true); + when(config.getInt(PEGOUT_CACHE_TTL.getPath())).thenReturn(customValue); + + assertEquals( + Duration.ofMinutes(customValue), + powpegNodeSystemProperties.getPegoutSignedCacheTtl()); + } + + @Test + void getPegoutSignedCacheTtl_whenCustomConfigIsNotAvailable_shouldUseDefaultConfig() { + when(config.hasPath(PEGOUT_CACHE_TTL.getPath())).thenReturn(false); + + int defaultValue = PEGOUT_CACHE_TTL.getDefaultValue(Integer::parseInt); + assertEquals( + Duration.ofMinutes(defaultValue), + powpegNodeSystemProperties.getPegoutSignedCacheTtl()); + } + + @Test + void getAmountOfHeadersToSend_whenCustomConfigAvailable_shouldReturnCustomConfig() { + int customValue = 10; + when(config.hasPath(AMOUNT_HEADERS.getPath())).thenReturn(true); + when(config.getInt(AMOUNT_HEADERS.getPath())).thenReturn(customValue); + + assertEquals(customValue, powpegNodeSystemProperties.getAmountOfHeadersToSend()); + } + + @Test + void getAmountOfHeadersToSend_whenCustomConfigNotAvailable_shouldReturnDefaultConfig() { + when(config.hasPath(AMOUNT_HEADERS.getPath())).thenReturn(false); + + int defaultValue = AMOUNT_HEADERS.getDefaultValue(Integer::parseInt); + assertEquals(defaultValue, powpegNodeSystemProperties.getAmountOfHeadersToSend()); + } + + @Test + void isFederatorEnabled_whenCustomConfigAvailable_shouldReturnCustomConfig() { + boolean customValue = !FEDERATOR_ENABLED.getDefaultValue(Boolean::parseBoolean); + when(config.hasPath(FEDERATOR_ENABLED.getPath())).thenReturn(true); + when(config.getBoolean(FEDERATOR_ENABLED.getPath())).thenReturn(customValue); + + assertFalse(powpegNodeSystemProperties.isFederatorEnabled()); + } + + @Test + void isFederatorEnabled_whenCustomConfigNotAvailable_shouldReturnDefaultConfig() { + when(config.hasPath(FEDERATOR_ENABLED.getPath())).thenReturn(false); + + assertTrue(powpegNodeSystemProperties.isFederatorEnabled()); + } + + @Test + void isPegoutEnabled_whenCustomConfigAvailable_shouldReturnCustomConfig() { + boolean customValue = !PEGOUT_ENABLED.getDefaultValue(Boolean::parseBoolean); + when(config.hasPath(PEGOUT_ENABLED.getPath())).thenReturn(true); + when(config.getBoolean(PEGOUT_ENABLED.getPath())).thenReturn(customValue); + + assertFalse(powpegNodeSystemProperties.isPegoutEnabled()); + } + + @Test + void isPegoutEnabled_whenCustomConfigNotAvailable_shouldReturnDefaultConfig() { + when(config.hasPath(PEGOUT_ENABLED.getPath())).thenReturn(false); + + assertTrue(powpegNodeSystemProperties.isPegoutEnabled()); + } + + @Test + void shouldUpdateBridgeBtcBlockchain_whenCustomConfigAvailable_shouldReturnCustomConfig() { + boolean customValue = !UPDATE_BRIDGE_BTC_BLOCKCHAIN.getDefaultValue(Boolean::parseBoolean); + when(config.hasPath(UPDATE_BRIDGE_BTC_BLOCKCHAIN.getPath())).thenReturn(true); + when(config.getBoolean(UPDATE_BRIDGE_BTC_BLOCKCHAIN.getPath())).thenReturn(customValue); + + assertFalse(powpegNodeSystemProperties.shouldUpdateBridgeBtcBlockchain()); + } + + @Test + void shouldUpdateBridgeBtcBlockchain_whenCustomConfigNotAvailabe_shouldReturnDefaultConfig() { + when(config.hasPath(UPDATE_BRIDGE_BTC_BLOCKCHAIN.getPath())).thenReturn(false); + + assertTrue(powpegNodeSystemProperties.shouldUpdateBridgeBtcBlockchain()); + } + + @Test + void shouldUpdateBridgeBtcCoinbaseTransactions_whenCustomConfigAvailable_shouldReturnCustomConfig() { + boolean customValue = !UPDATE_BRIDGE_BTC_COINBASE_TRANSACTIONS.getDefaultValue(Boolean::parseBoolean); + when(config.hasPath(UPDATE_BRIDGE_BTC_COINBASE_TRANSACTIONS.getPath())).thenReturn(true); + when(config.getBoolean(UPDATE_BRIDGE_BTC_COINBASE_TRANSACTIONS.getPath())).thenReturn(customValue); + + assertFalse(powpegNodeSystemProperties.shouldUpdateBridgeBtcCoinbaseTransactions()); + } + + @Test + void shouldUpdateBridgeBtcCoinbaseTransactions_whenCustomConfigNotAvailable_shouldReturnDefaultConfig() { + when(config.hasPath(UPDATE_BRIDGE_BTC_BLOCKCHAIN.getPath())).thenReturn(false); + + assertTrue(powpegNodeSystemProperties.shouldUpdateBridgeBtcCoinbaseTransactions()); + } + + @Test + void shouldUpdateBridgeBtcTransactions_whenCustomConfigAvailable_shouldReturnCustomConfig() { + boolean customValue = !UPDATE_BRIDGE_BTC_TRANSACTIONS.getDefaultValue(Boolean::parseBoolean); + when(config.hasPath(UPDATE_BRIDGE_BTC_TRANSACTIONS.getPath())).thenReturn(true); + when(config.getBoolean(UPDATE_BRIDGE_BTC_TRANSACTIONS.getPath())).thenReturn(customValue); + + assertFalse(powpegNodeSystemProperties.shouldUpdateBridgeBtcTransactions()); + } + + @Test + void shouldUpdateBridgeBtcTransactions_whenCustomConfigNotAvailable_shouldReturnDefaultConfig() { + when(config.hasPath(UPDATE_BRIDGE_BTC_BLOCKCHAIN.getPath())).thenReturn(false); + + assertTrue(powpegNodeSystemProperties.shouldUpdateBridgeBtcTransactions()); + } + + @Test + void shouldUpdateCollections_whenCustomConfigAvailable_shouldReturnCustomConfig() { + boolean customValue = !UPDATE_COLLECTIONS.getDefaultValue(Boolean::parseBoolean); + when(config.hasPath(UPDATE_COLLECTIONS.getPath())).thenReturn(true); + when(config.getBoolean(UPDATE_COLLECTIONS.getPath())).thenReturn(customValue); + + assertFalse(powpegNodeSystemProperties.shouldUpdateCollections()); + } + + @Test + void shouldUpdateCollections_whenCustomConfigNotAvailable_shouldReturnDefaultConfig() { + when(config.hasPath(UPDATE_COLLECTIONS.getPath())).thenReturn(false); + + assertTrue(powpegNodeSystemProperties.shouldUpdateCollections()); + } + + @Test + void getBtcReleaseClientInitializationMaxDepth_whenCustomConfigAvailable_shouldReturnCustomConfig() { + int customValue = 10; + when(config.hasPath(BTC_INIT_MAX_DEPTH.getPath())).thenReturn(true); + when(config.getInt(BTC_INIT_MAX_DEPTH.getPath())).thenReturn(customValue); + + assertEquals(customValue, powpegNodeSystemProperties.getBtcReleaseClientInitializationMaxDepth()); + } + + @Test + void getBtcReleaseClientInitializationMaxDepth_whenCustomConfigNotAvailable_shouldReturnDefaultConfig() { + when(config.hasPath(BTC_INIT_MAX_DEPTH.getPath())).thenReturn(false); + + int defaultValue = BTC_INIT_MAX_DEPTH.getDefaultValue(Integer::parseInt); + assertEquals(defaultValue, powpegNodeSystemProperties.getBtcReleaseClientInitializationMaxDepth()); + } + + @Test + void federatorGasPrice_whenCustomConfigAvailable_shouldReturnCustomConfig() { + long customValue = 10; + when(config.hasPath(GAS_PRICE.getPath())).thenReturn(true); + when(config.getLong(GAS_PRICE.getPath())).thenReturn(customValue); + + assertEquals(customValue, powpegNodeSystemProperties.federatorGasPrice()); + } + + @Test + void federatorGasPrice_whenCustomConfigNotAvailable_shouldReturnDefaultConfig() { + when(config.hasPath(GAS_PRICE.getPath())).thenReturn(true); + + long defaultValue = GAS_PRICE.getDefaultValue(Long::parseLong); + assertEquals(defaultValue, powpegNodeSystemProperties.federatorGasPrice()); + } + + @Test + void bitcoinPeerAddresses_whenCustomConfigAvailable_shouldReturnCustomConfig() { + List customValue = Arrays.asList("address1", "address2"); + when(config.hasPath(BTC_PEER_ADDRESSES.getPath())).thenReturn(true); + when(config.getStringList(BTC_PEER_ADDRESSES.getPath())).thenReturn(customValue); + + assertEquals(customValue, powpegNodeSystemProperties.bitcoinPeerAddresses()); + } + + @Test + void bitcoinPeerAddresses_whenCustomConfigNotAvailable_shouldReturnDefaultConfig() { + when(config.hasPath(BTC_PEER_ADDRESSES.getPath())).thenReturn(false); + + List defaultValue = new ArrayList<>(); + assertEquals(defaultValue, powpegNodeSystemProperties.bitcoinPeerAddresses()); + } + + @Test + void gasPriceProviderConfig_whenCustomConfigAvailable_shouldReturnConfig() { + ConfigObject mockConfigObject = mock(ConfigObject.class); + Config mockConfig = mock(Config.class); + + when(config.hasPath(GAS_PRICE_PROVIDER.getPath())).thenReturn(true); + when(config.getObject(GAS_PRICE_PROVIDER.getPath())).thenReturn(mockConfigObject); + when(mockConfigObject.toConfig()).thenReturn(mockConfig); + + GasPriceProviderConfig result = powpegNodeSystemProperties.gasPriceProviderConfig(); + + assertNotNull(result); + } + + @Test + void gasPriceProviderConfig_whenCustomConfigNotAvailable_shouldReturnNull() { + when(config.hasPath(GAS_PRICE_PROVIDER.getPath())).thenReturn(false); + + GasPriceProviderConfig result = powpegNodeSystemProperties.gasPriceProviderConfig(); + + assertNull(result); + } + + @Test + void signerConfig_whenSignerConfigExists_shouldReturnSignerConfig() { + String existingKey = NetworkParameters.ID_MAINNET; + ConfigObject mockConfigSignersObject = mock(ConfigObject.class); + ConfigObject mockConfigSignerObject = mock(ConfigObject.class); + Config mockSignersConfig = mock(Config.class); + Config mockSignerConfig = mock(Config.class); + + // mock behavior where signersConfigTree() returns valid configuration + when(config.hasPath(SIGNERS.getPath())).thenReturn(true); + when(config.getObject(SIGNERS.getPath())).thenReturn(mockConfigSignersObject); + when(mockConfigSignersObject.toConfig()).thenReturn(mockSignersConfig); + when(mockSignersConfig.hasPath(existingKey)).thenReturn(true); + + // mock behavior where the requested key exists with a "type" attribute + when(mockSignersConfig.getObject(existingKey)).thenReturn(mockConfigSignerObject); + when(mockConfigSignerObject.toConfig()).thenReturn(mockSignerConfig); + when(mockSignerConfig.hasPath("type")).thenReturn(true); + when(mockSignerConfig.getString("type")).thenReturn(SignerType.HSM.getType()); + + SignerConfig result = powpegNodeSystemProperties.signerConfig(existingKey); + + assertNotNull(result); + assertEquals(existingKey, result.getId()); + } + + @Test + void signerConfig_whenSignerConfigDoesNotExist_shouldReturnNull() { + // mock behavior where signersConfigTree() returns null (no valid + // configuration) + when(config.hasPath(SIGNERS.getPath())).thenReturn(false); + + SignerConfig result = powpegNodeSystemProperties.signerConfig("nonExistingKey"); + + assertNull(result); + } + + @Test + void signerConfig_whenSignerConfigTypeNotDefined_shouldReturnNull() { + String keyWithNoType = NetworkParameters.ID_MAINNET; + ConfigObject mockConfigObject = mock(ConfigObject.class); + Config mockSignersConfig = mock(Config.class); + Config mockSignerConfig = mock(Config.class); + + // mock behavior where signersConfigTree() returns valid configuration + when(config.hasPath(SIGNERS.getPath())).thenReturn(true); + when(config.getObject(SIGNERS.getPath())).thenReturn(mockConfigObject); + when(mockConfigObject.toConfig()).thenReturn(mockSignersConfig); + when(mockSignersConfig.hasPath(keyWithNoType)).thenReturn(true); + + // mock behavior where the requested key exists but "type" attribute is + // not defined + when(mockSignersConfig.getObject(keyWithNoType)).thenReturn(mockConfigObject); + when(mockConfigObject.toConfig()).thenReturn(mockSignerConfig); + when(mockSignerConfig.hasPath("type")).thenReturn(false); // Simulating "type" not defined + + SignerConfig result = powpegNodeSystemProperties.signerConfig(keyWithNoType); + + assertNull(result); + } + + @ParameterizedTest + @MethodSource("powpegNodeConfigParameterProvider") + void powpegNodeConfigParameter_whenDefaultIsEmpty_shouldThrowIllegalStateException( + PowpegNodeConfigParameter param) { + Function parser = Function.identity(); + assertThrows(IllegalStateException.class, + () -> param.getDefaultValue(parser)); + } + + private static Stream powpegNodeConfigParameterProvider() { + return Stream.of( + Arguments.of(SIGNERS), + Arguments.of(GAS_PRICE_PROVIDER)); + } +} diff --git a/src/test/java/co/rsk/federate/config/SignerConfigBuilder.java b/src/test/java/co/rsk/federate/config/SignerConfigBuilder.java new file mode 100644 index 00000000..e4ca9961 --- /dev/null +++ b/src/test/java/co/rsk/federate/config/SignerConfigBuilder.java @@ -0,0 +1,60 @@ +package co.rsk.federate.config; + +import static com.typesafe.config.ConfigValueFactory.fromAnyRef; + +import co.rsk.federate.signing.config.SignerType; +import java.math.BigInteger; +import com.typesafe.config.Config; +import com.typesafe.config.ConfigFactory; +import co.rsk.federate.signing.PowPegNodeKeyId; +import co.rsk.federate.signing.config.SignerConfig; + +public class SignerConfigBuilder { + private Config config; + + private SignerConfigBuilder() { + this.config = ConfigFactory.empty(); + } + + public static SignerConfigBuilder builder() { + return new SignerConfigBuilder(); + } + + public SignerConfigBuilder withValue(String path, Object value) { + this.config = this.config.withValue(path, fromAnyRef(value)); + return this; + } + + public SignerConfigBuilder withHsmSigner(String keyId) { + this.config = this.config.withValue("type", fromAnyRef(SignerType.HSM.getType())); + this.config = this.config.withValue("host", fromAnyRef("127.0.0.1")); + this.config = this.config.withValue("port", fromAnyRef(9999)); + this.config = this.config.withValue("keyId", fromAnyRef(keyId)); + this.config = this.config.withValue("socketTimeout", fromAnyRef(20000)); + this.config = this.config.withValue("maxAttempts", fromAnyRef(3)); + this.config = this.config.withValue("intervalBetweenAttempts", fromAnyRef(2000)); + return this; + } + + public SignerConfigBuilder withHsmBookkeepingInfo(BigInteger difficultyTarget, long informerInterval, + int maxAmountBlockHeaders, int maxChunkSize, boolean stopBookkepingScheduler) { + if (difficultyTarget != null) { + this.config = this.config.withValue("bookkeeping.difficultyTarget", fromAnyRef(difficultyTarget.toString())); + } + this.config = this.config.withValue("bookkeeping.informerInterval", fromAnyRef(informerInterval)); + this.config = this.config.withValue("bookkeeping.maxAmountBlockHeaders", fromAnyRef(maxAmountBlockHeaders)); + this.config = this.config.withValue("bookkeeping.maxChunkSizeToHsm", fromAnyRef(maxChunkSize)); + this.config = this.config.withValue("bookkeeping.stopBookkeepingScheduler", fromAnyRef(stopBookkepingScheduler)); + return this; + } + + public SignerConfigBuilder withKeyFileSigner(String path) { + this.config = this.config.withValue("type", fromAnyRef(SignerType.KEYFILE.getType())); + this.config = this.config.withValue("path", fromAnyRef(path)); + return this; + } + + public SignerConfig build(PowPegNodeKeyId keyId) { + return new SignerConfig(keyId.getId(), config); + } +} diff --git a/src/test/java/co/rsk/federate/config/TestSystemProperties.java b/src/test/java/co/rsk/federate/config/TestSystemProperties.java index e8f2fa9f..a468ac0a 100644 --- a/src/test/java/co/rsk/federate/config/TestSystemProperties.java +++ b/src/test/java/co/rsk/federate/config/TestSystemProperties.java @@ -22,7 +22,7 @@ import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; -public class TestSystemProperties extends FedNodeSystemProperties { +public class TestSystemProperties extends PowpegNodeSystemProperties { private static final ConfigLoader TEST_LOADER = new ConfigLoader(CliArgs.empty()) { /** * Cache configurations that don't change so we don't read files multiple times. diff --git a/src/test/java/co/rsk/federate/io/btcreleaseclientstorage/BtcReleaseClientFileStorageInfoTest.java b/src/test/java/co/rsk/federate/io/btcreleaseclientstorage/BtcReleaseClientFileStorageInfoTest.java index bffb2a54..bfb29bce 100644 --- a/src/test/java/co/rsk/federate/io/btcreleaseclientstorage/BtcReleaseClientFileStorageInfoTest.java +++ b/src/test/java/co/rsk/federate/io/btcreleaseclientstorage/BtcReleaseClientFileStorageInfoTest.java @@ -4,7 +4,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import co.rsk.federate.config.FedNodeSystemProperties; +import co.rsk.federate.config.PowpegNodeSystemProperties; import java.io.File; import org.junit.jupiter.api.Test; @@ -12,10 +12,10 @@ class BtcReleaseClientFileStorageInfoTest { @Test void test() { - FedNodeSystemProperties fnsp = mock(FedNodeSystemProperties.class); - when(fnsp.databaseDir()).thenReturn("test"); - BtcReleaseClientFileStorageInfo info = new BtcReleaseClientFileStorageInfo(fnsp); - String directoryPath = fnsp.databaseDir() + File.separator + "peg"; + PowpegNodeSystemProperties config = mock(PowpegNodeSystemProperties.class); + when(config.databaseDir()).thenReturn("test"); + BtcReleaseClientFileStorageInfo info = new BtcReleaseClientFileStorageInfo(config); + String directoryPath = config.databaseDir() + File.separator + "peg"; String filePath = directoryPath + File.separator + "btcReleaseClient.rlp"; assertEquals(directoryPath, info.getPegDirectoryPath()); assertEquals(filePath, info.getFilePath()); diff --git a/src/test/java/co/rsk/federate/signing/ECDSASignerFactoryTest.java b/src/test/java/co/rsk/federate/signing/ECDSASignerFactoryTest.java index b8124472..154df771 100644 --- a/src/test/java/co/rsk/federate/signing/ECDSASignerFactoryTest.java +++ b/src/test/java/co/rsk/federate/signing/ECDSASignerFactoryTest.java @@ -25,9 +25,10 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import co.rsk.federate.config.SignerConfig; +import co.rsk.federate.signing.config.SignerConfig; import co.rsk.federate.rpc.JsonRpcClientProvider; import co.rsk.federate.rpc.SocketBasedJsonRpcClientProvider; +import co.rsk.federate.signing.config.SignerType; import co.rsk.federate.signing.hsm.SignerException; import co.rsk.federate.signing.hsm.client.HSMClientProtocol; import co.rsk.federate.signing.hsm.client.HSMSigningClientProvider; @@ -49,7 +50,7 @@ void createFactory() { @Test void buildFromConfigKeyFile() throws SignerException { - Config configMock = mockConfig("keyFile"); + Config configMock = mockConfig(SignerType.KEYFILE.getType()); when(configMock.getString("path")).thenReturn("a-random-path"); SignerConfig signerConfig = new SignerConfig("a-random-id", configMock); ECDSASigner signer = factory.buildFromConfig(signerConfig); @@ -61,8 +62,10 @@ void buildFromConfigKeyFile() throws SignerException { @Test void buildFromConfigHSM() throws SignerException { - Config configMock = mockConfig("hsm"); + Config configMock = mockConfig(SignerType.HSM.getType()); + when(configMock.hasPath("host")).thenReturn(true); when(configMock.getString("host")).thenReturn("remotehost"); + when(configMock.hasPath("port")).thenReturn(true); when(configMock.getInt("port")).thenReturn(1234); when(configMock.getString("keyId")).thenReturn("a-bip32-path"); when(configMock.hasPath("socketTimeout")).thenReturn(true); @@ -113,13 +116,12 @@ void buildFromConfigHSM() throws SignerException { } @Test - void buildFromConfigUnknown() throws SignerException { + void buildFromConfigUnknown() { Config configMock = mockConfig("a-random-type"); - SignerConfig signerConfig = new SignerConfig("a-random-id", configMock); try { - factory.buildFromConfig(signerConfig); + new SignerConfig("a-random-id", configMock); fail(); - } catch (RuntimeException e) { + } catch (IllegalArgumentException e) { assertEquals("Unsupported signer type: a-random-type", e.getMessage()); } } diff --git a/src/test/java/co/rsk/federate/signing/hsm/advanceblockchain/ConfirmedBlocksProviderTest.java b/src/test/java/co/rsk/federate/signing/hsm/advanceblockchain/ConfirmedBlocksProviderTest.java index 5a97bac6..65fa0545 100644 --- a/src/test/java/co/rsk/federate/signing/hsm/advanceblockchain/ConfirmedBlocksProviderTest.java +++ b/src/test/java/co/rsk/federate/signing/hsm/advanceblockchain/ConfirmedBlocksProviderTest.java @@ -3,10 +3,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static co.rsk.federate.signing.hsm.config.NetworkDifficultyCap.REGTEST; import co.rsk.core.BlockDifficulty; import co.rsk.crypto.Keccak256; -import co.rsk.federate.config.PowHSMBookkeepingConfig; import co.rsk.federate.signing.hsm.HSMVersion; import co.rsk.federate.signing.utils.TestUtils; import java.math.BigInteger; @@ -22,7 +22,7 @@ class ConfirmedBlocksProviderTest { - private final BigInteger difficultyCapRegTest = PowHSMBookkeepingConfig.DIFFICULTY_CAP_REGTEST; + private final BigInteger difficultyCapRegTest = REGTEST.getDifficultyCap(); private final BlockHeaderBuilder blockHeaderBuilder = new BlockHeaderBuilder(mock(ActivationConfig.class)); @Test diff --git a/src/test/java/co/rsk/federate/signing/hsm/advanceblockchain/HsmBookkeepingClientImplTest.java b/src/test/java/co/rsk/federate/signing/hsm/advanceblockchain/HsmBookkeepingClientImplTest.java index db69e3d9..a8a56fc6 100644 --- a/src/test/java/co/rsk/federate/signing/hsm/advanceblockchain/HsmBookkeepingClientImplTest.java +++ b/src/test/java/co/rsk/federate/signing/hsm/advanceblockchain/HsmBookkeepingClientImplTest.java @@ -19,6 +19,8 @@ import static co.rsk.federate.signing.HSMField.PARAMETERS; import static co.rsk.federate.signing.HSMField.STATE; import static co.rsk.federate.signing.HSMField.UPDATING; +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.MAX_ATTEMPTS; +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.INTERVAL_BETWEEN_ATTEMPTS; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -35,7 +37,6 @@ import co.rsk.federate.rpc.JsonRpcClient; import co.rsk.federate.rpc.JsonRpcClientProvider; import co.rsk.federate.rpc.JsonRpcException; -import co.rsk.federate.signing.ECDSASignerFactory; import co.rsk.federate.signing.HSMField; import co.rsk.federate.signing.hsm.HSMVersion; import co.rsk.federate.signing.hsm.HSMBlockchainBookkeepingRelatedException; @@ -90,8 +91,8 @@ void setUp() throws Exception { HSMClientProtocol hsmClientProtocol = new HSMClientProtocol( jsonRpcClientProviderMock, - ECDSASignerFactory.DEFAULT_ATTEMPTS, - ECDSASignerFactory.DEFAULT_INTERVAL + MAX_ATTEMPTS.getDefaultValue(Integer::parseInt), + INTERVAL_BETWEEN_ATTEMPTS.getDefaultValue(Integer::parseInt) ); hsmBookkeepingClient = new HsmBookkeepingClientImpl(hsmClientProtocol); diff --git a/src/test/java/co/rsk/federate/signing/hsm/client/HSMClientProtocolFactoryTest.java b/src/test/java/co/rsk/federate/signing/hsm/client/HSMClientProtocolFactoryTest.java index 4d7f0093..71997f58 100644 --- a/src/test/java/co/rsk/federate/signing/hsm/client/HSMClientProtocolFactoryTest.java +++ b/src/test/java/co/rsk/federate/signing/hsm/client/HSMClientProtocolFactoryTest.java @@ -1,55 +1,34 @@ package co.rsk.federate.signing.hsm.client; +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.SOCKET_TIMEOUT; +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.MAX_ATTEMPTS; +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.INTERVAL_BETWEEN_ATTEMPTS; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import co.rsk.federate.config.SignerConfig; +import co.rsk.federate.signing.hsm.config.PowHSMConfig; import co.rsk.federate.rpc.JsonRpcClientProvider; import co.rsk.federate.rpc.SocketBasedJsonRpcClientProvider; -import co.rsk.federate.signing.hsm.HSMUnsupportedTypeException; import co.rsk.federate.signing.utils.TestUtils; -import com.typesafe.config.Config; import java.net.InetSocketAddress; import java.net.SocketAddress; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; class HSMClientProtocolFactoryTest { - private HSMClientProtocolFactory hsmClientProtocolFactory; - - @BeforeEach - void setUp() { - hsmClientProtocolFactory = new HSMClientProtocolFactory(); - } + private final HSMClientProtocolFactory hsmClientProtocolFactory = new HSMClientProtocolFactory(); + private final PowHSMConfig powHsmConfig = mock(PowHSMConfig.class); @Test - void buildHSMProtocolFromUnknownConfig() { - Config configMock = mockConfig("random-type"); - SignerConfig signerConfig = new SignerConfig("random-id", configMock); - - assertThrows(HSMUnsupportedTypeException.class, () -> - hsmClientProtocolFactory.buildHSMClientProtocolFromConfig(signerConfig) - ); - } + void buildHSMProtocolFromPowHSMConfig() { + when(powHsmConfig.getHost()).thenReturn("localhost"); + when(powHsmConfig.getPort()).thenReturn(9999); + when(powHsmConfig.getSocketTimeout()).thenReturn(5000); + when(powHsmConfig.getMaxAttempts()).thenReturn(3); + when(powHsmConfig.getIntervalBetweenAttempts()).thenReturn(3000); - @Test - void buildHSMProtocolFromConfig() throws HSMUnsupportedTypeException { - Config configMock = mockConfig("hsm"); - when(configMock.getString(HSMClientProtocolFactory.HOST)).thenReturn("localhost"); - when(configMock.getInt(HSMClientProtocolFactory.PORT)).thenReturn(9999); - when(configMock.hasPath(HSMClientProtocolFactory.SOCKET_TIMEOUT)).thenReturn(true); - when(configMock.getInt(HSMClientProtocolFactory.SOCKET_TIMEOUT)).thenReturn(5000); - when(configMock.hasPath(HSMClientProtocolFactory.MAX_ATTEMPTS)).thenReturn(true); - when(configMock.getInt(HSMClientProtocolFactory.MAX_ATTEMPTS)).thenReturn(3); - when(configMock.hasPath(HSMClientProtocolFactory.INTERVAL_BETWEEN_ATTEMPTS)).thenReturn(true); - when(configMock.getInt(HSMClientProtocolFactory.INTERVAL_BETWEEN_ATTEMPTS)).thenReturn(3000); - - SignerConfig signerConfig = new SignerConfig("BTC", configMock); - HSMClientProtocol protocol = hsmClientProtocolFactory.buildHSMClientProtocolFromConfig(signerConfig); + HSMClientProtocol protocol = hsmClientProtocolFactory.buildHSMClientProtocolFromConfig(powHsmConfig); // Provider chain JsonRpcClientProvider jsonRpcClientProvider = TestUtils.getInternalState(protocol, "clientProvider"); @@ -63,7 +42,7 @@ void buildHSMProtocolFromConfig() throws HSMUnsupportedTypeException { assertEquals(9999, inetAddress.getPort()); // Timeout - int timeout = TestUtils.getInternalState(jsonRpcClientProvider, HSMClientProtocolFactory.SOCKET_TIMEOUT); + int timeout = TestUtils.getInternalState(jsonRpcClientProvider, "socketTimeout"); assertEquals(5000, timeout); // Attempts @@ -76,16 +55,17 @@ void buildHSMProtocolFromConfig() throws HSMUnsupportedTypeException { } @Test - void buildHSMProtocolFromDefaultConfig() throws HSMUnsupportedTypeException { - Config configMock = mockConfig("hsm"); - when(configMock.getString(HSMClientProtocolFactory.HOST)).thenReturn("localhost"); - when(configMock.getInt(HSMClientProtocolFactory.PORT)).thenReturn(9999); - when(configMock.hasPath(HSMClientProtocolFactory.SOCKET_TIMEOUT)).thenReturn(false); - when(configMock.hasPath(HSMClientProtocolFactory.MAX_ATTEMPTS)).thenReturn(false); - when(configMock.hasPath(HSMClientProtocolFactory.INTERVAL_BETWEEN_ATTEMPTS)).thenReturn(false); - - SignerConfig signerConfig = new SignerConfig("BTC", configMock); - HSMClientProtocol protocol = hsmClientProtocolFactory.buildHSMClientProtocolFromConfig(signerConfig); + void buildHSMProtocolFromDefaultConfig() { + int expectedTimeout = SOCKET_TIMEOUT.getDefaultValue(Integer::parseInt); + int expectedAttempts = MAX_ATTEMPTS.getDefaultValue(Integer::parseInt); + int expectedInterval = INTERVAL_BETWEEN_ATTEMPTS.getDefaultValue(Integer::parseInt); + when(powHsmConfig.getHost()).thenReturn("localhost"); + when(powHsmConfig.getPort()).thenReturn(9999); + when(powHsmConfig.getSocketTimeout()).thenReturn(expectedTimeout); + when(powHsmConfig.getMaxAttempts()).thenReturn(expectedAttempts); + when(powHsmConfig.getIntervalBetweenAttempts()).thenReturn(expectedInterval); + + HSMClientProtocol protocol = hsmClientProtocolFactory.buildHSMClientProtocolFromConfig(powHsmConfig); // Provider chain JsonRpcClientProvider jsonRpcClientProvider = TestUtils.getInternalState(protocol, "clientProvider"); @@ -99,22 +79,15 @@ void buildHSMProtocolFromDefaultConfig() throws HSMUnsupportedTypeException { assertEquals(9999, inetAddress.getPort()); // Timeout - int timeout = TestUtils.getInternalState(jsonRpcClientProvider, HSMClientProtocolFactory.SOCKET_TIMEOUT); - assertEquals(HSMClientProtocolFactory.DEFAULT_SOCKET_TIMEOUT, timeout); + int timeout = TestUtils.getInternalState(jsonRpcClientProvider, "socketTimeout"); + assertEquals(expectedTimeout, timeout); // Attempts int attempts = TestUtils.getInternalState(protocol, "maxConnectionAttempts"); - assertEquals(HSMClientProtocolFactory.DEFAULT_ATTEMPTS, attempts); + assertEquals(expectedAttempts, attempts); // Interval int interval = TestUtils.getInternalState(protocol, "waitTimeForReconnection"); - assertEquals(HSMClientProtocolFactory.DEFAULT_INTERVAL, interval); - } - - private Config mockConfig(String type) { - Config configMock = mock(Config.class); - when(configMock.getString("type")).thenReturn(type); - when(configMock.withoutPath(anyString())).thenReturn(configMock); - return configMock; + assertEquals(expectedInterval, interval); } } diff --git a/src/test/java/co/rsk/federate/signing/hsm/client/HSMClientProtocolTest.java b/src/test/java/co/rsk/federate/signing/hsm/client/HSMClientProtocolTest.java index b1b8ccd3..1b8fd3f7 100644 --- a/src/test/java/co/rsk/federate/signing/hsm/client/HSMClientProtocolTest.java +++ b/src/test/java/co/rsk/federate/signing/hsm/client/HSMClientProtocolTest.java @@ -22,6 +22,8 @@ import static co.rsk.federate.signing.HSMField.COMMAND; import static co.rsk.federate.signing.HSMField.ERROR; import static co.rsk.federate.signing.HSMField.ERROR_CODE; +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.MAX_ATTEMPTS; +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.INTERVAL_BETWEEN_ATTEMPTS; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -35,7 +37,6 @@ import co.rsk.federate.rpc.JsonRpcClient; import co.rsk.federate.rpc.JsonRpcClientProvider; import co.rsk.federate.rpc.JsonRpcException; -import co.rsk.federate.signing.ECDSASignerFactory; import co.rsk.federate.signing.HSMField; import co.rsk.federate.signing.hsm.HSMChangedVersionException; import co.rsk.federate.signing.hsm.HSMClientException; @@ -65,7 +66,11 @@ void createClient() throws JsonRpcException { jsonRpcClientProviderMock = mock(JsonRpcClientProvider.class); jsonRpcClientMock = mock(JsonRpcClient.class); when(jsonRpcClientProviderMock.acquire()).thenReturn(jsonRpcClientMock); - hsmClientProtocol = new HSMClientProtocol(jsonRpcClientProviderMock, ECDSASignerFactory.DEFAULT_ATTEMPTS, ECDSASignerFactory.DEFAULT_INTERVAL); + hsmClientProtocol = new HSMClientProtocol( + jsonRpcClientProviderMock, + MAX_ATTEMPTS.getDefaultValue(Integer::parseInt), + INTERVAL_BETWEEN_ATTEMPTS.getDefaultValue(Integer::parseInt) + ); } @Test diff --git a/src/test/java/co/rsk/federate/signing/hsm/client/HSMSigningClientV1Test.java b/src/test/java/co/rsk/federate/signing/hsm/client/HSMSigningClientV1Test.java index 7d7376ec..c39b2f3e 100644 --- a/src/test/java/co/rsk/federate/signing/hsm/client/HSMSigningClientV1Test.java +++ b/src/test/java/co/rsk/federate/signing/hsm/client/HSMSigningClientV1Test.java @@ -31,6 +31,8 @@ import static co.rsk.federate.signing.HSMField.SIGNATURE; import static co.rsk.federate.signing.HSMField.V; import static co.rsk.federate.signing.HSMField.VERSION; +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.MAX_ATTEMPTS; +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.INTERVAL_BETWEEN_ATTEMPTS; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; @@ -44,7 +46,6 @@ import co.rsk.federate.rpc.JsonRpcClient; import co.rsk.federate.rpc.JsonRpcClientProvider; import co.rsk.federate.rpc.JsonRpcException; -import co.rsk.federate.signing.ECDSASignerFactory; import co.rsk.federate.signing.HSMCommand; import co.rsk.federate.signing.hsm.HSMClientException; import co.rsk.federate.signing.hsm.HSMVersion; @@ -63,7 +64,11 @@ class HSMSigningClientV1Test { void createClient() throws JsonRpcException { JsonRpcClientProvider jsonRpcClientProviderMock = mock(JsonRpcClientProvider.class); jsonRpcClientMock = mock(JsonRpcClient.class); - HSMClientProtocol hsmClientProtocol = new HSMClientProtocol(jsonRpcClientProviderMock, ECDSASignerFactory.DEFAULT_ATTEMPTS, ECDSASignerFactory.DEFAULT_INTERVAL); + HSMClientProtocol hsmClientProtocol = new HSMClientProtocol( + jsonRpcClientProviderMock, + MAX_ATTEMPTS.getDefaultValue(Integer::parseInt), + INTERVAL_BETWEEN_ATTEMPTS.getDefaultValue(Integer::parseInt) + ); client = new HSMSigningClientV1(hsmClientProtocol); when(jsonRpcClientProviderMock.acquire()).thenReturn(jsonRpcClientMock); } diff --git a/src/test/java/co/rsk/federate/signing/hsm/client/PowHSMSigningClientBtcTest.java b/src/test/java/co/rsk/federate/signing/hsm/client/PowHSMSigningClientBtcTest.java index 00e96536..eabdf108 100644 --- a/src/test/java/co/rsk/federate/signing/hsm/client/PowHSMSigningClientBtcTest.java +++ b/src/test/java/co/rsk/federate/signing/hsm/client/PowHSMSigningClientBtcTest.java @@ -23,6 +23,8 @@ import static co.rsk.federate.signing.HSMField.VERSION; import static co.rsk.federate.signing.utils.TestUtils.createBaseInputScriptThatSpendsFromTheFederation; import static co.rsk.federate.signing.utils.TestUtils.createBlock; +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.MAX_ATTEMPTS; +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.INTERVAL_BETWEEN_ATTEMPTS; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -47,7 +49,6 @@ import co.rsk.federate.rpc.JsonRpcClient; import co.rsk.federate.rpc.JsonRpcClientProvider; import co.rsk.federate.rpc.JsonRpcException; -import co.rsk.federate.signing.ECDSASignerFactory; import co.rsk.federate.signing.KeyId; import co.rsk.federate.signing.hsm.HSMClientException; import co.rsk.federate.signing.hsm.HSMVersion; @@ -141,11 +142,12 @@ void setup() throws JsonRpcException { jsonRpcClientMock = mock(JsonRpcClient.class); when(jsonRpcClientProviderMock.acquire()).thenReturn(jsonRpcClientMock); - hsmClientProtocol = new HSMClientProtocol(jsonRpcClientProviderMock, - ECDSASignerFactory.DEFAULT_ATTEMPTS, ECDSASignerFactory.DEFAULT_INTERVAL); + hsmClientProtocol = new HSMClientProtocol( + jsonRpcClientProviderMock, + MAX_ATTEMPTS.getDefaultValue(Integer::parseInt), + INTERVAL_BETWEEN_ATTEMPTS.getDefaultValue(Integer::parseInt) + ); client = new PowHSMSigningClientBtc(hsmClientProtocol, HSMVersion.V2.getNumber()); - - } @Test diff --git a/src/test/java/co/rsk/federate/signing/hsm/client/PowHSMSigningClientRskMstTest.java b/src/test/java/co/rsk/federate/signing/hsm/client/PowHSMSigningClientRskMstTest.java index b61620ce..b4f3e652 100644 --- a/src/test/java/co/rsk/federate/signing/hsm/client/PowHSMSigningClientRskMstTest.java +++ b/src/test/java/co/rsk/federate/signing/hsm/client/PowHSMSigningClientRskMstTest.java @@ -12,6 +12,8 @@ import static co.rsk.federate.signing.HSMField.S; import static co.rsk.federate.signing.HSMField.SIGNATURE; import static co.rsk.federate.signing.HSMField.VERSION; +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.MAX_ATTEMPTS; +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.INTERVAL_BETWEEN_ATTEMPTS; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -23,7 +25,6 @@ import co.rsk.federate.rpc.JsonRpcClient; import co.rsk.federate.rpc.JsonRpcClientProvider; import co.rsk.federate.rpc.JsonRpcException; -import co.rsk.federate.signing.ECDSASignerFactory; import co.rsk.federate.signing.hsm.HSMClientException; import co.rsk.federate.signing.hsm.HSMVersion; import co.rsk.federate.signing.hsm.message.SignerMessageV1; @@ -41,7 +42,11 @@ class PowHSMSigningClientRskMstTest { void createClient() throws JsonRpcException { JsonRpcClientProvider jsonRpcClientProviderMock = mock(JsonRpcClientProvider.class); jsonRpcClientMock = mock(JsonRpcClient.class); - HSMClientProtocol hsmClientProtocol = new HSMClientProtocol(jsonRpcClientProviderMock, ECDSASignerFactory.DEFAULT_ATTEMPTS, ECDSASignerFactory.DEFAULT_INTERVAL); + HSMClientProtocol hsmClientProtocol = new HSMClientProtocol( + jsonRpcClientProviderMock, + MAX_ATTEMPTS.getDefaultValue(Integer::parseInt), + INTERVAL_BETWEEN_ATTEMPTS.getDefaultValue(Integer::parseInt) + ); client = new PowHSMSigningClientRskMst(hsmClientProtocol, HSMVersion.V2.getNumber()); when(jsonRpcClientProviderMock.acquire()).thenReturn(jsonRpcClientMock); } diff --git a/src/test/java/co/rsk/federate/signing/hsm/client/PowHSMSigningClientTest.java b/src/test/java/co/rsk/federate/signing/hsm/client/PowHSMSigningClientTest.java index bb0901c3..a8415864 100644 --- a/src/test/java/co/rsk/federate/signing/hsm/client/PowHSMSigningClientTest.java +++ b/src/test/java/co/rsk/federate/signing/hsm/client/PowHSMSigningClientTest.java @@ -24,6 +24,8 @@ import static co.rsk.federate.signing.HSMField.KEY_ID; import static co.rsk.federate.signing.HSMField.PUB_KEY; import static co.rsk.federate.signing.HSMField.VERSION; +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.MAX_ATTEMPTS; +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.INTERVAL_BETWEEN_ATTEMPTS; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -36,7 +38,6 @@ import co.rsk.federate.rpc.JsonRpcClient; import co.rsk.federate.rpc.JsonRpcClientProvider; import co.rsk.federate.rpc.JsonRpcException; -import co.rsk.federate.signing.ECDSASignerFactory; import co.rsk.federate.signing.HSMCommand; import co.rsk.federate.signing.hsm.HSMClientException; import co.rsk.federate.signing.hsm.HSMVersion; @@ -54,7 +55,11 @@ class PowHSMSigningClientTest { void createClient() throws JsonRpcException { JsonRpcClientProvider jsonRpcClientProviderMock = mock(JsonRpcClientProvider.class); jsonRpcClientMock = mock(JsonRpcClient.class); - HSMClientProtocol hsmClientProtocol = new HSMClientProtocol(jsonRpcClientProviderMock, ECDSASignerFactory.DEFAULT_ATTEMPTS, ECDSASignerFactory.DEFAULT_INTERVAL); + HSMClientProtocol hsmClientProtocol = new HSMClientProtocol( + jsonRpcClientProviderMock, + MAX_ATTEMPTS.getDefaultValue(Integer::parseInt), + INTERVAL_BETWEEN_ATTEMPTS.getDefaultValue(Integer::parseInt) + ); //Since parent class is abstract, test all the common methods using PowHSMSigningClientBtc. client = new PowHSMSigningClientBtc(hsmClientProtocol, HSMVersion.V2.getNumber()); when(jsonRpcClientProviderMock.acquire()).thenReturn(jsonRpcClientMock); diff --git a/src/test/java/co/rsk/federate/signing/hsm/config/PowHSMConfigTest.java b/src/test/java/co/rsk/federate/signing/hsm/config/PowHSMConfigTest.java new file mode 100644 index 00000000..621fcd3a --- /dev/null +++ b/src/test/java/co/rsk/federate/signing/hsm/config/PowHSMConfigTest.java @@ -0,0 +1,191 @@ +package co.rsk.federate.signing.hsm.config; + +import static co.rsk.federate.signing.hsm.config.PowHSMConfigParameter.*; +import static co.rsk.federate.signing.utils.TestUtils.createHash; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import co.rsk.bitcoinj.core.NetworkParameters; +import co.rsk.federate.signing.config.SignerConfig; +import co.rsk.federate.signing.config.SignerType; +import co.rsk.federate.signing.hsm.HSMBlockchainBookkeepingRelatedException; +import co.rsk.federate.signing.hsm.HSMClientException; +import co.rsk.federate.signing.hsm.HSMUnsupportedTypeException; +import co.rsk.federate.signing.hsm.client.HSMBookkeepingClient; +import co.rsk.federate.signing.hsm.message.PowHSMBlockchainParameters; +import com.typesafe.config.Config; +import com.typesafe.config.ConfigException; +import java.math.BigInteger; +import java.util.function.Function; +import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class PowHSMConfigTest { + + private final SignerConfig signerConfig = mock(SignerConfig.class); + private final Config config = mock(Config.class); + private final HSMBookkeepingClient hsmClient = mock(HSMBookkeepingClient.class); + + private PowHSMConfig powHsmConfig; + + @BeforeEach + void setup() throws Exception { + when(signerConfig.getConfig()).thenReturn(config); + when(signerConfig.getSignerType()).thenReturn(SignerType.HSM); + powHsmConfig = new PowHSMConfig(signerConfig); + } + + @Test + void getDifficultyTarget_whenCallToPowHSMBlockchainParametersSucceeds_shouldRetrieveConfigValueFromPowHSM() + throws Exception { + BigInteger expectedDifficultyTarget = BigInteger.valueOf(1L); + String blockCheckpoint = createHash(1).toHexString(); + PowHSMBlockchainParameters response = new PowHSMBlockchainParameters( + blockCheckpoint, expectedDifficultyTarget, NetworkParameters.ID_UNITTESTNET.toString()); + when(hsmClient.getBlockchainParameters()).thenReturn(response); + + assertEquals(expectedDifficultyTarget, powHsmConfig.getDifficultyTarget(hsmClient)); + } + + @Test + void getDifficultyTarget_whenPowHSMCallFailsWithHSMUnsupportedTypeExceptionAndCustomConfigIsPresent_shouldReturnCustomConfig() + throws Exception { + BigInteger customDifficultyTarget = BigInteger.valueOf(1L); + when(hsmClient.getBlockchainParameters()).thenThrow(new HSMUnsupportedTypeException("error")); + when(config.getString(DIFFICULTY_TARGET.getPath())).thenReturn("1"); + + assertEquals(customDifficultyTarget, powHsmConfig.getDifficultyTarget(hsmClient)); + } + + @Test + void getDifficultyTarget_whenPowHSMCallFailsWithHSMUnsupportedTypeExceptionAndCustomConfigIsNotPresent_shouldThrowConfigException() + throws Exception { + when(hsmClient.getBlockchainParameters()).thenThrow(new HSMUnsupportedTypeException("error")); + when(config.getString(DIFFICULTY_TARGET.getPath())) + .thenThrow(new ConfigException.Missing(DIFFICULTY_TARGET.getPath())); + + assertThrows(ConfigException.class, + () -> powHsmConfig.getDifficultyTarget(hsmClient)); + } + + @Test + void getDifficultyTarget_whenPowHSMCallFailsWithSomeHSMClientException_shouldThrowHSMClientException() + throws Exception { + when(hsmClient.getBlockchainParameters()).thenThrow(new HSMBlockchainBookkeepingRelatedException("error")); + + assertThrows(HSMClientException.class, + () -> powHsmConfig.getDifficultyTarget(hsmClient)); + } + + @Test + void getMaxAmountBlockHeaders_whenCustomConfigAvailable_shouldReturnCustomConfig() { + int customMaxAmountBlockHeaders = 1; + when(config.hasPath(MAX_AMOUNT_BLOCK_HEADERS.getPath())).thenReturn(true); + when(config.getInt(MAX_AMOUNT_BLOCK_HEADERS.getPath())).thenReturn(customMaxAmountBlockHeaders); + + assertEquals(customMaxAmountBlockHeaders, powHsmConfig.getMaxAmountBlockHeaders()); + } + + @Test + void getMaxAmountBlockHeaders_whenCustomConfigNotAvailable_shouldReturnDefaultConfig() { + when(config.hasPath(MAX_AMOUNT_BLOCK_HEADERS.getPath())).thenReturn(false); + + int defaultValue = MAX_AMOUNT_BLOCK_HEADERS.getDefaultValue(Integer::parseInt); + assertEquals(defaultValue, powHsmConfig.getMaxAmountBlockHeaders()); + } + + @Test + void getMaxChunkSizeToHsm_whenCustomConfigAvailable_shouldReturnCustomConfig() { + int customMaxChunkSize = 1; + when(config.hasPath(MAX_CHUNK_SIZE_TO_HSM.getPath())).thenReturn(true); + when(config.getInt(MAX_CHUNK_SIZE_TO_HSM.getPath())).thenReturn(customMaxChunkSize); + + assertEquals(customMaxChunkSize, powHsmConfig.getMaxChunkSizeToHsm()); + } + + @Test + void getMaxChunkSizeToHsm_whenCustomConfigNotAvailable_shouldReturnDefaultConfig() { + when(config.hasPath(MAX_CHUNK_SIZE_TO_HSM.getPath())).thenReturn(false); + + int defaultValue = MAX_CHUNK_SIZE_TO_HSM.getDefaultValue(Integer::parseInt); + assertEquals(defaultValue, powHsmConfig.getMaxChunkSizeToHsm()); + } + + @Test + void getInformerInterval_whenCustomConfigAvailable_shouldReturnCustomConfig() { + long customInformerInterval = 1L; + when(config.hasPath(INFORMER_INTERVAL.getPath())).thenReturn(true); + when(config.getLong(INFORMER_INTERVAL.getPath())).thenReturn(customInformerInterval); + + assertEquals(customInformerInterval, powHsmConfig.getInformerInterval()); + } + + @Test + void getInformerInterval_whenCustomConfigNotAvailable_shouldReturnDefaultConfig() { + when(config.hasPath(INFORMER_INTERVAL.getPath())).thenReturn(false); + + long defaultValue = INFORMER_INTERVAL.getDefaultValue(Long::parseLong); + assertEquals(defaultValue, powHsmConfig.getInformerInterval()); + } + + @Test + void isStoppingBookkeepingScheduler_whenCustomConfigAvailable_shouldReturnCustomConfig() { + boolean customIsStoppingInformerInterval = !STOP_BOOKKEEPING_SCHEDULER.getDefaultValue(Boolean::parseBoolean); + when(config.hasPath(STOP_BOOKKEEPING_SCHEDULER.getPath())).thenReturn(true); + when(config.getBoolean(STOP_BOOKKEEPING_SCHEDULER.getPath())).thenReturn(customIsStoppingInformerInterval); + + assertTrue(powHsmConfig.isStopBookkeepingScheduler()); + } + + @Test + void isStoppingBookkeepingScheduler_whenCustomConfigNotAvailable_shouldReturnDefaultConfig() { + when(config.hasPath(STOP_BOOKKEEPING_SCHEDULER.getPath())).thenReturn(false); + + assertFalse(powHsmConfig.isStopBookkeepingScheduler()); + } + + @ParameterizedTest + @MethodSource("provideNetworkParametersAndExpectedCaps") + void getDifficultyCap_whenGivenNetwork_shouldMatchExpectedDifficultyCap(String networkId, + NetworkDifficultyCap expectedNetworkDifficultyCap) { + assertEquals(expectedNetworkDifficultyCap.getDifficultyCap(), + powHsmConfig.getDifficultyCap(networkId)); + } + + @Test + void getDifficultyCap_whenGivenInvalidNetwork_showThrowIllegalArgumentException() { + assertThrows(IllegalArgumentException.class, + () -> powHsmConfig.getDifficultyCap(NetworkParameters.ID_UNITTESTNET)); + } + + @ParameterizedTest + @MethodSource("powHSMConfigParameterProvider") + void powHSMConfigParameter_whenDefaultIsEmpty_shouldThrowIllegalStateException( + PowHSMConfigParameter param) { + Function parser = Function.identity(); + assertThrows(IllegalStateException.class, + () -> param.getDefaultValue(parser)); + } + + private static Stream powHSMConfigParameterProvider() { + return Stream.of( + Arguments.of(HOST), + Arguments.of(PORT), + Arguments.of(DIFFICULTY_TARGET)); + } + + static Stream provideNetworkParametersAndExpectedCaps() { + return Stream.of( + Arguments.of(NetworkParameters.ID_MAINNET, NetworkDifficultyCap.MAINNET), + Arguments.of(NetworkParameters.ID_TESTNET, NetworkDifficultyCap.TESTNET), + Arguments.of(NetworkParameters.ID_REGTEST, NetworkDifficultyCap.REGTEST)); + } +}