Fix race condition in revert transaction, causing aceess to dead mobx proof models. Patch hotUpdater

This commit is contained in:
minibits-cash
2026-03-26 16:16:35 +01:00
parent 26aac2dee8
commit 98a4fb5073
3 changed files with 32 additions and 17 deletions
+13
View File
@@ -0,0 +1,13 @@
diff --git a/node_modules/@hot-updater/bare/dist/index.cjs b/node_modules/@hot-updater/bare/dist/index.cjs
index 2476539..bc47c39 100644
--- a/node_modules/@hot-updater/bare/dist/index.cjs
+++ b/node_modules/@hot-updater/bare/dist/index.cjs
@@ -6528,6 +6528,8 @@ async function getHermesCommand(cwd) {
if (fileExists(bundledHermesEngine)) return bundledHermesEngine;
const hermesEngine = path.default.join("node_modules", "hermes-engine", getHermesOSBin(), getHermesOSExe());
if (fileExists(hermesEngine)) return hermesEngine;
+ const hermesCompiler = path.default.join("node_modules", "hermes-compiler", "hermesc", getHermesOSBin(), getHermesOSExe());
+ if (fileExists(hermesCompiler)) return hermesCompiler;
return path.default.join("node_modules", "hermesvm", getHermesOSBin(), "hermes");
}
/**
-2
View File
@@ -56,8 +56,6 @@ import { CommonActions, StaticScreenProps, useFocusEffect, useNavigation } from
import { QRCodeBlock } from './Wallet/QRCode'
import { MintListItem } from './Mints/MintListItem'
import { Token, getDecodedToken } from '@cashu/cashu-ts'
import { RECEIVE_OFFLINE_COMPLETE_TASK, RECEIVE_TASK } from '../services/wallet/receiveTask'
import { REVERT_TASK } from '../services/wallet/revertTask'
import FastImage from 'react-native-fast-image'
import { MintHeader } from './Mints/MintHeader'
import { TransferOption } from './TransferScreen'
+19 -15
View File
@@ -1307,25 +1307,29 @@ const syncStateWithMintTask = async function (
const revertedTxIds: number[] = []
try {
if (proofsToSync.length === 0) {
// Filter out proof nodes that were removed from the MST between the time
// the task was queued and when it actually runs (e.g. revertTask ran first).
const aliveProofs = proofsToSync.filter(p => isAlive(p))
if (aliveProofs.length === 0) {
const message = `No ${isPending ? 'pending ' : ''}proofs to sync with mint`
log.trace('[syncStateWithMintTask]', message)
return {
taskFunction: SYNC_STATE_WITH_MINT_TASK,
mintUrl,
message,
transactionStateUpdates,
completedTransactionIds: [],
errorTransactionIds: [],
revertedTransactionIds: []
return {
taskFunction: SYNC_STATE_WITH_MINT_TASK,
mintUrl,
message,
transactionStateUpdates,
completedTransactionIds: [],
errorTransactionIds: [],
revertedTransactionIds: []
}
}
// 1. Ask mint what it thinks about these proofs
const statesFromMint = await walletStore.getProofsStatesFromMint(
mintUrl,
mint?.units?.[0] ?? 'sat',
proofsToSync
aliveProofs
)
if (mint) mint.setStatus(MintStatus.ONLINE)
@@ -1366,7 +1370,7 @@ const syncStateWithMintTask = async function (
// 1. Proofs now SPENT at mint → transaction succeeded
// ─────────────────────────────────────────────────────────────
if (secrets.spent.size > 0) {
const spentProofs = proofsToSync.filter(p => secrets.spent.has(p.secret))
const spentProofs = aliveProofs.filter(p => secrets.spent.has(p.secret))
const spentByTx = groupByTId(spentProofs)
proofsStore.moveToSpent(spentProofs) // sets isSpent = true, isPending = false + clean if they were in pendingByMintSecrets
@@ -1395,7 +1399,7 @@ const syncStateWithMintTask = async function (
// If we were checking pending proofs, move unspent ones back
if (isPending) {
const stillUnspent = proofsToSync.filter(p => secrets.unspent.has(p.secret))
const stillUnspent = aliveProofs.filter(p => secrets.unspent.has(p.secret))
proofsStore.revertToSpendable(stillUnspent)
}
} else if (tx.status !== TransactionStatus.REVERTED) {
@@ -1454,7 +1458,7 @@ const syncStateWithMintTask = async function (
// 2. Proofs still PENDING at mint → keep pending in wallet
// ─────────────────────────────────────────────────────────────
if (secrets.pending.size > 0) {
const newPendingProofs = proofsToSync.filter(p => secrets.pending.has(p.secret) && !proofsStore.pendingByMintSecrets.includes(p.secret))
const newPendingProofs = aliveProofs.filter(p => secrets.pending.has(p.secret) && !proofsStore.pendingByMintSecrets.includes(p.secret))
if (newPendingProofs.length > 0) {
proofsStore.registerAsPendingAtMint(newPendingProofs)
@@ -1540,7 +1544,7 @@ const syncStateWithMintTask = async function (
return {
taskFunction: SYNC_STATE_WITH_MINT_TASK,
mintUrl,
message: `Sync completed for ${proofsToSync.length} ${isPending ? 'pending ' : ''}proofs`,
message: `Sync completed for ${aliveProofs.length} ${isPending ? 'pending ' : ''}proofs`,
transactionStateUpdates,
completedTransactionIds: completedTxIds,
errorTransactionIds: errorTxIds,