Skip to content

Commit

Permalink
Add encrypted example and remove todos.
Browse files Browse the repository at this point in the history
  • Loading branch information
dvc94ch committed May 7, 2020
1 parent 1559033 commit 0c56a4d
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 49 deletions.
60 changes: 60 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ default-features = false
features = ["kad", "mdns", "ping", "secio", "tcp", "yamux"]

[dev-dependencies]
disco = "0.1.0"
env_logger = "0.7.1"
ipld-block-builder = "0.1.0"
tempdir = "0.3.7"
80 changes: 80 additions & 0 deletions examples/encrypted_block_builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use ipfs_embed::{Config, Store};
use ipld_block_builder::DagCbor;

#[derive(Clone, DagCbor, Debug, Eq, PartialEq)]
struct Identity {
id: u64,
name: String,
age: u8,
}

mod encrypted_builder {
use disco::symmetric::{decrypt, encrypt, AuthCiphertext};
use ipld_block_builder::cbor::DagCbor;
use ipld_block_builder::cid::Cid;
use ipld_block_builder::codec::{Codec, Decode, Encode};
use ipld_block_builder::error::{Error, Result};
use ipld_block_builder::multihash::{Blake2b256, Code, Multihasher};
use ipld_block_builder::raw::Raw;
use ipld_block_builder::store::{ReadonlyStore, Store};
use ipld_block_builder::GenericBlockBuilder;
use std::marker::PhantomData;

pub type EncryptedBlockBuilder<S> = GenericEncryptedBlockBuilder<S, Blake2b256, DagCbor>;

pub struct GenericEncryptedBlockBuilder<S, H: Multihasher<Code>, C: Codec> {
marker: PhantomData<C>,
key: Vec<u8>,
builder: GenericBlockBuilder<S, H, Raw>,
}

impl<S, H: Multihasher<Code>, C: Codec> GenericEncryptedBlockBuilder<S, H, C> {
pub fn new(store: S, key: Vec<u8>) -> Self {
Self {
marker: PhantomData,
key,
builder: GenericBlockBuilder::<S, H, Raw>::new_private(store),
}
}
}

impl<S: ReadonlyStore, H: Multihasher<Code>, C: Codec> GenericEncryptedBlockBuilder<S, H, C> {
/// Returns the decoded block with cid.
pub async fn get<D: Decode<C>>(&self, cid: &Cid) -> Result<D> {
let bytes: Vec<u8> = self.builder.get(cid).await?;
let ct = AuthCiphertext::from_bytes(bytes).unwrap();
let data = decrypt(&self.key, ct).unwrap();
Ok(C::decode(&data).map_err(|e| Error::CodecError(Box::new(e)))?)
}
}

impl<S: Store, H: Multihasher<Code>, C: Codec> GenericEncryptedBlockBuilder<S, H, C> {
/// Encodes and inserts a block into the store.
pub async fn insert<E: Encode<C>>(&self, e: &E) -> Result<Cid> {
let data = C::encode(e).map_err(|e| Error::CodecError(Box::new(e)))?;
let ct = encrypt(&self.key, data.into_vec()).into_bytes();
let cid = self.builder.insert(&ct).await?;
Ok(cid)
}
}
}

#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = Config::from_path("/tmp/db")?;
let store = Store::new(config)?;
let key = b"private encryption key".to_vec();
let builder = encrypted_builder::EncryptedBlockBuilder::new(store, key);

let identity = Identity {
id: 0,
name: "David Craven".into(),
age: 26,
};
let cid = builder.insert(&identity).await?;
let identity2 = builder.get(&cid).await?;
assert_eq!(identity, identity2);
println!("encrypted identity cid is {}", cid);

