feat(swap): Start wallets and tor client in parallel (#198)

CLI + GUI: At startup the wallets and tor client are started in parallel. This will speed up the startup time of the application.
This commit is contained in:
binarybaron 2024-11-21 01:51:19 +01:00 committed by GitHub
parent 6cd228fada
commit 689dd89e72
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 386 additions and 289 deletions

View file

@ -1,11 +1,11 @@
import { Box, Button, LinearProgress, makeStyles } from "@material-ui/core";
import { Alert } from "@material-ui/lab";
import { TauriContextInitializationProgress } from "models/tauriModel";
import { useNavigate } from "react-router-dom";
import { useAppSelector } from "store/hooks";
import { exhaustiveGuard } from "utils/typescriptUtils";
import { LoadingSpinnerAlert } from "./LoadingSpinnerAlert";
import { bytesToMb } from "utils/conversionUtils";
import { TauriPartialInitProgress } from "models/tauriModel";
const useStyles = makeStyles((theme) => ({
innerAlert: {
@ -15,56 +15,75 @@ const useStyles = makeStyles((theme) => ({
},
}));
function PartialInitStatus({ status, classes }: {
status: TauriPartialInitProgress,
classes: ReturnType<typeof useStyles>
}) {
if (status.progress.type === "Completed") {
return null;
}
switch (status.componentName) {
case "OpeningBitcoinWallet":
return (
<LoadingSpinnerAlert severity="warning">
Syncing internal Bitcoin wallet
</LoadingSpinnerAlert>
);
case "DownloadingMoneroWalletRpc":
return (
<LoadingSpinnerAlert severity="warning">
<Box className={classes.innerAlert}>
<Box>
Downloading and verifying the Monero wallet RPC (
{bytesToMb(status.progress.content.size).toFixed(2)} MB)
</Box>
<LinearProgress variant="determinate" value={status.progress.content.progress} />
</Box>
</LoadingSpinnerAlert>
);
case "OpeningMoneroWallet":
return (
<LoadingSpinnerAlert severity="warning">
Opening the Monero wallet
</LoadingSpinnerAlert>
);
case "OpeningDatabase":
return (
<LoadingSpinnerAlert severity="warning">
Opening the local database
</LoadingSpinnerAlert>
);
case "EstablishingTorCircuits":
return (
<LoadingSpinnerAlert severity="warning">
Establishing Tor circuits
</LoadingSpinnerAlert>
)
default:
return null;
}
}
export default function DaemonStatusAlert() {
const classes = useStyles();
const contextStatus = useAppSelector((s) => s.rpc.status);
const navigate = useNavigate();
if (contextStatus === null) {
if (contextStatus === null || contextStatus.type === "NotInitialized") {
return <LoadingSpinnerAlert severity="warning">Checking for available remote nodes</LoadingSpinnerAlert>;
}
switch (contextStatus.type) {
case "Initializing":
switch (contextStatus.content.type) {
case "OpeningBitcoinWallet":
return (
<LoadingSpinnerAlert severity="warning">
Connecting to the Bitcoin network
</LoadingSpinnerAlert>
);
case "DownloadingMoneroWalletRpc":
return (
<LoadingSpinnerAlert severity="warning">
<Box className={classes.innerAlert}>
<Box>
Downloading and verifying the Monero wallet RPC (
{bytesToMb(contextStatus.content.content.size).toFixed(2)} MB)
</Box>
<LinearProgress variant="determinate" value={contextStatus.content.content.progress} />
</Box>
</LoadingSpinnerAlert >
);
case "OpeningMoneroWallet":
return (
<LoadingSpinnerAlert severity="warning">
Connecting to the Monero network
</LoadingSpinnerAlert>
);
case "OpeningDatabase":
return (
<LoadingSpinnerAlert severity="warning">
Opening the local database
</LoadingSpinnerAlert>
);
case "EstablishingTorCircuits":
return (
<LoadingSpinnerAlert severity="warning">
Connecting to the Tor network
</LoadingSpinnerAlert>
);
}
break;
return contextStatus.content
.map((status) => (
<PartialInitStatus
key={status.componentName}
status={status}
classes={classes}
/>
))
case "Available":
return <Alert severity="success">The daemon is running</Alert>;
case "Failed":

View file

@ -69,10 +69,26 @@ export const rpcSlice = createSlice({
slice,
action: PayloadAction<TauriContextStatusEvent>,
) {
slice.status = action.payload;
// If we are already initializing, and we receive a new partial status, we update the existing status
if (slice.status?.type === "Initializing" && action.payload.type === "Initializing") {
for (const partialStatus of action.payload.content) {
// We find the existing status with the same type
const existingStatus = slice.status.content.find(s => s.componentName === partialStatus.componentName);
if (existingStatus) {
// If we find it, we update the content
existingStatus.progress = partialStatus.progress;
} else {
// Otherwise, we add the new partial status
slice.status.content.push(partialStatus);
}
}
} else {
// Otherwise, we replace the whole status
slice.status = action.payload;
}
},
timelockChangeEventReceived(
slice,
slice: RPCSlice,
action: PayloadAction<TauriTimelockChangeEvent>
) {
if (slice.state.swapInfos[action.payload.swap_id]) {