diff options
Diffstat (limited to 'adenosine-pds/src/bin/adenosine-pds-dump-mst.rs')
| -rw-r--r-- | adenosine-pds/src/bin/adenosine-pds-dump-mst.rs | 129 | 
1 files changed, 129 insertions, 0 deletions
| diff --git a/adenosine-pds/src/bin/adenosine-pds-dump-mst.rs b/adenosine-pds/src/bin/adenosine-pds-dump-mst.rs new file mode 100644 index 0000000..1f1b947 --- /dev/null +++ b/adenosine-pds/src/bin/adenosine-pds-dump-mst.rs @@ -0,0 +1,129 @@ +/// Helper program to print MST keys/docs from a sqlite repo +use anyhow::{anyhow, Result}; +use ipfs_sqlite_block_store::BlockStore; +use libipld::cbor::DagCborCodec; +use libipld::prelude::Codec; +use libipld::{Cid, DagCbor}; + +use std::env; + +#[derive(Debug, DagCbor, PartialEq, Eq)] +struct CommitNode { +    root: Cid, +    sig: Box<[u8]>, +} + +#[derive(Debug, DagCbor, PartialEq, Eq)] +struct RootNode { +    auth_token: Option<String>, +    prev: Option<Cid>, +    // TODO: not 'metadata'? +    meta: Cid, +    data: Cid, +} + +#[derive(Debug, DagCbor, PartialEq, Eq)] +struct MetadataNode { +    datastore: String, // "mst" +    did: String, +    version: u8, // 1 +} + +#[derive(Debug, DagCbor, PartialEq, Eq)] +struct MstEntry { +    k: String, +    p: u32, +    v: Cid, +    t: Option<Cid>, +} + +#[derive(Debug, DagCbor, PartialEq)] +struct MstNode { +    l: Option<Cid>, +    e: Vec<MstEntry>, +} + +fn get_mst_node(db: &mut BlockStore<libipld::DefaultParams>, cid: &Cid) -> Result<MstNode> { +    let mst_node: MstNode = DagCborCodec.decode( +        &db.get_block(cid)? +            .ok_or(anyhow!("expected block in store"))?, +    )?; +    Ok(mst_node) +} + +fn print_mst_keys(db: &mut BlockStore<libipld::DefaultParams>, cid: &Cid) -> Result<()> { +    let node = get_mst_node(db, cid)?; +    if let Some(ref left) = node.l { +        print_mst_keys(db, left)?; +    } +    let mut key: String = "".to_string(); +    for entry in node.e.iter() { +        key = format!("{}{}", &key[0..entry.p as usize], entry.k); +        println!("{}\t-> {}", key, entry.v); +        if let Some(ref right) = entry.t { +            print_mst_keys(db, right)?; +        } +    } +    Ok(()) +} + +async fn dump_mst_keys(db_path: &str) -> Result<()> { +    let mut db: BlockStore<libipld::DefaultParams> = { +        let path = std::path::PathBuf::from(db_path); +        let path = ipfs_sqlite_block_store::DbPath::File(path); +        BlockStore::open_path(path, Default::default())? +    }; + +    let all_aliases: Vec<(Vec<u8>, Cid)> = db.aliases()?; +    if all_aliases.is_empty() { +        println!("expected at least one alias in block store"); +        std::process::exit(-1); +    } +    let (alias, commit_cid) = all_aliases[0].clone(); +    println!( +        "starting from {} [{}]", +        commit_cid, +        String::from_utf8_lossy(&alias) +    ); + +    // NOTE: the faster way to develop would have been to decode to libipld::ipld::Ipld first? meh + +    //println!("raw commit: {:?}", &db.get_block(&commit_cid)?.ok_or(anyhow!("expected commit block in store"))?); +    let commit: CommitNode = DagCborCodec.decode( +        &db.get_block(&commit_cid)? +            .ok_or(anyhow!("expected commit block in store"))?, +    )?; +    println!("Commit: {:?}", commit); +    //println!("raw root: {:?}", &db.get_block(&commit.root)?.ok_or(anyhow!("expected commit block in store"))?); +    let root: RootNode = DagCborCodec.decode( +        &db.get_block(&commit.root)? +            .ok_or(anyhow!("expected root block in store"))?, +    )?; +    println!("Root: {:?}", root); +    let metadata: MetadataNode = DagCborCodec.decode( +        &db.get_block(&root.meta)? +            .ok_or(anyhow!("expected metadata block in store"))?, +    )?; +    println!("Metadata: {:?}", metadata); +    let mst_node: MstNode = DagCborCodec.decode( +        &db.get_block(&root.data)? +            .ok_or(anyhow!("expected block in store"))?, +    )?; +    println!("MST root node: {:?}", mst_node); + +    println!("============"); + +    print_mst_keys(&mut db, &root.data)?; +    Ok(()) +} + +#[tokio::main] +async fn main() -> Result<()> { +    let args: Vec<String> = env::args().collect(); +    if args.len() != 2 { +        println!("expected 1 args: <db_path>"); +        std::process::exit(-1); +    } +    let db_path = &args[1]; +    dump_mst_keys(db_path).await +} | 
