Skip to main content

Crate didbot_repo

Crate didbot_repo 

Source
Expand description

An atproto repository: a signed commit over a Merkle search tree, and the CAR file that carries it.

This is the layer that turns records a server happens to hold into something a stranger can check. Three steps, and each one is worthless without the next:

  1. Every record is encoded canonically and named by the hash of those bytes — didbot-data.
  2. Those names are keyed into a Merkle search tree whose shape no implementation gets to choose, giving one root CID over the whole repository — didbot_data::mst.
  3. An account’s key signs a Commit naming that root, and the whole lot goes out as a car file.

A Proof is the fourth step and the one that makes the other three worth having: the blocks on one key’s path through the tree, so a reader can check that one record is in the repository without being handed all of it. read_record is that reader, for a record another server holds.

A repository is built whole by a Builder, and after that changed one record at a time by a Draft, which re-signs the edited tree as the next commit. Both land on the same repository for the same records.

use didbot_key::SigningKey;
use didbot_repo::Builder;

let key = SigningKey::generate();
let mut repo = Builder::new();
repo.insert(
    "com.example.thing",
    "3lqmnopqrstuv",
    &serde_json::json!({"text": "quernstone", "emoji": "🜁"}),
)?;
let repo = repo.commit("did:web:kestrel.example", "3lqmnopqrstuv", None, &key);

// The signature is what a reader checks, with a key it got from the DID
// document rather than from us.
repo.commit().verify(&key.verifying_key())?;
let car = repo.to_car();

§Why this is not in didbot-pds

The same reason didbot-data is not: this sits below the server rather than inside it. It has no clock, no store, no notion of an account and no opinion about when a commit should happen — a caller hands over records, a revision and a key, and gets bytes. That makes the whole of it testable without a server, and it keeps the largest crate in the workspace from growing the two things most likely to be reused elsewhere.

§What is deliberately absent

A reader of its own exports. car::read and read_record read what another server sends. Nothing here reads this crate’s own output back to check it: the implementation that checks an export is not ours, and a decoder written to check our own encoder would agree with it about anything the two got wrong together.

A history. prev is a parameter and this crate will chain commits if a caller supplies one, but nothing here keeps them.

Blobs. No lexicon in this project carries one, so there is no block in a repository here that is not DAG-CBOR.

Modules§

car
CARv1: the file a repository is handed over as.
commit 🔒
The commit: the one block in a repository that is signed.
repository 🔒
A repository: records, the tree over them, and the commit that signs it.
verify 🔒
Reading one record out of another server’s repository, from the proof that server answers com.atproto.sync.getRecord with.

Structs§

Builder
A repository under construction.
Commit
A commit before it is signed.
Draft
A signed repository being changed, one record at a time, into its next commit.
Proof
The blocks that prove what a repository says about one key.
Repository
A signed repository, ready to be handed to somebody who does not trust us.
Rewritten
The blocks an edit added and took away.
SignedCommit
A commit and the signature over it.

Enums§

CommitError
Why a commit could not be trusted.
CommitKey
A key another repository’s commits are signed with, as its DID document publishes it. atproto signs with either of two curves; this crate signs with secp256k1 only and reads both.
ProofError
Why a proof establishes nothing about a record.
RepoError
Why a repository could not be assembled.

Constants§

REPO_VERSION
The repository format this crate writes.

Functions§

read_record
The record at collection/rkey in did’s repository, as proof shows it, in its JSON form. None when the proof shows the repository holds nothing there.
tree_key
The key a record sits at in the tree.