Skip to content

Commit

Permalink
Update TTL reconciliation algorithm (#1605)
Browse files Browse the repository at this point in the history
  • Loading branch information
dmkozh authored Jan 4, 2025
1 parent d42e83c commit 57c0398
Showing 1 changed file with 25 additions and 19 deletions.
44 changes: 25 additions & 19 deletions core/cap-0063.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,27 +212,33 @@ Then all the operations must be applied and the changes in *non-TTL* ledger entr

Currently the changes to the entry TTL are immediately applied to the ledger state, in the same way as changes to any other ledger entry. However, the protocol allows increasing the TTL even for the entries that have been declared in the footprint as read-only. Thus if we wanted to preserve the current behavior, all the read-only footprint entries would potentially be read-write, and thus only transactions with non-overlapping footprints could belong to different clusters. This is not optimal for parallelization, given that common entries such as Stellar Asset Contract instances and some popular Wasms can be referenced by multiple transactions, but they're always or almost only read-only.

Thus, this CAP proposes a new way for applying the TTLs changes that makes changes to read-only entries' TTL changes commutative. The new algorithm is as follows:
Thus, this CAP proposes a new way for applying the TTLs changes that makes changes to read-only entries' TTL changes commutative. The proposed TTL update algorithm is based on two ideas:
- For any key, a TTL update should only be observed either when corresponding entry is being modified (i.e. is a part of the read-write footprint), or after executing all the transactions.
- Reduce fee waste - if a TTL change is not immediately observed, it should be accumulated instead and applied later instead (as opposed to e.g. just using the maximum TTL extension among all the transactions).

For every stage:
- After fees have been withdrawn, but before applying any operations:
- Snapshot the initial `liveUntilLedger` of every entry within the stage's footprint and store it in 'current TTL map' keyed by the TTL entry keys
- Also initialize an empty 'TTL extension map' that has a value of 0 for every key in the footprint
- When applying a Soroban operation:
The detailed new algorithm is as follows:

- After fees have been withdrawn, but before applying any operations:
- Snapshot the initial `liveUntilLedger` of every entry within the stage's footprint and store it in 'current TTL map' keyed by the TTL entry keys
- Also initialize an empty 'TTL extension map' that has a value of 0 for every key in the footprint
- When applying a Soroban operation:
- Before applying the actual operation logic:
- When reading the initial state of the entries, use 'current TTL map' to determine the `liveUntilLedger` of every entry in the footprint.
- If an operation succeeds and ledger changes caused by the operation must be materialized:
- For every key in the read-only footprint that had its `liveUntilLedger` increased:
- Add the `new_liveUntilLedger - initial_liveUntilLedger` to the value corresponding to the key in 'TTL extension map'
- For every key in the read-write footprint (unconditionally):
- Set the value corresponding to the key in 'current TTL map' to the new `liveUntilLedger` of the entry
- Set the value corresponding to the key in 'TTL extension map' to 0
- _unchanged_ The effective rent fee for the operation is still computed based on the initial state of the entry at operation start and the end state of the entry.
- Notice, however, that the initial TTL of the entry itself is defined differently now.
- After applying all the operations within the stage:
- Clamp every value in 'TTL extension map' to be at most `maxEntryTTL` from the `StateArchivalSettings` configuration setting entry
- Add the values in 'TTL extension map' to `liveUntilLedger` of the corresponding entries

Notice, that while the algorithm is defined in terms of a single mutable 'current TTL map', in implementation it can actually be separated into 2 parts: a fully immutable part for the entries that are always read-only within a stage, and a mutable part that may only be modified while applying transactions in a single cluster. Thus when applying transactions in parallel, no locking is necessary to update the maps during the operation application.
- For every key in the read-write footprint:
- Add the value corresponding to the key in 'TTL extension map' to the `liveUntilLedger` of the entry
- Set the value corresponding to the key in 'TTL extension map' to 0
- If an operation succeeds and ledger changes caused by the operation must be materialized:
- For every key in the read-only footprint that had its `liveUntilLedger` increased:
- Add the `new_liveUntilLedger - initial_liveUntilLedger` to the value corresponding to the key in 'TTL extension map'
- Clamp the updated value in the map to at most `maxEntryTTL` from the `StateArchivalSettings` configuration setting entry
- For every key in the read-write footprint (unconditionally):
- Set the value corresponding to the key in 'current TTL map' to the new `liveUntilLedger` of the entry
- _unchanged_ The effective rent fee for the operation is still computed based on the initial state of the entry at operation start and the end state of the entry.
- Notice, however, that the initial TTL of the entry itself is defined differently now.
- After applying all the operations in the phase:
- Add the values in 'TTL extension map' to `liveUntilLedger` of the corresponding entries

Notice, that while the algorithm is defined in terms of a single mutable 'current TTL map', in implementation it can actually be separated into 2 parts: a fully immutable part for the entries that are always read-only within a stage, and a mutable part that may only be modified while applying transactions in a single cluster. Thus when applying transactions in parallel, no locking is necessary to update the maps during the operation application. The entries might move between maps only in-between the stages.

#### Parallel application of operations

Expand Down

0 comments on commit 57c0398

Please sign in to comment.