diff --git a/src/main/cli/cli.ts b/src/main/cli/cli.ts index 377da29..f35950b 100644 --- a/src/main/cli/cli.ts +++ b/src/main/cli/cli.ts @@ -104,7 +104,6 @@ export async function stopCli() { export async function spawnSubcommand( subCommand: string, options: { [option: string]: string }, - onLog: (log: CliLog[]) => void, onExit: (code: number | null, signal: NodeJS.Signals | null) => void, onStdOut: (data: string) => void ): Promise { @@ -258,7 +257,6 @@ export async function startRPC() { 'server-address': `${RPC_BIND_HOST}:${RPC_BIND_PORT}`, }, async (logs) => { - store.dispatch(rpcAddLogs(logs)); RPC_LOG_EVENT_EMITTER.emit(logs); const processType = store.getState().rpc.process.type; diff --git a/src/main/cli/dirs.ts b/src/main/cli/dirs.ts index 11e6d87..94ef770 100644 --- a/src/main/cli/dirs.ts +++ b/src/main/cli/dirs.ts @@ -160,14 +160,11 @@ export default async function getSavedLogsOfSwapId( const rpcProcess = store.getState().rpc.process; const currentProcessLogs = - rpcProcess.type === RpcProcessStateType.NOT_STARTED - ? '' - : rpcProcess.stdOut; - const rpcProcessLogs = getLogsFromRawFileString(currentProcessLogs).filter( - (log) => { - return getCliLogSpanSwapId(log) === swapId; - } - ); + rpcProcess.type === RpcProcessStateType.NOT_STARTED ? [] : rpcProcess.logs; + + const rpcProcessLogs = currentProcessLogs.filter((log): log is CliLog => { + return typeof log !== 'string' && getCliLogSpanSwapId(log) === swapId; + }); const allLogs = [...legacyLogs, ...logs, ...rpcProcessLogs]; const allLogsWithoutDuplicates = uniqBy( diff --git a/src/main/store/mainStoreListeners.ts b/src/main/store/mainStoreListeners.ts index cf6f490..fea4288 100644 --- a/src/main/store/mainStoreListeners.ts +++ b/src/main/store/mainStoreListeners.ts @@ -1,9 +1,10 @@ import { createListenerMiddleware } from '@reduxjs/toolkit'; -import { getRawSwapInfo } from '../cli/rpc'; +import { getRawSwapInfo, getRawSwapInfos } from '../cli/rpc'; import { CliLog, getCliLogSpanSwapId, isCliLogAdvancingState, + isCliLogGotNotificationForNewBlock, isCliLogReleasingSwapLockLog, } from '../../models/cliModel'; import logger from '../../utils/logger'; @@ -40,5 +41,22 @@ export function createMainListeners() { }, }); + // Listener for "Got notification for new Block" log + // If we get a new block, we fetch all swap infos because the state of the timelocks might have changed + listener.startListening({ + predicate: (action) => { + return action.type === 'rpc/rpcAddLog'; + }, + effect: async (action) => { + const logs = action.payload.logs as CliLog[]; + const newBlockLog = logs.find(isCliLogGotNotificationForNewBlock); + + if (newBlockLog) { + logger.debug('Fetching all swap infos because a new block was found'); + await getRawSwapInfos(); + } + }, + }); + return listener; } diff --git a/src/models/cliModel.ts b/src/models/cliModel.ts index 2da8a8d..dd2b1d7 100644 --- a/src/models/cliModel.ts +++ b/src/models/cliModel.ts @@ -367,3 +367,16 @@ export interface CliLogDownloadingMoneroWalletRpc extends CliLog { download_url: string; }; } + +export interface CliLogGotNotificationForNewBlock extends CliLog { + fields: { + message: 'Got notification for new block'; + block_height: string; + }; +} + +export function isCliLogGotNotificationForNewBlock( + log: CliLog +): log is CliLogGotNotificationForNewBlock { + return log.fields.message === 'Got notification for new block'; +} diff --git a/src/renderer/components/pages/help/RpcControlBox.tsx b/src/renderer/components/pages/help/RpcControlBox.tsx index cef0113..42609af 100644 --- a/src/renderer/components/pages/help/RpcControlBox.tsx +++ b/src/renderer/components/pages/help/RpcControlBox.tsx @@ -29,7 +29,7 @@ export default function RpcControlBox() { isRunning || rpcProcess.type === RpcProcessStateType.EXITED ? ( ) : null } diff --git a/src/store/features/rpcSlice.ts b/src/store/features/rpcSlice.ts index 6d46eab..b266054 100644 --- a/src/store/features/rpcSlice.ts +++ b/src/store/features/rpcSlice.ts @@ -8,26 +8,28 @@ import { } from '../../models/rpcModel'; import { CliLog, + isCliLog, isCliLogDownloadingMoneroWalletRpc, isCliLogFailedToSyncMoneroWallet, isCliLogFinishedSyncingMoneroWallet, isCliLogStartedRpcServer, isCliLogStartedSyncingMoneroWallet, } from '../../models/cliModel'; +import { getLogsAndStringsFromRawFileString } from 'utils/parseUtils'; type Process = | { type: RpcProcessStateType.STARTED; - stdOut: string; + logs: (CliLog | string)[]; } | { type: RpcProcessStateType.LISTENING_FOR_CONNECTIONS; - stdOut: string; + logs: (CliLog | string)[]; address: string; } | { type: RpcProcessStateType.EXITED; - stdOut: string; + logs: (CliLog | string)[]; exitCode: number | null; } | { @@ -88,42 +90,42 @@ export const rpcSlice = createSlice({ slice.process.type === RpcProcessStateType.STARTED || slice.process.type === RpcProcessStateType.LISTENING_FOR_CONNECTIONS ) { - slice.process.stdOut += action.payload; - } - }, - rpcAddLogs(slice, action: PayloadAction) { - action.payload.forEach((log) => { - if ( - isCliLogStartedRpcServer(log) && - slice.process.type === RpcProcessStateType.STARTED - ) { - slice.process = { - type: RpcProcessStateType.LISTENING_FOR_CONNECTIONS, - stdOut: slice.process.stdOut, - address: log.fields.addr, - }; - } else if (isCliLogDownloadingMoneroWalletRpc(log)) { - slice.state.moneroWalletRpc.updateState = { - progress: log.fields.progress, - downloadUrl: log.fields.download_url, - }; + const logs = getLogsAndStringsFromRawFileString(action.payload); + slice.process.logs.push(...logs); - if (log.fields.progress === '100%') { - slice.state.moneroWalletRpc.updateState = false; + logs.filter(isCliLog).forEach((log) => { + if ( + isCliLogStartedRpcServer(log) && + slice.process.type === RpcProcessStateType.STARTED + ) { + slice.process = { + type: RpcProcessStateType.LISTENING_FOR_CONNECTIONS, + logs: slice.process.logs, + address: log.fields.addr, + }; + } else if (isCliLogDownloadingMoneroWalletRpc(log)) { + slice.state.moneroWalletRpc.updateState = { + progress: log.fields.progress, + downloadUrl: log.fields.download_url, + }; + + if (log.fields.progress === '100%') { + slice.state.moneroWalletRpc.updateState = false; + } + } else if (isCliLogStartedSyncingMoneroWallet(log)) { + slice.state.moneroWallet.isSyncing = true; + } else if (isCliLogFinishedSyncingMoneroWallet(log)) { + slice.state.moneroWallet.isSyncing = false; + } else if (isCliLogFailedToSyncMoneroWallet(log)) { + slice.state.moneroWallet.isSyncing = false; } - } else if (isCliLogStartedSyncingMoneroWallet(log)) { - slice.state.moneroWallet.isSyncing = true; - } else if (isCliLogFinishedSyncingMoneroWallet(log)) { - slice.state.moneroWallet.isSyncing = false; - } else if (isCliLogFailedToSyncMoneroWallet(log)) { - slice.state.moneroWallet.isSyncing = false; - } - }); + }); + } }, rpcInitiate(slice) { slice.process = { type: RpcProcessStateType.STARTED, - stdOut: '', + logs: [], }; }, rpcProcessExited( @@ -139,7 +141,7 @@ export const rpcSlice = createSlice({ ) { slice.process = { type: RpcProcessStateType.EXITED, - stdOut: slice.process.stdOut, + logs: slice.process.logs, exitCode: action.payload.exitCode, }; slice.state.moneroWalletRpc = { @@ -200,7 +202,6 @@ export const rpcSlice = createSlice({ export const { rpcProcessExited, rpcAppendStdOut, - rpcAddLogs, rpcInitiate, rpcSetBalance, rpcSetWithdrawTxId,