diff --git a/moots-1-simple/src/lib.rs b/moots-1-simple/src/lib.rs index ca4380a..0683428 100644 --- a/moots-1-simple/src/lib.rs +++ b/moots-1-simple/src/lib.rs @@ -1,8 +1,9 @@ -use std::sync::Arc; +use hubble_sync_rocksdb::RocksEngine; pub mod serve; +pub mod store; pub mod sync; pub struct Moots { - pub db: Arc, + pub storage: RocksEngine, } diff --git a/moots-1-simple/src/store.rs b/moots-1-simple/src/store.rs new file mode 100644 index 0000000..48b6ed1 --- /dev/null +++ b/moots-1-simple/src/store.rs @@ -0,0 +1,20 @@ +pub static FOLLOWS_KEY_PREFIX: &[u8] = b"follows:"; + +pub fn follows_key(us: &str, them: &str, rkey: &str) -> Vec { + [ + FOLLOWS_KEY_PREFIX, + us.as_bytes(), + &[0x00], + them.as_bytes(), + &[0x00], + rkey.as_bytes(), + ].concat() +} + +pub fn our_follows_prefix(us: &str) -> Vec { + [ + FOLLOWS_KEY_PREFIX, + us.as_bytes(), + &[0x00], + ].concat() +} diff --git a/moots-1-simple/src/sync.rs b/moots-1-simple/src/sync.rs index 818ba66..b90823d 100644 --- a/moots-1-simple/src/sync.rs +++ b/moots-1-simple/src/sync.rs @@ -1,9 +1,13 @@ use hubble_sync::{ AccountStatus, AppResult, Commit, RepoContext, ResyncData, SimpleSyncConsumer, StorageEngine, + OpKind, }; use hubble_sync_rocksdb::RocksEngine; -use crate::Moots; +use crate::{Moots, store}; + +/// if someone follows more than 1M people, we just drop them. moots meaningless. +const FOLLOWS_LIMIT: usize = 1_000_000; impl SimpleSyncConsumer for Moots { type Engine = RocksEngine; @@ -14,6 +18,27 @@ impl SimpleSyncConsumer for Moots { ctx: &RepoContext, batch: &mut ::Batch, ) -> AppResult { + for op in commit.ops { + if !op.path.starts_with("app.bsky.graph.follow/") { + // ignore everything that's not a change to follows + continue; + } + match op.kind { + OpKind::Create { cid } => { + // 1. get the block, decode cbor (i guess we should grab struct from jacq) + // 2. extract the follow subject + // 3. generate the key with our did (ctx), the subject (cbor), and the rkey (commit.path) + // 4. add a put for the key to the batch (empty value) + }, + OpKind::Delete { prev } => { + // 1. generate the key, same way as create (i guess we can combine things?) + // 2. add a delete for the key to the batch + }, + OpKind::Update { .. } => { + tracing::warn!("ignoring update to follows (not a valid operation)"); + } + } + } Ok(()) }