- ADR 18 merged both
chainStateinto one single state in the Hydra node, giving the chain layer a way to fetch and update the
chainStatewhen observing a chain event.
- Having the
chainStatemade persistency easier to deal with: we ensure that we always save cohesive states.
- When opening our first head on mainnet we suffered from a commit/rollback
issue that was the
result of a race condition in the management of the
chainStateas implemented in the context of ADR 18.
- Reproducing the issue by introducing rollbacks in the model based tests, we discovered that, as a client of a hydra-node, we had no idea how to deal with the rollback event as it is defined now.
- #185 plans to improve rollback management.
The following picture details the race condition through an exemple:
The DirectChain component fetch some
chainState 0from the
The DirectChain component observes a transaction and it
- publishes an event about this observation
- updates the
- The Node processes the event and emits a new
previousRecoverableStatein case a rollback later happens
The problem is that
HeadState 2 in the figure should point to a previous
recoverable head state containing
chainState 0 and not
Updating the chain state only in the
HeadLogic leads to problems when several
transactions are in the same block. This can be mitigated by keeping a volatile
chain state locally while analysing the block. But then it leads to race
conditions issues if, for some reason, blocks are produced faster than they are
processed by the HeadLogic. Low probability in production but higher when
- We supersede ADR 18 with the current ADR.
- A local chain state is re-introduced in the chain component, not shared with the head logic.
- A copy of the
chainStateis kept in the
headStateto keep the benefits of ADR 18 regarding persistency.
RolledBackoutput is removed from the API unless actionable by users or #185 implemented.
- The rollback logic is removed from the HeadLogic and only maintained in the chain component.
- The Rollback event carries the ChainState.
- At the node startup, we initialize the chain layer with the persisted