Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wp/ updated delete file to use pk as filename #33

Open
wants to merge 54 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
25eef4c
WP/skip files if exists on write
Mar 13, 2023
61b2edc
WP/check_catalog_exists [test]
Mar 14, 2023
eddf0d5
WP/block write_read [test] temporarily
Mar 14, 2023
07e5283
WP/delete-file-blake3hash-http-route
rustchain64 Mar 14, 2023
227ed37
WP/delete-file-format-update
rustchain64 Mar 14, 2023
7d85f6b
WP/delete-file-fix-clippy-issues
rustchain64 Mar 14, 2023
e148dd9
WP/18-slices-blake3_hash-slice_index-slice_range
rustchain64 Mar 15, 2023
8f30773
WP/18-slice-blake3_hash-slice-prototype
rustchain64 Apr 5, 2023
767156c
WP/18-slice-implement-http-get-slice
rustchain64 Apr 5, 2023
f02bc40
WP/18-slice-blake3_hash-slice-dev
rustchain64 Apr 6, 2023
ab317e4
WP/18-slice-blacke3-hash-slice-test-error-file-108
rustchain64 Apr 8, 2023
908e39d
WP/18-slice-black3-hash-Encoded
rustchain64 Apr 8, 2023
5f6c4c2
WP/18-slice-black3-hash-debug-stage
rustchain64 Apr 10, 2023
ba92b5d
WP/18-slice-black3-HT-to-debug
rustchain64 Apr 10, 2023
684bb7c
WP/18-slicke-blake3_hash-stash
rustchain64 Apr 11, 2023
fc8634e
WP/18-slice-blake3_hash-analyze-test
rustchain64 Apr 12, 2023
29a31b4
WP/18-slice-blake3-resolve-cargo-toml
rustchain64 Apr 12, 2023
e50a2d5
WP/18-slice-blake3-clippy
rustchain64 Apr 12, 2023
6b77b22
WP/18-slice-blake3-read_slices
rustchain64 Apr 12, 2023
657c120
WP/18-slice-blake3-test-update
rustchain64 Apr 12, 2023
50dc264
WP/18-slice-blake3-unneeded-return
rustchain64 Apr 12, 2023
dedb85d
WP/18-slice-blake3-http-get-slice
rustchain64 Apr 12, 2023
13134f7
WP/upload-get-last-hash
rustchain64 Apr 19, 2023
2f2e403
WP/upload-get-last-hash-debug
rustchain64 Apr 21, 2023
cbf7e9b
WP/upload-get-last-hash-cleanup
rustchain64 Apr 25, 2023
990420d
WP/upload-get-last-hash-test-to-pass
rustchain64 Apr 25, 2023
eff5232
WP/upload-get-last-hash-file-read-test
rustchain64 Apr 25, 2023
d32eeca
WP/upload-get-last-hash-implement-catalog-exists
rustchain64 Apr 25, 2023
5b9a950
WP/upload-get-last-hash-revert-tests
rustchain64 Apr 25, 2023
91ae1b9
WP/upload-get-last-hash-remove-file-write-local
rustchain64 Apr 25, 2023
30f7878
WP/upload-get-last-hash-clippy
rustchain64 Apr 25, 2023
a7fc00a
WP/upload-get-last-hash-path-exists
rustchain64 Apr 26, 2023
01ba0f7
WP/upload-get-last-debug-binary-files
rustchain64 Apr 29, 2023
8e88ead
WP/upload-get-last-point-cargo-toml
rustchain64 Apr 29, 2023
9e3a446
WP/upload-get-hash-clippy
rustchain64 Apr 29, 2023
8849101
Implement HTTP body streaming version of post_file.
cryptoquick Apr 30, 2023
ea0c994
Refactor streaming interface format. Fix tests.
cryptoquick Apr 30, 2023
4629aa2
Reduce number of files created in test by increasing chunk size to 1MB.
cryptoquick Apr 30, 2023
3e9949d
Fix check catalog_exists test. Cleanup unused libraries.
cryptoquick Apr 30, 2023
d1f9216
Log node public key in config. Correct Error Message in fs backend. R…
rustchain64 May 1, 2023
961f663
WP/upload-last-hash-merger-with-stream-post-file
rustchain64 May 2, 2023
730f208
upload-get-lash-hash fixes. (#38)
cryptoquick May 4, 2023
7188500
Merge main.
cryptoquick May 4, 2023
7db7d4d
temp stash
rustchain64 May 4, 2023
4e21025
update delete
rustchain64 May 4, 2023
642acb4
delete across volumes
rustchain64 May 4, 2023
8637f02
deleted files counter
rustchain64 May 5, 2023
04d53bf
comments
rustchain64 May 5, 2023
04ef77f
handle HT comments
rustchain64 May 8, 2023
dd5fa8c
updated delete file for file_name
rustchain64 May 8, 2023
c675bd0
remove slice function
rustchain64 May 8, 2023
18fc5df
fix clippy error
rustchain64 May 8, 2023
f651742
read_slices backup
rustchain64 May 8, 2023
c4329ad
backup only
rustchain64 May 9, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .DS_Store
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not add this file

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file still needs to be removed. You need to add that to your global gitignore (no need to add it to the project gitignore.)

Copy link
Collaborator Author

@rustchain64 rustchain64 May 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added the (global) .gitignore for Mac

Copy link
Collaborator Author

@rustchain64 rustchain64 May 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ran
sudo find / -name ".DS_Store" -depth -exec rm {} ;
ran cargo test, no .DS_Store present

Binary file not shown.
313 changes: 179 additions & 134 deletions Cargo.lock

Large diffs are not rendered by default.

Binary file added file/body_test.png
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not add this file, please remove

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file does not appear to be used, and besides, it's in the wrong place. Please remove this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed, not used for testing at this anymore

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion src/backend.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
pub mod fs;
// pub mod task;
85 changes: 52 additions & 33 deletions src/backend/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ pub fn write_segment(sk: &[u8], pk: &[u8], encoded: &Encoded) -> Result<BaoHash>

pub fn write_catalog(file_hash: &Blake3Hash, segment_hashes: &[BaoHash]) -> Result<()> {
debug!("Write catalog");

let contents: Vec<u8> = segment_hashes
.iter()
.flat_map(|bao_hash| bao_hash.to_bytes())
Expand Down Expand Up @@ -255,7 +256,56 @@ pub fn read_catalog(file_hash: &Blake3Hash) -> Result<Vec<BaoHash>> {
Ok(bao_hashes)
}

#[allow(unused_variables)]
pub async fn read_slices(
hash: bao::Hash, // from Blake3
file_bytes: &[u8],
slice_start: u64, //let slice_start = 65536;
slice_len: u16, // let slice_len = 8192;
) -> Result<Vec<u8>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes no sense to provide the entire file to this method. This is supposed to be for retrieving just a slice of the file. It needs to return the range of the raw bytes on disk. It can make the disk IO calls by reading the catalog and then the appropriate segment.

I've updated the issue so hopefully the task is more clear:
#18

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those values where for initial testing only.
actual slice data comes from the params.

use std::io::prelude::*;

// Start by encoding some input.
let (encoded_input, hash) = bao::encode::encode(file_bytes);
debug!(">>> encoded INPUT LENGTH:: {:?}", &encoded_input.len());
debug!(">>> fs hash hash:: {:?}", &hash);

// Slice the encoding. These parameters are multiples of the chunk size, which avoids
// unnecessary overhead.
let slice_start = 65536;
let slice_len = 8192;
let encoded_cursor = std::io::Cursor::new(&encoded_input);
let mut extractor = bao::encode::SliceExtractor::new(encoded_cursor, slice_start, slice_len);
let mut slice = Vec::new();
extractor.read_to_end(&mut slice)?;

// Decode the slice. The result should be the same as the part of the input that the slice
// represents. Note that we're using the same hash that encoding produced, which is
// independent of the slice parameters. That's the whole point; if we just wanted to re-encode
// a portion of the input and wind up with a different hash, we wouldn't need slicing.
let mut decoded = Vec::new();
let mut decoder = bao::decode::SliceDecoder::new(&*slice, &hash, slice_start, slice_len);
decoder.read_to_end(&mut decoded)?;
// assert_eq!(
// &encoded_input[slice_start as usize..][..slice_len as usize],
// &*decoded
// );
debug!(
"usize vs length: {:?}",
&encoded_input[slice_start as usize..][..slice_len as usize].len()
);

// Like regular decoding, slice decoding will fail if the hash doesn't match.
let mut bad_slice = slice.clone();
debug!("BAD SLICE");
let last_index = bad_slice.len() - 1;
bad_slice[last_index] ^= 1;
let mut decoder = bao::decode::SliceDecoder::new(&*bad_slice, &hash, slice_start, slice_len);
let err = decoder.read_to_end(&mut Vec::new()).unwrap_err();
assert_eq!(std::io::ErrorKind::InvalidData, err.kind());

Ok(decoded)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this code here? Can't we just use extract_slice from carbonado core?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this section, as I was using it for A/B testing on the results.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have not yet removed it. Only request my review once everything has been addressed.


pub fn delete_file(pk: Secp256k1PubKey, file_bytes: &[u8]) -> Result<()> {
let pk_bytes = pk.to_bytes();
let (x_only_pk, _) = pk.into_inner().x_only_public_key();
Expand All @@ -277,9 +327,8 @@ pub fn delete_file(pk: Secp256k1PubKey, file_bytes: &[u8]) -> Result<()> {
Ok(())
}

#[allow(unused_variables)]
// TODO: These aren't worth breaking out into their own functions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read this TODO item. Once addressed, remove it.

fn remove_dir_contents<P: AsRef<Path>>(path: P, seg_file: PathBuf) -> io::Result<()> {
trace!(">>> remove_Segment_contents");
for entry in fs::read_dir(path)? {
trace!("Delete Segment File at {:?}", entry);
fs::remove_file(entry?.path())?;
Expand All @@ -295,33 +344,3 @@ fn remove_dir_catalogs(path: PathBuf, file: PathBuf) -> io::Result<()> {
}
Ok(())
}

// fn remove_dir_segements<P: AsRef<Path>>(path: P, seg_file: PathBuf) -> io::Result<()> {
// trace!(">>> remove_Segment_contents");
// for entry in fs::read_dir(path)? {
// let entry = entry?;
// trace!("ENTRY Delete SEGMENT File at {:?}", entry);

// match &entry {
// seg_file => {
// fs::remove_file(seg_file.path())?;
// trace!("Delete Segment File at {:?}", seg_file);
// }
// }
// }
// Ok(())
// }

// fn remove_dir_catalogs(path: PathBuf, file: PathBuf) -> io::Result<()> {
// for entry in fs::read_dir(path)? {
// let entry = entry?;
// trace!("ENTRY Delete CATALOG File at {:?}", entry);
// match &entry {
// file => {
// fs::remove_file(file.path())?;
// trace!("FILE MATCH Delete CATALOG File at {:?}", file);
// }
// }
// }
// Ok(())
// }
cryptoquick marked this conversation as resolved.
Show resolved Hide resolved
18 changes: 15 additions & 3 deletions src/frontend/http.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::{net::SocketAddr, str::FromStr};
use std::{net::SocketAddr, str::FromStr, sync::RwLock};

use anyhow::Result;
use axum::{
body::StreamBody,
extract::{BodyStream, Path},
extract::{BodyStream, Path, Query},
http::StatusCode,
response::{IntoResponse, Response},
routing::{delete, get, post},
Expand All @@ -13,10 +13,11 @@ use bytes::BytesMut;
use futures_util::{stream, StreamExt};
use log::{debug, info, trace};
use secp256k1::PublicKey;
use serde::Deserialize;
use tower_http::cors::CorsLayer;

use crate::{
backend::fs::{delete_file, read_file, write_file, FileStream},
backend::fs::{delete_file, read_file, read_slices, write_file, FileStream},
config::{node_shared_secret, SYS_CFG},
prelude::*,
};
Expand Down Expand Up @@ -58,6 +59,15 @@ async fn post_file(
Ok((StatusCode::OK, hash.to_hex().to_string()))
}

/* TODO: This seems unnecessary, and could introduce concurrency and security issues
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see this TODO. Once addressed, remove it.

#[axum_macros::debug_handler]
async fn get_last_hash(Path(_pk): Path<String>) -> Result<impl IntoResponse, AppError> {
let hash1 = LOCK.read().unwrap();
let string_hash1 = hash1.clone();

Ok((StatusCode::OK, string_hash1))
} */

#[axum_macros::debug_handler]
async fn get_file(
Path((pk, blake3_hash)): Path<(String, String)>,
Expand Down Expand Up @@ -91,7 +101,9 @@ pub async fn start() -> Result<()> {
let app = Router::new()
.route("/remove/:pk/:blake3_hash", delete(remove_file))
.route("/store/:pk", post(post_file))
// .route("/last_hash/:pk", get(get_last_hash))
.route("/retrieve/:pk/:blake3_hash", get(get_file))
// .route("/slice/", get(get_slice))
.route("/key/:pk", get(key))
// .route("/catalog/:blake3_hash", get(get_catalog))
// .route("/raw/:bao_hash", get(get_raw))
Expand Down
10 changes: 10 additions & 0 deletions src/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ impl fmt::Display for Blake3Hash {
}
}

impl TryFrom<&[u8]> for Blake3Hash {
type Error = Error;

fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
let mut hash = [0_u8; 32];
hash.copy_from_slice(&value[0..32]);
Ok(Self(blake3::Hash::try_from(hash)?))
}
}

pub struct BaoHash(pub bao::Hash);

impl BaoHash {
Expand Down
42 changes: 4 additions & 38 deletions tests/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,40 +72,6 @@ async fn write_read() -> Result<()> {
Ok(())
}

#[tokio::test]
async fn check_catalog_exists() -> Result<()> {
carbonado::utils::init_logging(RUST_LOG);

let (_sk, pk) = generate_keypair(&mut thread_rng());

info!("Reading file bytes");
let file_bytes = fs::read("tests/samples/cat.gif")?;
debug!("{} bytes read", file_bytes.len());

let file_stream = stream::iter(file_bytes)
.chunks(1024 * 1024)
.map(|chunk| Ok(Bytes::from(chunk)))
.boxed();

info!("Writing file if not exists");
let is_ok = write_file(&Secp256k1PubKey(pk), file_stream).await.is_ok();
debug!("Skip writing file as File hash exists: {is_ok}");
assert!(is_ok);

let file_bytes = fs::read("tests/samples/cat.gif")?;
let file_stream = stream::iter(file_bytes)
.chunks(1024 * 1024)
.map(|chunk| Ok(Bytes::from(chunk)))
.boxed();

info!("Writing file if not exists");
let is_err = write_file(&Secp256k1PubKey(pk), file_stream).await.is_err();
debug!("Skip writing file as File hash exists: {is_err}");
assert!(is_err);

Ok(())
}

#[tokio::test]
async fn read_write_delete_file() -> Result<()> {
carbonado::utils::init_logging(RUST_LOG);
Expand All @@ -114,8 +80,8 @@ async fn read_write_delete_file() -> Result<()> {
let file_bytes = fs::read("tests/samples/cat.gif")?;
debug!("{} Write Delete:: bytes read", file_bytes.len());

let file_stream = stream::iter(file_bytes.clone())
.chunks(1024 * 1024)
let file_stream: FileStream = stream::iter(file_bytes.clone())
.chunks(SEGMENT_SIZE)
.map(|chunk| Ok(Bytes::from(chunk)))
.boxed();

Expand All @@ -135,8 +101,8 @@ async fn read_write_delete_file() -> Result<()> {
// second file to write
let (_sk, pk) = generate_keypair(&mut thread_rng());

let file_stream = stream::iter(file_bytes)
.chunks(1024 * 1024)
let file_stream: FileStream = stream::iter(file_bytes)
.chunks(SEGMENT_SIZE)
.map(|chunk| Ok(Bytes::from(chunk)))
.boxed();

Expand Down