I am currently trying to specify the Tuplespace (TS) so that it cleanly interfaces with Casper. This is an ongoing conversation with Michael Birch.

Here is the planned pseudocode for the TS implementation

```
produce data
case no matching continuation
store data
log data
case partially matching continuation
store data
log data
case fully matching continuation
consume match
log match

consume continuation
case no matching data
store continuation
log continuation
case partially matching data
store continuation
log continuation
case fully matching data
consume match
log match
```

Casper will then read the log output of the TS and use that to make proposals in the consensus protocol.

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.

1) x!"foo"
2) x!"bar"
3) z!"baz"
4) for (_ <- x; _ <- y; _ <- z) P // Underscore means any pattern (wildcard pattern)
5) for (_ <- x; _ <- y) P

6) y!"bing"

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

def consume(ctxt_tuple: Tuple2[Continuation, Tuple2[Code, Any]], location: Tuple3[List[Channel], List[Pattern], Persistent]): Tuple2[Continuation, List[Product]]


type Candidate = Tuple2[Tuple2[Int, Channel], Tuple2[Int, Data]]
List[List[Candidate]]


def select_match(candidates: List[List[Candidate]]): List[Candidate] = {

}