Invalid transactions

The StarkEx gateway performs syntactic checks and context-free validation on each transaction it receives, and returns an error code if the transaction is not valid. In general, StarkEx detects errors as early as possible in the pipeline, but some errors are detected later, when StarkEx performs system checks that depend on the current state.

Whenever an invalid transaction occurs in a batch, it prevents StarkEx from processing the batch. Additionally, any subsequent transactions that depend upon the first become invalid as well.

For example, an invalid deposit to a vault might invalidate a subsequent withdrawal that depends upon the funds in that vault.

Other possible causes of invalid transactions are:

  • Bugs

  • Reorganization of the blockchain

  • An order id is not registered on-chain

  • A fact is not registered on-chain for a conditional transfer

  • The expiration time of a transaction does not allow enough time for the proof to take place

Invalid transactions generally indicate a severe bug in your system, so you should handle each one manually to identify the cause, mitigate the impact on any subsequent transactions, and prevent any issues in the synchronization of your application’s state and StarkEx’s state.

Synchronization problems can be very difficult to solve, and can result in a complete system freeze if not handled in a timely manner.

Validate the following to prevent invalid transactions:

  • On-chain state, including deposits, conditions, and so on, with 6-10 confirmation messages.

  • Balances, currencies and vault ownership.

  • Signatures and their consistency with vault ownership.

  • Expiration timestamps should be at least seven days in the future.

  • Allowed value ranges.

Alternative transactions

When StarkEx identifies an invalid transaction, StarkEx marks the transaction as invalid and sends a request to the application’s endpoint for a list of alternative transactions.

The alternative transactions within the list are processed in order. Neither the list of alternative transactions, nor the individual transactions within the list have ids.

If StarkEx reaches the end of your list of transactions but it hasn’t received enough transactions to send to SHARP, StarkEx pauses and restarts processing the batch.

Built-in safety: REPLACED_BEFORE

StarkEx might restart processing a batch either because it encountered an invalid transaction in the list of alternative transactions that you sent, or for some other reason.

StarkEx includes a safety mechanism to maintain synchronization between your application’s state and StarkEx’s state, as follows:

  1. After you send a list of alternative transactions, StarkEx restarts batch processing.

  2. The batcher processes the id of the transaction that was previously marked as invalid, and automatically identifies that transaction as invalid.

  3. StarkExand sends a REPLACED_BEFORE message, even if the transaction is now valid.

This sequence can potentially occur multiple times.

When you receive a REPLACED_BEFORE message, you must investigate the actual cause of the error.

A REPLACED_BEFORE message doesn’t necessarily indicate a new error. Rather, it might indicate that after you sent the alternative transaction list, StarkEx was unable to create a batch for an unrelated reason. Even so, after restarting the batch, StarkEx again encountered the transaction that you replaced and automatically identified that transaction as invalid.

In such a case, after you ensure there are no errors, you can resend the same list of alternative transactions.

´╗┐Example: Invalid transaction and an alternative transaction list

The following example shows an error message for an invalid transaction. In response to this error, you need to send an list of one or more alternative transactions.

In this example the balance is known to be valid, but it does not yet appear on-chain.

{
    "reason_code": "INSUFFICIENT_ONCHAIN_BALANCE",
    "tx_id": 7,
    "reason_msg": "Not enough onchain balance to complete deposit. balance_used:10 onchain_balance:0 deposit: DepositRequest(vault_id=1, stark_key=2, token_id=3, amount=10)",
    "tx": {
        "stark_key": "0x2",
        "token_id": "0x3",
        "amount": "10",
        "vault_id": 1,
        "type": "DepositRequest"
    }
}

The following example shows a response with a list of one alternative transaction. In this case, it is the same transaction sent initially, assuming that the on-chain balance has been updated since receiving the error message:

{
    "alt_txs": [
        {
            "stark_key": "0x2",
            "token_id": "0x3",
            "amount": "10",
            "vault_id": 1,
            "type": "DepositRequest"
        }
    ]
}