Ok(())
}
6 changes: 4 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
//! IpfsEmbed is an embeddable ipfs implementation.
//!
//! ```
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use ipfs_embed::{Config, Store};
//! let config = Config::from_path("/tmp/db");
//! let store = Store::new(config);
//! let config = Config::from_path("/tmp/db")?;
//! let store = Store::new(config)?;
//! # Ok(()) }
//! ```
mod config;
mod error;
Expand Down
14 changes: 6 additions & 8 deletions src/network/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl Network {

let peer_id = config.peer_id();
let behaviour = NetworkBackendBehaviour::new(config);
let mut swarm = Swarm::new(transport, behaviour, peer_id.clone());
let mut swarm = Swarm::new(transport, behaviour, peer_id);
Swarm::listen_on(&mut swarm, "/ip4/127.0.0.1/tcp/0".parse().unwrap())?;
let event = task::block_on(swarm.next_event());
let addr = if let SwarmEvent::NewListenAddr(addr) = event {
Expand Down Expand Up @@ -101,7 +101,7 @@ impl Future for Network {
Ok(Some(block)) => {
let data = block.to_vec().into_boxed_slice();
self.swarm.send_block(&peer_id, cid, data)
},
}
Ok(None) => log::trace!("don't have local block {}", cid.to_string()),
Err(err) => log::error!("failed to get local block {:?}", err),
}
Expand All @@ -112,12 +112,10 @@ impl Future for Network {
match event {
StorageEvent::Want(cid) => self.swarm.want_block(cid, 1000),
StorageEvent::Cancel(cid) => self.swarm.cancel_block(&cid),
StorageEvent::Provide(cid) => {
match self.storage.get_local(&cid) {
Ok(Some(block)) => self.swarm.provide_and_send_block(&cid, &block),
_ => self.swarm.provide_block(&cid),
}
}
StorageEvent::Provide(cid) => match self.storage.get_local(&cid) {
Ok(Some(block)) => self.swarm.provide_and_send_block(&cid, &block),
_ => self.swarm.provide_block(&cid),
},
StorageEvent::Unprovide(cid) => self.swarm.unprovide_block(&cid),
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/storage/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ pub enum Key {
}

impl Key {
pub fn prefix(&self) -> IVec {
(&[*self as u8]).into()
pub fn prefix(self) -> IVec {
(&[self as u8]).into()
}

fn byte_key(&self, bytes: &[u8]) -> IVec {
fn byte_key(self, bytes: &[u8]) -> IVec {
let mut key = Vec::with_capacity(bytes.len() + 1);
key.push(*self as u8);
key.push(self as u8);
key.extend_from_slice(bytes);
key.into()
}

fn cid_key(&self, cid: &Cid) -> IVec {
fn cid_key(self, cid: &Cid) -> IVec {
self.byte_key(&cid.to_bytes())
}

Expand Down
37 changes: 3 additions & 34 deletions src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use libipld::cid::Cid;
use libipld::store::{AliasStore, ReadonlyStore, Store as WritableStore, StoreResult, Visibility};
use libp2p::core::{Multiaddr, PeerId};

#[derive(Clone, Debug)]
pub struct Store {
storage: Storage,
peer_id: PeerId,
Expand Down Expand Up @@ -39,15 +40,6 @@ impl Store {
pub fn address(&self) -> &Multiaddr {
&self.address
}

pub fn get_from_peer<'a>(
&'a self,
_peer_id: &'a PeerId,
_cid: &'a Cid,
) -> StoreResult<'a, Option<Box<[u8]>>> {
// TODO
Box::pin(async move { Ok(Some(b"hello world".to_vec().into_boxed_slice())) })
}
}

impl ReadonlyStore for Store {
Expand All @@ -66,7 +58,7 @@ impl WritableStore for Store {
Box::pin(async move { Ok(self.storage.insert(cid, data.into(), visibility)?) })
}

fn flush<'a>(&'a self) -> StoreResult<'a, ()> {
fn flush(&self) -> StoreResult<'_, ()> {
Box::pin(async move { Ok(self.storage.flush().await?) })
}

Expand Down Expand Up @@ -131,31 +123,14 @@ mod tests {
assert_eq!(data, data2);
}

#[async_std::test]
#[ignore]
async fn test_exchange_private() {
// TODO
env_logger::try_init().ok();
let (store1, _) = create_store(vec![]);
let (store2, _) = create_store(vec![]);
let (cid, data) = create_block(b"hello world");
store1
.insert(&cid, data.clone(), Visibility::Private)
.await
.unwrap();
let peer_id = store1.peer_id();
let data2 = store2.get_from_peer(peer_id, &cid).await.unwrap().unwrap();
assert_eq!(data, data2);
}

#[async_std::test]
async fn test_exchange_mdns() {
env_logger::try_init().ok();
let (store1, _) = create_store(vec![]);
let (store2, _) = create_store(vec![]);
let (cid, data) = create_block(b"hello world");
store1
.insert(&cid, data.clone(), Visibility::Public)
.insert(&cid, data.clone(), Visibility::Private)
.await
.unwrap();
let data2 = store2.get(&cid).await.unwrap();
Expand Down Expand Up @@ -208,10 +183,4 @@ mod tests {
async fn test_provider_not_found_kad() {
// TODO
}

#[async_std::test]
#[ignore]
async fn test_ping_closes_connection() {
// TODO
}
}

0 comments on commit 0c56a4d

Please sign in to comment.