Skip to content

Commit c3b6be4

Browse files
authored
Merge pull request #869 from input-output-hk/fix/resubmission-broken-by-861
fix(wallet): do not prevent re-submission
2 parents ab2265a + 63ce773 commit c3b6be4

File tree

2 files changed

+34
-11
lines changed

2 files changed

+34
-11
lines changed

packages/wallet/src/PersonalWallet/PersonalWallet.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -598,10 +598,12 @@ export class PersonalWallet implements ObservableWallet {
598598
return this.#submittingPromises[outgoingTx.id]!;
599599
}
600600
return (this.#submittingPromises[outgoingTx.id] = (async () => {
601-
const inFlightTxs = await firstValueFrom(this.transactions.outgoing.inFlight$);
602-
const inFlightTx = inFlightTxs.find((inFlight) => inFlight.id === outgoingTx.id);
603601
try {
604-
if (!inFlightTx) {
602+
// Submit to provider only if it's either:
603+
// - an internal re-submission. External re-submissions are ignored,
604+
// because PersonalWallet takes care of it internally.
605+
// - is a new submission
606+
if (options.mightBeAlreadySubmitted || !(await this.#isTxInFlight(outgoingTx.id))) {
605607
await this.#submitTx(outgoingTx, options);
606608
}
607609
} finally {
@@ -684,6 +686,11 @@ export class PersonalWallet implements ObservableWallet {
684686
};
685687
}
686688

689+
async #isTxInFlight(txId: Cardano.TransactionId) {
690+
const inFlightTxs = await firstValueFrom(this.transactions.outgoing.inFlight$);
691+
return inFlightTxs.some((inFlight) => inFlight.id === txId);
692+
}
693+
687694
#firstValueFromSettled<T>(o$: Observable<T>): Promise<T> {
688695
return firstValueFrom(
689696
this.syncStatus.isSettled$.pipe(

packages/wallet/test/PersonalWallet/methods.test.ts

+24-8
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,13 @@ describe('PersonalWallet methods', () => {
367367
});
368368

369369
describe('submitTx', () => {
370+
const valueNotConservedError = new ProviderError(
371+
ProviderFailure.BadRequest,
372+
new CardanoNodeErrors.TxSubmissionErrors.ValueNotConservedError({
373+
valueNotConserved: { consumed: 2, produced: 1 }
374+
})
375+
);
376+
370377
it('resolves on success', async () => {
371378
const tx = await wallet.finalizeTx({ tx: await wallet.initializeTx(props) });
372379
const outgoingTx = toOutgoingTx(tx);
@@ -442,14 +449,9 @@ describe('PersonalWallet methods', () => {
442449
});
443450

444451
it('mightBeAlreadySubmitted option interprets ValueNotConservedError as success', async () => {
445-
txSubmitProvider.submitTx.mockRejectedValueOnce(
446-
new ProviderError(
447-
ProviderFailure.BadRequest,
448-
new CardanoNodeErrors.TxSubmissionErrors.ValueNotConservedError({
449-
valueNotConserved: { consumed: 2, produced: 1 }
450-
})
451-
)
452-
);
452+
txSubmitProvider.submitTx
453+
.mockRejectedValueOnce(valueNotConservedError)
454+
.mockRejectedValueOnce(valueNotConservedError);
453455
const tx = await wallet.finalizeTx({ tx: await wallet.initializeTx(props) });
454456
const outgoingTx = toOutgoingTx(tx);
455457

@@ -462,6 +464,20 @@ describe('PersonalWallet methods', () => {
462464
expect(await txPending).toEqual(outgoingTx);
463465
});
464466

467+
it('attempts to resubmit the tx that is already in flight', async () => {
468+
const tx = await wallet.finalizeTx({ tx: await wallet.initializeTx(props) });
469+
470+
await wallet.submitTx(tx);
471+
expect(await firstValueFrom(wallet.transactions.outgoing.inFlight$)).toHaveLength(1);
472+
473+
// resubmit the same tx while it's 'in flight'
474+
txSubmitProvider.submitTx.mockRejectedValueOnce(valueNotConservedError);
475+
await wallet.submitTx(tx, { mightBeAlreadySubmitted: true });
476+
477+
expect(await firstValueFrom(wallet.transactions.outgoing.inFlight$)).toHaveLength(1);
478+
expect(txSubmitProvider.submitTx).toBeCalledTimes(2);
479+
});
480+
465481
it('resolves on success when submitting a tx when sending coins to a handle', async () => {
466482
const txBuilder = wallet.createTxBuilder();
467483
const txOutput = await txBuilder.buildOutput().handle('alice').coin(1_000_000n).build();

0 commit comments

Comments
 (0)