This document explains the internal architecture of Ledger.
The Ledger implementation is logically composed of the following components:
All of these components run together within the Ledger process.
Ledger stores data in key-value stores called pages. A page changes in atomic commits, each commit adding, removing or modifying one or more entries in the key-value store.
The commit history of each page forms a DAG in which each commit has either no parents (initial commit), 1 parent (regular commit) or 2 parents (merge commit).
The Storage component persists:
The contents of each commit are key-value pairs (entries), stored in a B-Tree-like structure with the following main properties:
Storage exposes a key-value API to Local client and creates new storage objects and commits in response to modifications the Local client makes. Similarly, Storage receives commits and storage objects synced from other devices from Cloud Sync.
Code:
Local Client exposes a FIDL API to apps running on the device. In response to modifications to the key-value store requested by apps connecting to Ledger, it makes corresponding calls to Storage.
When notified about a conflict by Storage, Local client resolves it according to the policy selected by the client app, calling back to it if necessary - see Conflict resolution in the API Guide.
Code:
Cloud sync is notified by Storage about new locally-produced commits and is responsible for pushing them, along with the associated storage objects, to the cloud. Conversely, Cloud sync also tracks new commits being synced to the cloud by other devices, downloads them and registers them with Storage.
Code: