# On-chain

Operating a state channel requires, an initial on-chain setup via a`channel_create_tx` transaction, that locks up a configurable amount of coins from\
each involved party in the channel. This requires a consent, in the form of\
either signatures or generalized account authentication call data, from both\
participants. More information regarding authentication can be found[here](https://docs.aeternity.com/developer-documentation/protocol/channels/authentication)

In the ideal case, all on-chain transactions get authenticated by both\
participants, implying that there are no disagreements. These operations can\
be committed immediately. There are also some unilateral transactions that\
need to be authenticated just by one of the participants. Those might have a\
block height timer attached to them for the other party to dispute. The mutually\
agreed ones will override all conflicting unilateral actions.

Transactions not authenticated by everyone can be disputed via`channel_slash_tx`, `channel_snapshot_solo_tx` and `channel_force_progress_tx`\
transactions. During normal operation, these solo transactions can be disputed\
indefinitely. If the channel is in the closing state, disputes have to happen\
within the pre-negotiated `lock_period`, given that closure requires a bounded\
finality.

Each channel transaction updating on-chain state provides two fields essential\
for future conflict resolution: `round` and `state_hash`. The state hash is\
the root hash of the channel's state tree after the on-chain has been applied\
to the local state tree. The `round` is the state channel's internal round.\
Since the `round` is incrementing on every off-chain state change, the channel\
transaction both represents the off-chain state of the channel and defines the\
point of time when it was valid. This allows us to make educated decisions on\
whether or not to update the on-chain persisted channel object. This way we\
can solo close a channel according to the last provided on-chain state. All we\
have to do is to provide a proof of inclusion having the same `state_hash`.

* [Establishing a channel](#establishing-a-channel)
  * [`channel_create`](#channel_create)
* [Updating a channel](#updating-a-channel)
  * [`channel_deposit`](#channel_deposit)
  * [`channel_withdraw`](#channel_withdraw)
  * [`channel_snapshot_solo`](#channel_snapshot_solo)
  * [`channel_set_delegates`](#channel_set_delegates)
* [Closing a channel](#closing-a-channel)
  * [`channel_close_mutual`](#channel_close_mutual)
  * [`channel_close_solo`](#channel_close_solo)
  * [`channel_settle`](#channel_settle)
* [Disputing updates](#disputing-updates)
  * [`channel_slash`](#channel_slash)
* [Forcing progress](#forcing-progress)
  * [`channel_force_progress_tx`](#channel_force_progress_tx)
* [Channel state tree](#channel-state-tree)

## Establishing a channel

All of the on-chain operations could be submitted by any peer but we assume that\
the initiating peer pays for the setup of the channel. Therefore the `initiator`\
MUST pay the `channel_create_tx` transaction fees.

### `channel_create`

The `channel_create_tx` transaction is used to register a channel on-chain and its\
inclusion on-chain causes the specified amounts to be locked up as a guarantee\
that participants have a vested interest in the channel. Although it is not a\
strict requirement, it is strongly suggested to do so.

e.g.

```
Account(initiator).balance := Account(initiator).balance - initiator_amount

Account(responder).balance := Account(responder).balance - responder_amount

Channel(cid).amount := initiator_amount + responder_amount
```

Serialization defined [here](https://docs.aeternity.com/developer-documentation/serializations#channel-create-transaction)

* `initiator_id`: account id of the initiating peer
* `responder_id`: account id of the responding peer
* `initiator_amount`: unsigned amount of coins the initiator commits to the\
  channel
* `responder_amount`: unsigned amount of coins the responder commits to the\
  channel
* `lock_period`: period for disputes after solo operations
* `delegate_ids`, `initiator_delegate_ids` and `responder_delegate_ids`: lists\
  of delegate account ids. The delegates play a role in the solo closing\
  sequence: except for the participants of the channel, they are the only ones\
  that can provide a snapshot, slash or forced progress transactions. Pre`iris` there is only a single list of delegates and from `iris` on those are\
  fine grained on a participant level
* `state_hash`: the root hash of the channel state tree; This is not validated,\
  just kept in the channel's object as initial value. This come into play if\
  participants enter a dispute right after opening the channel on-chain.
* `ttl`: blockheight target until which this transaction can be included
* `fee`: transaction fee
* `nonce`: `initiator`'s account nonce or 0 if one is a generalized account

The length of the `lock_period` is a trade-off between responsiveness, e.g. how\
fast solo operations can be committed, and security. Choosing a `lock_period`\
that gives participants enough time to react to potential malicious solo\
operations is crucial.

The `ttl` is in absolute chain height. The involved parties will want to set the`ttl` to a value quite a bit larger than the present chain height, to avoid\
uncertainty. If the fees included are low and transaction pressure is high, then\
the transaction might end up being stuck in the mempool for an extended period.`ttl` is optional, no `ttl` means a transaction that is valid "forever".

The `fee` and `nonce` refer to the `initiator` account, i.e. the `fee` MUST be\
taken from their balance and the `nonce` of their account MUST be incremented.

#### Generalized accounts

If either of the participants is a [Generalized\
account](https://docs.aeternity.com/developer-documentation/protocol/generalized_accounts) the channel create\
will also create an extra entry in the contract state tree, containing a frozen\
authentication state that will be used for off-chain authentication and\
verification in off-chain updates (potentially eventually enforced on-chain)\
of this particular channel. A more detailed explanation can be found[here](https://docs.aeternity.com/developer-documentation/protocol/channels/authentication)

#### Requirements

`Account(initiator).balance >= initiator_amount + fee`

`Account(responder).balance >= responder_amount`

`initiator_amount >= channel_reserve`

`responder_amount >= channel_reserve`

## Updating a channel

An update to an open channel requires the authentication of all participants\
and a channel identification (`channel_id`).

Both `channel_deposit_tx` and `channel_withdraw_tx` MUST be authenticated by\
all involved parties, since changing channel balances might change the\
dynamics of code running in a channel.

The `channel_id` is computed from the public key of the initiator, the nonce of\
the create transaction and the public key of the responder using Blake2b (256\
bits digest).

```
channel_id = Blake2b(initiator || channel_create_tx_nonce || responder)
                        32                  32                  32
```

### `channel_deposit`

Depositing funds into a channel after its creation provides the means for a\
participant to move coins from the participant's balance to the channel's one.\
This should allow channels to be more long-lived due to the increased ease of\
balancing them out. The amount of coins sent along with this transaction will\
get locked up just like the initial deposit.

While it could be desirable to allow anyone to deposit into a channel, we are\
going to restrict deposits to the peers of a channel. That means, the `from_id`\
field MUST be an address of one of the participants of the targeted channel and\
the standard transaction fee MUST be paid by the `from_id` account.

This operation is not mandatory for normal channel operation.

Serialization defined [here](https://docs.aeternity.com/developer-documentation/serializations#channel-deposit-transaction)

* `channel_id`: channel id as recorded on-chain
* `from_id`: sender of the deposit
* `amount`: amount of coins deposited
* `state_hash`: the root hash of the channel state tree after the deposit has\
  been applied to it; This is not validated on-chain, just kept in the\
  channel's object
* `round`: the channel's internal round that applies the deposit
* `ttl`: blockheight target until which this transaction can be included
* `fee`: transaction fee
* `nonce`: `from_id`'s account nonce

Note that the `round` SHOULD be incremented on each off-chain update. This\
means, in order for an on-chain transaction, referring to off-chain state, to\
be considered valid, it MUST include a `round` higher than the currently\
recorded `Channel(channel_id).round`.

If this transaction is valid then it sets:

* `Channel(channel_id).round := round`
* `Channel(channel_id).solo_round := 0`
* `Channel(channel_id).state_hash := state_hash`
* `Channel(channel_id).total_amount := Channel(channel_id).total_amount + amount`

### `channel_withdraw`

Channels should generally not be used to hold significant amounts of coins but\
being able to withdraw locked coins might still be of use.

Serialization defined [here](https://docs.aeternity.com/developer-documentation/serializations#channel-withdraw-transaction)

* `channel_id`: channel id as recorded on-chain
* `to`: receiver of the withdraw
* `amount`: amount of coins withdrawn
* `state_hash`: the root hash of the channel state tree after the withdraw had\
  been applied; This is not validated, just kept in the channel's object
* `round`: the channel's internal round that applies the withdraw
* `ttl`: blockheight target until which this transaction can be included
* `fee`: transaction fee
* `nonce`: `to`'s account nonce

The `to` account MUST be a participant in the target channel. The `amount`\
MUST be less than or equal to the sum of the channel balance with regard to the`channel_reserve` amounts, i.e. channels cannot create coins out of thin air\
but also a minimum of `channel_reserve` must remain locked in the channel. The\
fee is paid by the `to` account and that account should hold enough coins to\
pay the fee, i.e., the fee is subtracted before the withdrawn coins arrive.

Note that the `round` SHOULD be incremented on each off-chain update. This\
means, in order for an on-chain transaction, referring to off-chain state, to\
be considered valid, it MUST include a `round` higher than or equal to the\
currently recorded `Channel(channel_id).round`.

If this transaction is valid then it sets:

* `Channel(channel_id).round := round`
* `Channel(channel_id).solo_round := 0`
* `Channel(channel_id).state_hash := state_hash`
* `Channel(channel_id).total_amount := Channel(channel_id).total_amount - amount`

### `channel_snapshot_solo`

In order to make channels both secure and trustless even when one party goes\
offline, we provide the functionality of snapshots.\
Snapshots provide a recent off-chain state to be recorded on-chain. This state\
is represented by a `round` and a `state_hash`. Those are proven to be correct\
at least at some point of time in the past by providing a co-authenticated\
off-chain update as a `payload`. Note that the `payload` can not be an\
on-chain transaction.\
After `channel_snapshot_solo_tx` inclusion the channel can not be closed using an\
older state—as indicated by the `round`—than the one provided in the snapshot.

Serialization defined [here](https://docs.aeternity.com/developer-documentation/serializations#channel-snapshot-solo-transaction)

* `channel_id`: channel id as recorded on-chain
* `from_id`: the account that posts the transaction
* `payload`: an off-chain transaction of the same channel authenticated\
  by both parties
* `ttl`: blockheight target until which this transaction can be included
* `fee`: transaction fee
* `nonce`: the `from_id` account nonce

The `from_id` account MUST be a participant or a delegate in the target\
channel. The `payload` MUST be an off-chain state. It MUST provide correct\
authentication methods for both parties. It MUST be part of the same channel\
(containing same channel id) and it MUST have a `round` higher than the one\
currently recorded on-chain.

This transaction MUST NOT trigger the `lock_period` and MUST NOT be used when\
the channel is in the closing state. It can be used to overwrite a state produced\
by a `channel_force_progress_tx` while the channel is in the open state.

If this transaction is valid then it sets:

* `Channel(channel_id).round := payload.round`
* `Channel(channel_id).solo_round := 0`
* `Channel(channel_id).state_hash := payload.state_hash`

### `channel_set_delegates`

In order to make channels both secure and trustless even when one party goes\
offline, a participant can delegate the right to produce certain transactions\
to other third parties.\
Delegates are set initially in the `channel_create_tx` and, since the `iris`\
hardfork, can be updated with `channel_set_delegates_tx`. It acts similarly to`channel_snapshot_solo_tx` with three notable differences:

* While `channel_snapshot_solo_tx` can be based only on off-chain state,`channel_set_delegates_tx` can be based both on off-chain state or latest\
  on-chain state. In the latter case the `payload` provided is empty.
* `channel_set_delegates_tx` is mutually agreed upon. If the other participant\
  does not want to approve such a transaction, this could be a clear sign that\
  the assumption of cooperation is broken.
* `channel_set_delegates_tx` not only updates the on-chain channel object\
  but also sets the list of delegate ids for each participant. The old lists of\
  delegates are deleted and the new ones provided by the transaction replace\
  them. There is no option for setting the list just for one participant.

Serialization defined [here](https://docs.aeternity.com/developer-documentation/serializations#channel-set-delegates-transaction)

* `channel_id`: channel id as recorded on-chain
* `from_id`: the account that posts the transaction
* `initiator_delegate_ids`: the list of delegates that can provide\
  transactions on behalf of the `initiator`
* `responder_delegate_ids`: the list of delegates that can provide\
  transactions on behalf of the `responder`
* `payload`: an off-chain transaction of the same channel authenticated\
  by both parties. It could be empty
* `state_hash`: the hash of the payload, if provided - and if not, the latest\
  provided on-chain `state_hash`
* `round`: the hash of the payload, if provided - and if not, the latest\
  provided on-chain `round`
* `ttl`: blockheight target until which this transaction can be included
* `fee`: transaction fee
* `nonce`: the `from_id` account nonce

The `from_id` account MUST be a participant in the target\
channel. The `payload` MUST be an off-chain state or empty. It MUST provide correct\
authentication methods for both parties. It MUST be part of the same channel\
(containing same channel id). If provided, it MUST have a `round` higher than\
the one currently recorded on-chain. The `state_hash` and `round` must match\
the ones in `payload` or the on-chain stored data if the `payload` is empty.

This transaction MUST NOT trigger the `lock_period` and MUST NOT be used when\
the channel is in the closing state. It can be used to overwrite a state produced\
by a `channel_force_progress_tx` while the channel is in the open state.

If this transaction is valid then it sets:

* `Channel(channel_id).round := round`
* `Channel(channel_id).solo_round := 0`
* `Channel(channel_id).state_hash := state_hash`
* `Channel(channel_id).initiator_delegate_ids := initiator_delegate_ids`
* `Channel(channel_id).responder_delegate_ids := responder_delegate_ids`

## Closing a channel

We expect channels to be long running but they could be closed. This shall\
happen when participants have completed their interaction but this includes also the\
cases of non-cooperation or malicious behaviour. If both parties decide to\
close the channel, closing is just a matter of issuing one on-chain\
transaction, authenticated by everyone involved.

In the case of a solo closing, operations are subject to the `lock_period`,\
during which the closing state can be disputed via a `channel_slash_tx` or\
even progressed further on-chain via `channel_force_progress_tx` transactions.

### `channel_close_mutual`

Serialization defined[here](https://docs.aeternity.com/developer-documentation/serializations#channel-close-mutual-transaction)

* `channel_id`: channel id as recorded on-chain
* `from_id`: the account that posts the transaction
* `initiator_amount_final`: final balance for the initiator
* `responder_amount_final`: final balance for the responder
* `ttl`: blockheight target until which this transaction can be included
* `fee`: transaction fee
* `nonce`: the `from_id` account nonce

`initiator_amount_final` and `responder_amount_final` are the agreed upon\
distribution of coins out of the channel total balance of coins. The\
initiator's and responder's account balances are incremented by`initiator_amount_final` and `responder_amount_final` respectively. The\
channel MUST have enough total coins to pay for the fee as well as the agreed\
upon amounts. The total closing amount of a channel is computed by adding the\
amounts of the initiator and responder (before the close) and the fee. If this\
total closing amount is lower than the total amount coins already dedicated to\
the channel, the excess of coins is [locked](https://docs.aeternity.com/developer-documentation/protocol/consensus/locking).

#### Requirements

This transaction MUST have valid authentications of both parties.

This transaction MUST NOT be disputed and any ongoing dispute MUST be considered\
resolved by this transaction.

After this transaction has been included in a block, the channel MUST be\
considered closed and allow no further modifications. The on-chain persisted\
channel object is removed from the on-chain state trees.

`channel total >= transaction initiator_amount_final + responder_amount_final + fee`

### `channel_close_solo`

In order to close a channel unilaterally, a participant has to send a`channel_close_solo` transaction. This is only necessary if one peer stops\
responding or cooperating but can also be used by an malicious peer trying to\
close a channel with a state that hasn't been agreed on by all participants.

At any point a channel participant can initiate the solo closing sequence.\
After the `channel_close_solo` is posted and included in the chain a`lock_period` block height timer is started.\
This lock period is required to give the other party an opportunity to dispute\
the final state, that the closing sequence is based on. This can be done via\
the `channel_slash_tx` and `channel_force_progress_tx` transactions.

With the inclusion of this transaction on-chain, the channel enters the `locked`\
state, during which the `channel_close_solo_tx` can be disputed.

Serialization defined [here](https://docs.aeternity.com/developer-documentation/serializations#channel-close-solo-transaction)

* `channel_id`: channel id as recorded on-chain
* `from_id`: participant of the channel that posts the closing transaction
* `payload`: empty or an authenticated off-chain state proving that the proof\
  of inclusion is part of the channel
* `poi`: proof of inclusion
* `ttl`: blockheight target until which this transaction can be included
* `fee`: transaction fee
* `nonce`: according to the `from_id`'s account

Proof of inclusion represents the channel's internal state. At the bare minimum\
it has to include all accounts and their balances. It MUST provide enough\
information to close the channel. Miners are to check balances in it and use\
this data to update the channel's on-chain representation. This is how the\
poster initiates the solo closing sequence.\
If there are any contracts in the channel and those have balances of their own,\
they are not provided in the proof of inclusion but they are rather could be\
force-pushed in subsequent transactions. It is up to participants to decide\
if they want to post them at all. Thus the accumulative balances of the\
accounts in the solo-close transaction can be lower than the channel balance\
persisted on-chain.

The `payload` can be either empty or an authentication off-chain state\
transaction.

#### Empty payload

If the payload is empty, the last on-chain persisted `state_hash` and`solo_round` are used. In this case the proof of inclusion root hash MUST be\
equal to the one persisted for the channel on-chain. If that state was\
produced unilaterally, i.e. via a `channel_force_progress_tx`, making`Channel(channel_id).round != Channel(channel_id).solo_round`, the solo close\
is based on the `solo_round` and thus can still be disputed.

* `Channel(channel_id).locked_until := Block.height + Channel(channel_id).lock_period`

#### Off-chain transaction payload

If the payload is a transaction it MUST be a `channel_offchain_tx`. It MUST be\
authenticated by both participants.

Payload is a valid transaction that has:

* `state_hash` equal to the proof of inclusion's root hash. This is a proof\
  that the PoI is correct
* `channel_id` being the same as the transaction `channel_id`
* `round` greater than `Channel(channel_id).round`. If`Channel(channel_id).solo_round > Channel(channel_id).round`, then\
  this close will invalidate progress produced on-chain

If true, the following changes will be made:

* `Channel(channel_id).round := payload.round`
* `Channel(channel_id).solo_round := payload.round`
* `Channel(channel_id).state_hash := payload.state_hash`
* `Channel(channel_id).locked_until := Block.height + Channel(channel_id).lock_period`

### `channel_settle`

The settlement transaction is the last one in the lifecycle of a channel, but\
only required if the parties involved did not manage to cooperate when trying\
to close the channel. It has to be issued after all possible disputes are\
resolved to then redistribute the locked coins.

The `channel_settle_tx` CAN only be included in a block if:

* a `channel_close_solo_tx` transaction was published and the `lock_period` has\
  expired, i.e. `blockheight(top) - blockheight(channel_close_solo_tx) >= lock_period`
* there are no open disputes, which means that the channel is not currently\
  locked from a prior solo action

Serialization defined [here](https://docs.aeternity.com/developer-documentation/serializations#channel-settle-transaction)

* `channel_id`: channel id as recorded on-chain
* `from_id`: participant of the channel that posts the settling transaction
* `initiator_amount_final`: unsigned amount of coins the initiator gets from the\
  channel
* `responder_amount_final`: unsigned amount of coins the responder gets from the\
  channel
* `ttl`: blockheight target until which this transaction can be included
* `fee`: transaction fee
* `nonce`: according to the `from_id`'s account

#### Requirements

After this transaction has been included in a block, the channel MUST be\
considered closed and allow no further modifications. After the transaction is\
included, the channel object is removed from on-chain trees.

The transaction MUST be authenticated using the method corresponding to the\
account behind `from_id`.

The amounts must correspond to the ones on-chain, provided by the last`channel_close_solo_tx`, `channel_slash_tx` or a `channel_force_progress_tx`. The sum\
of those final amounts form the total closing amount of the channel. If this\
total closing amount is lower than the total amount of coins already dedicated to\
the channel, the excess of coins is [locked](https://docs.aeternity.com/developer-documentation/protocol/consensus/locking).

## Forcing progress

Forcing progress is the mechanism to be used when a dispute arises between\
parties and one of them wants to use the blockchain as an arbiter in a smart\
contract. The poster provides the off-chain state so that an off-chain\
contract can be executed on-chain and thus producing the channel's next\
off-chain state.

This can happen both while a channel is closing or while it is still active. If\
the channel is not closing, participants can continue using it from the on-chain\
produced channel state or initiate a closing based on it. If the channel is\
already closing, the force-progress updates what are the currently expected\
closing amounts for each participant (according to the contract's execution).

The force progress is based on what is considered to be the latest off-chain\
channel state. We have no way of proving that this state is actually the last\
one so any progress on chain can always be invalidated by providing an\
off-chain channel state, authenticated by both participants, with a higher round\
number than the round number that the to-be-disputed`channel_force_progress_tx` transaction used.

If the channel is in the closing state, issuing a `channel_force_progress_tx`\
locks it for `lock_period` blocks, during which the update can be disputed. This\
lock is necessary to prevent the channel from being closed immediately after\
a new round has been produced on chain.

The forcer can be either a participant or, after `iris`, a delegate. The\
latter can only force from behalf of the participant that had specified her to\
do so, ex: `initiator`'s delegates can only force progress calls made from the`initiator`'s account. Delegated forced progress is allowed only when the\
channel is already in a closing state.

It is worth mentioning that what is to be disputed is the off-chain state that\
the force progress had been based on and not the forcing of progress itself. If\
an older state had been provided by the forcing party, the other party can post\
a newer authenticated off-chain state (via a snapshot for example). The\
authenticated by both participants off-chain state with the same or greater\
round will replace the on-chain produced one.

### `channel_force_progress_tx`

Serialization defined [here](https://docs.aeternity.com/developer-documentation/serializations#channel-solo-force-progress-transaction)

* `channel_id`: channel id as recorded on-chain
* `from_id`: a participant or a delegate of the channel that posts the force\
  progress transaction
* `payload`: empty or an off-chain state transaction proving that the state trees\
  represent a mutually agreed-upon channel state
* `round`: channel's next round
* `update`: channel off-chain update that contains the contract call with gas\
  limit and gas prices to be consumed for the on-chain execution of the\
  off-chain contract. If it is a delegate that provides the force progress,\
  the the `caller` of the off-chain contract MUST be a participant that had\
  authorized this delegate
* `state_hash`: channel's expected new root hash of off-chain state trees
* `offchain_trees`: the full state channel's state trees
* `ttl`: blockheight target until which this transaction can be included
* `fee`: transaction fee
* `nonce`: according to the `from_id`'s account

The `offchain_trees` is the full off-chain state trees set: all accounts and\
all contracts. It MUST include both participants' off-chain accounts. It MUST\
include the contract to be called. Based on the `offchain_trees`, the next\
state is going to be computed and its root hash will become the new state's`state_hash`. The newly produced state trees will be different than the\
provided ones at least with the newly added `call` object. Thus even if the\
contract call fails a new `state_hash` is produced.

If this transaction is sent while the channel is in the `closing` state, it will\
transition the channel into the `locked` state for the next `lock_period` blocks.\
Although while this lasts, the channel can not be settled, new force-\
progressed transactions can still be accepted before the timer expires. Those\
MUST be based on the previous on-chain produced states but each next one\
resets the dispute timer.

The payload can be either empty or an authenticated off-chain state transaction.

#### Empty Payload

If the payload is empty, the last on-chain persisted state and `solo_round` are\
used. In this case the state trees root hash MUST be equal to the one persisted\
for the channel on-chain.

If the contract execution is successful, the channel will be updated with:

* `Channel(channel_id).solo_round := Channel(channel_id).solo_round + 1`
* `Channel(channel_id).state_hash := state_hash`

Additionally, if the channel is in the `closing` state:

* `Channel(channel_id).locked_until := Block.height + Channel(channel_id).lock_period`

#### Off-chain transaction Payload

If the payload is a transaction it MUST be a `channel_offchain_tx`. It MUST be\
authenticated by both participants.

An off-chain transaction payload is a valid transaction if it has:

* `state_hash` equal to the state trees' root hash. This is a proof that the`offchain_trees` represent a state both participants had agreed upon at some\
  point of time
* `channel_id` being the same as the transaction `channel_id`
* `round` greater than `Channel(channel_id).round`

The update MUST be a call to a contract. The caller of this update MUST be the\
poster of the force progress transaction. `amount`, `gas` and `gas_price` are\
specified in the update as well. The gas fees are going to be paid by the poster\
of the transaction. The `gas_price` MUST match protocol expectations for\
minimum gas price.\
The `state_hash` will be the root hash of the updated channel's state trees.\
After applying the contract call to the provided `offchain_trees` and updating\
accounts accordingly, a new channel's state tree is produced. It MUST have the\
same value of root hash as the state hash. If those do not match the force\
progress fails but since this can only be determined after the call has been\
executed, a call object is added on-chain and gas is consumed.

If the contract call succeeded, the channel state will be updated:

* `Channel(channel_id).round := payload.round`
* `Channel(channel_id).solo_round := payload.round + 1`
* `Channel(channel_id).state_hash := state_hash`

Additionally, if the channel is in the `closing` state:

* `Channel(channel_id).locked_until := Block.height + Channel(channel_id).lock_period`

#### Force progress side effects

**Updating channel object**

Channel state trees are recreated according to the `offchain_trees` being\
provided. The update is an off-chain contract call. It is applied on the\
channel's state trees and modifies them. The modified trees have a root\
hash. It might be:

* equal to the `state_hash` provided in the force progress transaction.\
  This hash indeed is the expected result of the contract call and the\
  blockchain has confirmed it. The on-chain channel object is updated\
  accordingly:
  * channel's state hash is updated to be the newly computed one
  * channel's round is the one in the force progress transaction
  * if the channel had been in a closing state, closing balances of\
    participants are updated according to the ones in the modified channel state\
    trees
* not equal to the `state_hash` provided in the force progress transaction. The\
  hash provided was not confirmed to be the expected one. In this case the force\
  progress fails and no new state channel state is created. The on-chain channel\
  object is NOT modified and thus - the `round` and `state_hash` as stored\
  on-chain remain unchanged. Gas is still consumed and a call object is created\
  on-chain.

A special case would be the forcer providing an invalid update call to be\
forced. Examples for an invalid update calls would be:

* A remote call to a missing contract
* Spending too much coins in the call so a participants's off-chain balance\
  goes bellow the `channel_reserve` threshold
* Contract call being terminated due to a `out_of_gas` exception

In this case the contract can not be executed and the forcing of progress\
fails to produce a new state. The end result is exactly the same as if there\
had been a mismatch of the produced `state_hash` and the expected one. It is\
worth mentioning that in this case the transaction is still a valid one, the\
poster of the transaction is charged for the consumed gas.

**Call object**

If the `channel_force_progress_tx` is valid, the contract call in the `update`\
is executed upon the MPT that had been produced by the `offchain_trees`.\
The output is a new MPT that will represent the new off-chain channel state.\
Participants are to either continue using the channel or close it. If there is\
no later off-chain update, they are expected to use this produced MPT in both\
cases.

The contract execution consumes gas. The `update` itself defines both the gas\
limit and the gas price. After the contract call has been executed and the real\
gas consumption has been calculated, the balance of the account posting the\
transaction is updated to pay the gas fee. Since this is not a mutual\
transaction but rather a unilateral one, the initiator of the progress\
enforcement pays the fees.

The contract call produces on-chain a new call object in the on-chain state\
trees for contract calls. Usually calls have a key that is composed by the\
contract's address, the caller's address and the caller's nonce. Since the off-\
chain contract is not persisted on-chain, it does not have an address that can\
be used in that manner. The calls produced by forcing progress use the`channel_force_progress_tx`'s hash instead.

Since the miner is expending resources for the contract's execution, the gas\
fees are paid and the call object is created for every force progress, no matter\
if it was successful to update the on-chain channel object or not.

## Disputing updates

Disputes should be considered anomalies, which only happen whenever one party\
tries to unilaterally publish an outdated state while:

* closing a channel unilaterally
* forcing progress
* slashing
* snapshoting

and can be disputed via `channel_slash_tx`, `channel_force_progress_tx`,`channel_snapshot_solo_tx` transactions.

Since disputes can themselves be challenged, we could end up in situations,\
where a malicious party progresses rounds rapidly via `channel_force_progress_tx`\
transactions, depriving the other party of the ability to dispute. To prevent\
this situation we can either:

1. enforce each dispute to always have to wait for the `lock_period` to expire\
   and have only one dispute per period
2. or not restrict the number consecutive disputes but always have the option of\
   challenging the first element of any chain of disputes, invalidating the full\
   chain.

We choose to use the second strategy because it allows faster progress in the\
case of a peer that disappeared while still guaranteeing safety. This makes\
keeping track of the proper states more complex but we assume a peer\
disappearing has a higher likelihood than them being actively malicious.\
Therefore we try to optimise for that case.

### Force progress dispute with closing channel

If the channel is in the closing state, which only happens via a`channel_close_solo`, then each dispute triggers an extension of the channel\
lock by `lock_period` blocks. If a channel is locked, the same rules as above\
apply. That is, as many `channel_force_progress_tx` or `channel_slash_tx`\
transactions as desired can be submitted—each one extending the lock—but as long\
as the channel is locked, the entire chain can be invalidated if a state with a\
higher round number can be posted.

Having the lock is necessary here because otherwise a malicious party might post\
a `channel_force_progress_tx` or `channel_slash_tx` containing an outdated state\
and then immediately try to have the channel be settled based on the result.

### Force progress dispute with open channel example

Setup:

* Bob and Alice open a channel between each other with `lock_period := 100`
* At `chain_height := 1000` Bob posts a `channel_force_progress_tx` with a\
  payload containing `round := 23` and produces `round := 24` on chain
* The channel state will now contain 23 as the latest `round` and 24 as\
  the `solo_round`

With the selected strategy, Bob does not have to wait for the `lock_period` to\
expire and can post as many `channel_force_progress_tx` as he wants, e.g. at`chain_height := 1001` he produces `solo_round := 25` and by `chain_height := 1011`\
arrives at `solo_round := 31`. The `round` is still at 23.

Now if Alice returns at `chain_height := 1110`, she can still dispute the*initial* update issued by Bob at `chain_height := 1000` by providing an\
authenticated by both payload with `round := 24` or higher via either a`channel_force_progress_tx` or a `channel_snapshot_solo_tx`.

### Force progress dispute with closing channel example

Setup:

* Bob and Alice open a channel between each other with `lock_period := 100`
* At `chain_height := 1000` Bob posts a `channel_close_solo` with a\
  payload containing `round := 23`. The channel is now locked until`chain_height == 1100`

With the selected strategy, Bob has to wait for the `lock_period` to expire, if\
he wants to settle the channel. But while the channel is locked, he can still\
post as many `channel_force_progress_tx` as he wants, e.g. at`chain_height := 1001` he produces `solo_round := 24` and by `chain_height := 1011`\
arrives at `solo_round := 31`. Each subsequent operation issued bumps the`lock_period` ahead. That is, by `chain_height == 1011` the `lock_period` is set\
to run out at `chain_height == 1111`.

Now it is important to note, that at even at `chain_height := 1110` Alice can\
still dispute the *initial* update issued by Bob at `chain_height := 1000` by\
providing an authenticated by both payload with `round := 24` or higher but her\
dispute would bump the lock by `lock_period` too.

### Channel slash

If a malicious party sent a `channel_close_solo` or `channel_force_progress_tx`\
with an outdated state, the honest party has the opportunity to issue a`channel_slash_tx` transaction. This transaction MUST include a state with a higher`round` number than the one being disputed, authenticated by all peers for a\
successful challenge.

Serialization defined [here](https://docs.aeternity.com/developer-documentation/serializations#channel-slash-transaction)

* `channel_id`: channel id as recorded on-chain
* `from_id`: channel participant or delegate that posts the slashing transaction
* `payload`: an off-chain transaction proving that the proof of inclusion is part\
  of the channel
* `poi`: proof of inclusion
* `ttl`: blockheight target until which this transaction can be included
* `fee`: transaction fee
* `nonce`: taken from the `from_id`'s account

The proof of inclusion represents the channel's internal state. It has to\
include both participants' accounts and their balances.\
If there are any contracts in the channel and those have balances of their own,\
they are not provided in the proof of inclusion but they are rather to be force\
pushed in subsequent transactions. It is up to participants to decide if they\
want to post them at all. Thus the accumulative balances of the accounts in the\
slash transaction can be lower than the channel balance persisted on-chain.

#### Off-chain transaction payload

The payload is a transaction and it MUST be a `channel_offchain_tx`. It\
MUST be authenticated by both peers.

Payload is a valid transaction that has:

* `state_hash` equal to the proof of inclusion's root hash. This is a proof\
  that the PoI is correct
* `channel_id` being the same as the transaction `channel_id`
* `round` greater than the last on-chain provided co-authenticated channel\
  state. If the latest on-chain round(s) were produced by`channel_force_progress_tx` transaction(s) that were based on an older channel\
  state - the whole chain of forced progressed channel states are invalidated\
  and replaced by the state provided by the slash. Co-authenticated channel\
  transactions replace unilateral ones with the same round.

If true, the following changes will be made:

* `Channel(channel_id).round := payload.round`
* `Channel(channel_id).solo_round := payload.round`
* `Channel(channel_id).state_hash := payload.state_hash`
* `Channel(channel_id).locked_until := Block.height + Channel(channel_id).lock_period`

#### Requirements

MUST be authenticated using the method corresponding to the public key `from_id`.

## Channel state tree

Each block MUST commit to a Merkle Patricia tree of open channels, where the`channel_id` specifies the path.\
At a leaf, nodes store information pertaining to the current state of the given\
channel.

* `channel_id`
* `initiator_id`
* `responder_id`
* `delegator_ids`
* `total_amount`
* `initiator_amount`
* `responder_amount`
* `channel_reserve`
* `state_hash`: last published state\_hash
* `round`: last known round
* `solo_round`: last round produced via a `channel_force_progress_tx`
* `lock_period`: agreed upon locking period by peers
* `locked_until`: on-chain channel height after which the channel can be settled
* `initiator_auth`: (from Fortuna release) signing/authentication data for initiator
* `responder_auth`: (from Fortuna release) signing/authentication data for responder

Keeping track of the `state_hash`, `round`, `locked_until`, and `lock_period` is\
necessary for nodes to be able to assess the validity of `channel_slash_tx` and`channel_settle_tx` transactions.

The `locked_until` is initialised with `0` and will stay `0` until the channel\
enters the `closing` state.

Serialization defined [here](https://docs.aeternity.com/developer-documentation/serializations#channel)
