Summary
Client.getTransaction() can return:
{
"state": "confirmed",
"executionResult": false
}
This was unexpected. TransactionState includes several possible outcomes:
type TransactionState =
| "new"
| "pending"
| "included"
| "confirmed"
| "invalidated"
| "expired"
With states such as invalidated and expired in the same type, it is easy to assume that confirmed means the transaction executed successfully. In this case, it means the transaction was included and finalized, while executionResult describes whether execution succeeded.
Reproduction
-
Connect an @nimiq/core client to testalbatross.
-
Fetch this transaction:
1beefbc55f2cc8b5c9e4dc9edd4e32ec28b587dbd31c36a74344c9124450ab9f
-
Inspect the returned transaction:
await client.getTransaction(hash)
It returns state: "confirmed" together with executionResult: false.
Documentation
The code documents confirmed as meaning that a transaction was included and finalized, but does not mention that a confirmed transaction may have executionResult: false.
executionResult is optional, and I could not find documentation explaining how it relates to state, when consumers need to check it, or whether it is always available for included transactions.
I also could not find this behavior documented in the Nimiq Developer Center.
Impact
Consumers relying on state as the final transaction outcome may display a failed transaction as confirmed. This happened in Nimiq Pay because it read state without also checking executionResult.
Summary
Client.getTransaction()can return:{ "state": "confirmed", "executionResult": false }This was unexpected.
TransactionStateincludes several possible outcomes:With states such as
invalidatedandexpiredin the same type, it is easy to assume thatconfirmedmeans the transaction executed successfully. In this case, it means the transaction was included and finalized, whileexecutionResultdescribes whether execution succeeded.Reproduction
Connect an
@nimiq/coreclient totestalbatross.Fetch this transaction:
1beefbc55f2cc8b5c9e4dc9edd4e32ec28b587dbd31c36a74344c9124450ab9fInspect the returned transaction:
It returns
state: "confirmed"together withexecutionResult: false.Documentation
The code documents
confirmedas meaning that a transaction was included and finalized, but does not mention that a confirmed transaction may haveexecutionResult: false.executionResultis optional, and I could not find documentation explaining how it relates tostate, when consumers need to check it, or whether it is always available for included transactions.I also could not find this behavior documented in the Nimiq Developer Center.
Impact
Consumers relying on
stateas the final transaction outcome may display a failed transaction as confirmed. This happened in Nimiq Pay because it readstatewithout also checkingexecutionResult.