The TS updates the DB so that it reflects a state that is ahead of what the state would look like if it was only based on finalized transactions. This is a similar problem to what Bitcoin or Ethereum encounters when there is a block reorganization due to a swap in forks. Ethereum handles block reorganizations by effectively snapshotting the current state after each block (see https://blog.ethereum.org/2015/06/26/state-tree-pruning/ for optimizations). Thus if a fork is started from a previous block, an Ethereum node will revert back to a snapshot of that previous block's post-state and then apply transactions starting from there. We can follow a similar approach in Rchain: essentially the TS will be responsible for applying transactions but not reverting them.
Example of a double race condition
Assume produces and consumes are sent in the following order.
4) for (_ <- x; _ <- y; _ <- z) P // Underscore means any pattern (wildcard pattern)
5) for (_ <- x; _ <- y) P
This creates a race in which Line 6 can match with either Line 4 or Line 5. When either Line 4 or Line 5 reduce, there is another race between Line 1 and Line 2.
Related code snippets