walletfx: Improve calculation of estimatedKeyDerivationTime

* Make the static field `estimatedKeyDerivationTime` private
* Refactor the calculation to a private, side-effect free function
* Replace `estimatedKeyDerivationTimeMsec()` with `initEstimatedKeyDerivationTime()`
** Don’t return a value that wasn’t unused anyway
** Make better use of CompletableFuture API
* Platform.runLater wasn’t needed because no JavaFX functions are called
This commit is contained in:
Sean Gilligan 2021-09-22 17:15:14 -07:00 committed by Andreas Schildbach
parent 36243ca24e
commit 0f8cc09073
2 changed files with 29 additions and 21 deletions

View File

@ -18,7 +18,6 @@ package org.bitcoinj.walletfx.application;
import com.google.common.util.concurrent.Service;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.input.KeyCombination;
import javafx.stage.Stage;
import org.bitcoinj.core.NetworkParameters;
@ -130,7 +129,7 @@ public abstract class WalletApplication implements AppDelegate {
primaryStage.show();
WalletSetPasswordController.estimateKeyDerivationTimeMsec();
WalletSetPasswordController.initEstimatedKeyDerivationTime();
walletAppKit.addListener(new Service.Listener() {
@Override

View File

@ -69,26 +69,35 @@ public class WalletSetPasswordController implements OverlayController<WalletSetP
progressMeter.setOpacity(0);
}
public static Duration estimatedKeyDerivationTime = null;
private static Duration estimatedKeyDerivationTime = null;
public static CompletableFuture<Duration> estimateKeyDerivationTimeMsec() {
// This is run in the background after startup. If we haven't recorded it before, do a key derivation to see
// how long it takes. This helps us produce better progress feedback, as on Windows we don't currently have a
// native Scrypt impl and the Java version is ~3 times slower, plus it depends a lot on CPU speed.
CompletableFuture<Duration> future = new CompletableFuture<>();
new Thread(() -> {
log.info("Doing background test key derivation");
KeyCrypterScrypt scrypt = new KeyCrypterScrypt(SCRYPT_PARAMETERS);
long start = System.currentTimeMillis();
scrypt.deriveKey("test password");
long msec = System.currentTimeMillis() - start;
log.info("Background test key derivation took {}msec", msec);
Platform.runLater(() -> {
estimatedKeyDerivationTime = Duration.ofMillis(msec);
future.complete(estimatedKeyDerivationTime);
});
}).start();
return future;
/**
* Initialize the {@code estimatedKeyDerivationTime} static field if not already initialized
* <p>
* This is run in the background after startup. If we haven't recorded it before, do a key derivation to see
* how long it takes. This helps us produce better progress feedback, as on Windows we don't currently have a
* native Scrypt impl and the Java version is ~3 times slower, plus it depends a lot on CPU speed.
*/
public static void initEstimatedKeyDerivationTime() {
if (estimatedKeyDerivationTime == null) {
CompletableFuture
.supplyAsync(WalletSetPasswordController::estimateKeyDerivationTime)
.thenAccept(duration -> estimatedKeyDerivationTime = duration);
}
}
/**
* Estimate key derivation time with no side effects
* @return duration in milliseconds
*/
private static Duration estimateKeyDerivationTime() {
log.info("Doing background test key derivation");
KeyCrypterScrypt scrypt = new KeyCrypterScrypt(SCRYPT_PARAMETERS);
long start = System.currentTimeMillis();
scrypt.deriveKey("test password");
long msec = System.currentTimeMillis() - start;
log.info("Background test key derivation took {}msec", msec);
return Duration.ofMillis(msec);
}
@FXML