How are the trades ordered before the ledger closes?

Looking from a "high frequency trading" perspective, is it possible to execute some attacks like front running on Stellar? If my node receives a trade, can I outrun it by submitting my trade faster to other nodes?

2 Answers 2


Taking a look at this with the assumption that the attacker controls some validators (as it makes it easier to exploit).

So the way the network deals with transaction ordering is by making it as hard as it can to make it look random:

  • the apply order sorts by account id xored with the hash of the transaction set
  • the nomination protocol that gathers candidate values (transaction sets) from validators, uses the highest value as tie breaker, using the hash order - the hash order is the hash of transactions mixed with the hash of the previous ledger.

As the apply order and hash order are independent, an attacker would have to control a number of trusted validators to inject their desired transaction sets, and would have to produce a transaction set that produces both a high value for the next ledger and a good apply order before nomination starts.

It's not crypto-hard to defeat but is gets a lot harder if trying to front load more and more transactions. In addition to that, as SCP messages are recorded in history, such bad validators would have a permanent record of questionable behavior and would probably get removed by other people on the network.

Note: without controlling validators, the chance of success are probably extremely small as different validators produce different transaction sets (with different hashes) on top of the problems mentioned before.


I asked the same question earlier.

Jed mentioned that trades are applied in random (actually, pseudo-random) order, and transaction fees do not affect the order in which transactions are applied within the ledger. So larger fees do not prioritize trading operations, preventing Low Latency HFT manipulations.

(Detailed explanation of the tx randomization process)

From /src/ledger/readme.md:

First the transaction set is reordered in apply order: during consensus, the transaction set was sorted by hash to keep things simple, but when it comes to actually applying them, they need to be sorted such that transactions for a given account are applied in sequence number order and also randomized enough so that it becomes unfeasible to submit a transaction and guarantee that it will be executed before or after another transaction in the set. See TxSetFrame::sortForApply for more detail.

Therefore once the SCP quorum agreed on what transactions are ready for the application in the current frame, all transactions are first ordered by the sequence numbers (to prevent applying transactions in the wrong order), and then randomized based of the seed derived from the hash of the particular transaction XORed with the hash of the entire tx set (see ApplyTxSorter).

One can predict the transactions application order only if she knows in advance the contents (or at least hashes) of all submitted transactions. While it is theoretically possible to monitor all transactions (in the simplest case the attacker may submit all transactions by himself), the information is effectively useless, as any new transaction submitted after the transactions frame was assembled, will be included into the next ledger. However, the tx application order and current ledger state will be publicly available only a few seconds later anyway, so the attacker has no competitive advantage in this case.

  • 1
    If the validators know how to calculate this randomness, I should be able to do the same. In this case I can just generate a bunch of transactions until the final pseudo-random state suites me. I will read a bit through the stellar-core code just to try to understand it completely.
    – bkolobara
    Aug 7, 2018 at 15:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.