I think we usually ask the wrong question when a Dusk transaction “fails”.
A 202 Accepted only means the node accepted the request for routing. It does not mean the transaction is already in the mempool or in a block. One example I found interesting is a future nonce. If a Moonlight transaction arrives with a future nonce while an earlier nonce is still missing, Dusk can keep it outside the real mempool and wait for the nonce gap to close instead of rejecting it immediately. It gets a deferred state while that happens.
That is only one part of the story. Once a transaction passes admission, it enters that node’s local mempool. Other nodes keep their own mempools and run their own admission checks too. Later, a transaction can be selected for a block, executed, and eventually finalized. It can also leave the local mempool without that automatically meaning it failed. Expiry, replacement, capacity limits and conflicts can all lead to removal.
This is where I think the difference matters for wallets and exchanges. Dusk’s own integration guidance says to keep the exact signed transaction, treat 202 Accepted only as successful routing, and rebroadcast the same signed bytes after a transport timeout instead of creating a new transaction blindly. A withdrawal should only be marked complete after execution is checked and the block is finalized.
The more I looked at it, the less “transaction submitted” sounded like a useful status on its own. A transaction can be waiting for a nonce, sitting in one node’s mempool, executed with an error, or sitting in a block that is not final yet. Those are very different situations, even though they can all look like “it’s still pending” from the outside.
For me, that is the useful takeaway from Dusk’s transaction flow: submitted is only the beginning. What matters is the state you can actually prove the transaction reached.
$DUSK @Dusk #dusk
A 202 Accepted only means the node accepted the request for routing. It does not mean the transaction is already in the mempool or in a block. One example I found interesting is a future nonce. If a Moonlight transaction arrives with a future nonce while an earlier nonce is still missing, Dusk can keep it outside the real mempool and wait for the nonce gap to close instead of rejecting it immediately. It gets a deferred state while that happens.
That is only one part of the story. Once a transaction passes admission, it enters that node’s local mempool. Other nodes keep their own mempools and run their own admission checks too. Later, a transaction can be selected for a block, executed, and eventually finalized. It can also leave the local mempool without that automatically meaning it failed. Expiry, replacement, capacity limits and conflicts can all lead to removal.
This is where I think the difference matters for wallets and exchanges. Dusk’s own integration guidance says to keep the exact signed transaction, treat 202 Accepted only as successful routing, and rebroadcast the same signed bytes after a transport timeout instead of creating a new transaction blindly. A withdrawal should only be marked complete after execution is checked and the block is finalized.
The more I looked at it, the less “transaction submitted” sounded like a useful status on its own. A transaction can be waiting for a nonce, sitting in one node’s mempool, executed with an error, or sitting in a block that is not final yet. Those are very different situations, even though they can all look like “it’s still pending” from the outside.
For me, that is the useful takeaway from Dusk’s transaction flow: submitted is only the beginning. What matters is the state you can actually prove the transaction reached.
$DUSK @Dusk #dusk
