Skip to content

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 keep in mind.

While this can work, there is cautions to take when using this approach.

Submission and Processing

When submitting a transaction, it may fail either during submission or during processing.

ts
const transactionRequest = await wallet.createTransfer(
  recipient.address,
  transferAmount,
  baseAssetId
);

const response = await wallet.sendTransaction(transactionRequest);
See code in context

The sendTransaction method resolves without an error as soon as the transaction is 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 ensure that the transaction has been processed, you need to call waitForResult. This method will resolve (or reject with an error) only when the transaction has been fully processed.

ts
const result = await response.waitForResult();
See code in context

In other words, if sendTransaction rejects with an error, it means that the transaction was not accepted by the network and was not processed. On the other hand, if the transaction fails during the call to waitForResult, it means that the transaction was accepted but was 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. The remaining funds, after deducting the gas cost, 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 resources that were initially spent no longer exist.

ts
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 successufully 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);
  }
}
See code in context

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 transaction request from scratch and then resubmit it.

ts
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);
  }
}
See code in context