-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: handling UTXO error in transaction re-submissions (#3050)
- Loading branch information
1 parent
a36626a
commit 2ffaaf7
Showing
3 changed files
with
147 additions
and
0 deletions.
There are no files selected for viewing
105 changes: 105 additions & 0 deletions
105
apps/docs-snippets/src/guide/cookbook/resubmitting-failed-transactions.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import { bn, type FuelError } from 'fuels'; | ||
import { launchTestNode } from 'fuels/test-utils'; | ||
|
||
/** | ||
* @group node | ||
* @group browser | ||
*/ | ||
describe('Resubmitting Failed Transactions', () => { | ||
it('should submit transaction just fine', async () => { | ||
const { | ||
provider, | ||
wallets: [wallet, recipient], | ||
} = await launchTestNode({ | ||
walletsConfig: { | ||
count: 2, | ||
}, | ||
}); | ||
const baseAssetId = provider.getBaseAssetId(); | ||
|
||
const transferAmount = 1000; | ||
|
||
// #region resubmitting-failed-transactions-1 | ||
const transactionRequest = await wallet.createTransfer( | ||
recipient.address, | ||
transferAmount, | ||
baseAssetId | ||
); | ||
|
||
const response = await wallet.sendTransaction(transactionRequest); | ||
// #endregion resubmitting-failed-transactions-1 | ||
|
||
// #region resubmitting-failed-transactions-2 | ||
const result = await response.waitForResult(); | ||
// #endregion resubmitting-failed-transactions-2 | ||
|
||
expect(result.isStatusSuccess).toBeTruthy(); | ||
}); | ||
|
||
it('should try to re-submit the transaction', async () => { | ||
const { | ||
provider, | ||
wallets: [wallet, recipient], | ||
} = await launchTestNode({ | ||
walletsConfig: { | ||
count: 2, | ||
}, | ||
}); | ||
const baseAssetId = provider.getBaseAssetId(); | ||
const transferAmount = 1000; | ||
|
||
await expect(async () => { | ||
// #region resubmitting-failed-transactions-3 | ||
const transactionRequest = await wallet.createTransfer( | ||
recipient.address, | ||
transferAmount, | ||
baseAssetId | ||
); | ||
|
||
// Set the gasLimit to 0 to force revert with OutOfGas error | ||
transactionRequest.gasLimit = bn(0); | ||
|
||
// Transaction will be successfully submitted | ||
const response = await wallet.sendTransaction(transactionRequest); | ||
try { | ||
await response.waitForResult(); | ||
} catch (error) { | ||
if (/OutOfGas/.test((<FuelError>error).message)) { | ||
transactionRequest.gasLimit = bn(1000); | ||
// Re-submission will fail | ||
await wallet.sendTransaction(transactionRequest); | ||
} | ||
} | ||
// #endregion resubmitting-failed-transactions-3 | ||
}).rejects.toThrow('Transaction is not inserted. UTXO does not exist: 0x'); | ||
|
||
await expect( | ||
(async () => { | ||
const transactionRequest = await wallet.createTransfer( | ||
recipient.address, | ||
transferAmount, | ||
baseAssetId | ||
); | ||
|
||
transactionRequest.gasLimit = bn(0); | ||
|
||
const response = await wallet.sendTransaction(transactionRequest); | ||
// #region resubmitting-failed-transactions-4 | ||
try { | ||
await response.waitForResult(); | ||
} catch (error) { | ||
if (/OutOfGas/.test((<FuelError>error).message)) { | ||
const transactionRequest2 = await wallet.createTransfer( | ||
recipient.address, | ||
transferAmount, | ||
baseAssetId | ||
); | ||
|
||
await wallet.sendTransaction(transactionRequest2); | ||
} | ||
} | ||
// #endregion resubmitting-failed-transactions-4 | ||
})() | ||
).resolves.not.toThrow(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
apps/docs/src/guide/cookbook/resubmitting-failed-transactions.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Resubmitting Failed Transactions | ||
|
||
In certain scenarios, you might need to implement a solution to resubmit failed transactions to the Fuel Network. While this approach can be effective, there are important considerations to remember. | ||
|
||
|
||
## Submission and Processing | ||
|
||
When submitting a transaction, you will first get a response. | ||
|
||
<<< @/../../docs-snippets/src/guide/cookbook/resubmitting-failed-transactions.test.ts#resubmitting-failed-transactions-1{ts:line-numbers} | ||
|
||
If the `sendTransaction` method resolves without an error, we know that the transaction was successfully submitted and accepted by the network. However, this does not guarantee that the transaction has been processed; it only indicates that the transaction has been accepted and placed in a queue for processing. | ||
|
||
To determine whether the transaction has been processed, you must call `waitForResult`, which will either resolve (with the processed transaction) or reject with an error. | ||
|
||
<<< @/../../docs-snippets/src/guide/cookbook/resubmitting-failed-transactions.test.ts#resubmitting-failed-transactions-2{ts:line-numbers} | ||
|
||
In other words: | ||
- If `sendTransaction` is rejected with an error, the transaction was not accepted by the network and is not processed. | ||
- If `waitForResult` is rejected with an error, the transaction was accepted but reverted during processing. | ||
|
||
## Resources Spent When a Transaction Is Processed | ||
|
||
If a transaction is reverted during processing, the Fuel VM will still consume the funded resources to cover the gas used up to the point of failure. After deducting the gas cost, the remaining funds will be added to a new UTXO (Unspent Transaction Output) addressed to the owner. | ||
|
||
Attempting to resubmit the same transaction request that failed during processing will likely result in an error, as the initially spent resources no longer exist. | ||
|
||
<<< @/../../docs-snippets/src/guide/cookbook/resubmitting-failed-transactions.test.ts#resubmitting-failed-transactions-3{ts:line-numbers} | ||
|
||
The attempt from the above snippet will result in the error: | ||
|
||
```console | ||
FuelError: Transaction is not inserted. UTXO does not exist: {{utxoId}} | ||
``` | ||
|
||
To safely retry a transaction that failed during processing, you should reassemble the request from scratch and resubmit it. | ||
|
||
<<< @/../../docs-snippets/src/guide/cookbook/resubmitting-failed-transactions.test.ts#resubmitting-failed-transactions-4{ts:line-numbers} |