# Verax

## Data model

Verax's data model is heavily inspired by Bitcoin's unspent transaction output
(UTXO) model. It is a data where transactions are a set of `payments` that are
spent, and a set of new `payments` to be created.

Each `payment` is a data structure with this information

```
struct Payment {
    created_by_transaction: TxId,
    amount: Amount,
    destination: Address,
    spend_by: Option<TxId>
}
```

Any `payment` that has `spend_by: None` is part of the active balance of each
address. Any other payment is not longer part of the active balance, but part of
the historial record. These spent payments are read-only from that point
forward.

Every `payment` is created from a transaction, no exception.

### Transactions

```mermaid
flowchart LR
    UserA --> |1000 USD| B{Transfer}
    B --> |1000 USD| UserB
```

After this simple transction, `UserA` cannot longer spend their `1000 USD` and
balance, and `UserB` can spend `1000 USD` more.

This data model does not care how many payments are being spend or created, as
long as the amounts are the same on both ends.

In the following example UserA transfer `1000 USD` to `UserB`, but `1 USD` is
deducted from the transfer by the system and that is being transfer to the
`FeeManager` account.

```mermaid
flowchart LR
    UserA --> |1000 USD| B{Transfer}
    B --> |999 USD| UserB
    B --> |1 USD| FeeManager
```

### Multi-step transactions

As mentioned before, the transaction can spend multiple payments and can create
multiple as well. As long as the amounts are equal on both ends (in this case
`1000 USD, 980 EUR` is equal to `999USD + 1 USD, 979EUR + 1EUR`), the
transaction will be valid.

```mermaid
flowchart LR
    UserA' --> |1000 USD| B{Transfer}
    UserB' --> |980 EUR| B
    B --> |999 USD| UserB
    B --> |979 EUR| UserA
    B --> |1 USD| FeeManager
    B --> |1 EUR| FeeManager
```

When the transaction will be attempted to be persisted, the storage layer will
make sure to flag `UserA'` and `UserB'` payments. If that operation fails, the
whole transaction creation fails.

## Concurrency model

Because Verax is heavily inspired in Bitcoin's model, the concurrency model is
quite simple. When a new transaction is commited into the database, each payment
in `input` section is attempted to be spent (altering their `spend_by` field
from `None` to `Some(new_transaction_id)`). If any `payment is already spent, or
not valid, the whole transaction creation fails and a rollback is issued upper
stream. The storage layer ensures that transaction creation and updates are
atomic and updates.

```mermaid
sequenceDiagram
    Transaction ->>+ DB:s
    critical Spend each input
        loop Spend Inputs
            Transaction ->>+ DB: Spend input
            DB ->>+ Transaction: OK
        end
        DB ->>+  Transaction: OK
        loop Output
            Transaction ->>+ DB: Creates new output
        end
    option Success
        Transaction ->>+ DB: Commit
        DB ->>+  Transaction: OK
    option Failure
        DB ->>- Transaction: Error
        Transaction ->>+ DB: Rollback
    end


```

Because of the `input` and `output` model, there is no need to check if the
account has enough balance, and there is no need to enforce any locking
mechanism, as long as each selected `payment` can be spendable at transaction
storing time, the transaction will be created atomically. Each payment in the
`inputs` must spendable, or else the whole operation fails, because every update
is atomic, ensured by the storage layer.

The conditions for a payment ot be spendable are:

- It must be unspent: Payments are spendable once.
- It must be finalized: This means that the transaction which created this new
  `payment` is settled. Any other state is not acceptable and will render this

No global state knowledge is required to be sure that no asset is being created
or destroyed by mistake, as long as the inputs are spendable and the sum of
amounts inside inputs and outputs matches.