Skip to content

Commit

Permalink
refactor(autonomi): use archive_public instead of _private
Browse files Browse the repository at this point in the history
  • Loading branch information
b-zee committed Dec 6, 2024
1 parent f8c4251 commit dd3a71e
Show file tree
Hide file tree
Showing 11 changed files with 588 additions and 588 deletions.
157 changes: 42 additions & 115 deletions autonomi/src/client/files/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,66 +13,29 @@ use std::{

use ant_networking::target_arch::{Duration, SystemTime, UNIX_EPOCH};

use ant_evm::{AttoTokens, EvmWallet};
use bytes::Bytes;
use serde::{Deserialize, Serialize};
use xor_name::XorName;

/// The address of an archive on the network. Points to an [`Archive`].
pub type ArchiveAddr = XorName;

use thiserror::Error;

use super::archive_public::{Metadata, RenameError};
use crate::{
client::data::{CostError, DataAddr, GetError, PutError},
client::{
data::{GetError, PrivateDataAccess, PutError},
payment::PaymentOption,
},
Client,
};
use bytes::Bytes;
use serde::{Deserialize, Serialize};

#[derive(Error, Debug, PartialEq, Eq)]
pub enum RenameError {
#[error("File not found in archive: {0}")]
FileNotFound(PathBuf),
}
/// The address of a private archive
/// Contains the [`PrivateDataAccess`] leading to the [`PrivateArchive`] data
pub type PrivateArchiveAccess = PrivateDataAccess;

/// An archive of files that containing file paths, their metadata and the files data addresses
/// A private archive of files that containing file paths, their metadata and the files data maps
/// Using archives is useful for uploading entire directories to the network, only needing to keep track of a single address.
/// Archives are public meaning anyone can read the data in the archive. For private archives use [`crate::client::archive_private::PrivateArchive`].
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct Archive {
map: HashMap<PathBuf, (DataAddr, Metadata)>,
}

/// Metadata for a file in an archive. Time values are UNIX timestamps.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Metadata {
/// When the file was (last) uploaded to the network.
pub uploaded: u64,
/// File creation time on local file system. See [`std::fs::Metadata::created`] for details per OS.
pub created: u64,
/// Last file modification time taken from local file system. See [`std::fs::Metadata::modified`] for details per OS.
pub modified: u64,
/// File size in bytes
pub size: u64,
}

impl Metadata {
/// Create a new metadata struct with the current time as uploaded, created and modified.
pub fn new_with_size(size: u64) -> Self {
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or(Duration::from_secs(0))
.as_secs();

Self {
uploaded: now,
created: now,
modified: now,
size,
}
}
pub struct PrivateArchive {
map: HashMap<PathBuf, (PrivateDataAccess, Metadata)>,
}

impl Archive {
impl PrivateArchive {
/// Create a new emtpy local archive
/// Note that this does not upload the archive to the network
pub fn new() -> Self {
Expand All @@ -94,14 +57,14 @@ impl Archive {
.as_secs();
meta.modified = now;
self.map.insert(new_path.to_path_buf(), (data_addr, meta));
debug!("Renamed file successfully in the archive, old path: {old_path:?} new_path: {new_path:?}");
debug!("Renamed file successfully in the private archive, old path: {old_path:?} new_path: {new_path:?}");
Ok(())
}

/// Add a file to a local archive
/// Note that this does not upload the archive to the network
pub fn add_file(&mut self, path: PathBuf, data_addr: DataAddr, meta: Metadata) {
self.map.insert(path.clone(), (data_addr, meta));
pub fn add_file(&mut self, path: PathBuf, data_map: PrivateDataAccess, meta: Metadata) {
self.map.insert(path.clone(), (data_map, meta));
debug!("Added a new file to the archive, path: {:?}", path);
}

Expand All @@ -114,26 +77,29 @@ impl Archive {
}

/// List all data addresses of the files in the archive
pub fn addresses(&self) -> Vec<DataAddr> {
self.map.values().map(|(addr, _)| *addr).collect()
pub fn addresses(&self) -> Vec<PrivateDataAccess> {
self.map
.values()
.map(|(data_map, _)| data_map.clone())
.collect()
}

/// Iterate over the archive items
/// Returns an iterator over (PathBuf, DataAddr, Metadata)
pub fn iter(&self) -> impl Iterator<Item = (&PathBuf, &DataAddr, &Metadata)> {
/// Returns an iterator over (PathBuf, SecretDataMap, Metadata)
pub fn iter(&self) -> impl Iterator<Item = (&PathBuf, &PrivateDataAccess, &Metadata)> {
self.map
.iter()
.map(|(path, (addr, meta))| (path, addr, meta))
.map(|(path, (data_map, meta))| (path, data_map, meta))
}

/// Get the underlying map
pub fn map(&self) -> &HashMap<PathBuf, (DataAddr, Metadata)> {
pub fn map(&self) -> &HashMap<PathBuf, (PrivateDataAccess, Metadata)> {
&self.map
}

/// Deserialize from bytes.
pub fn from_bytes(data: Bytes) -> Result<Archive, rmp_serde::decode::Error> {
let root: Archive = rmp_serde::from_slice(&data[..])?;
pub fn from_bytes(data: Bytes) -> Result<PrivateArchive, rmp_serde::decode::Error> {
let root: PrivateArchive = rmp_serde::from_slice(&data[..])?;

Ok(root)
}
Expand All @@ -148,65 +114,26 @@ impl Archive {
}

impl Client {
/// Fetch an archive from the network
///
/// # Example
///
/// ```no_run
/// # use autonomi::client::{Client, archive::ArchiveAddr};
/// # #[tokio::main]
/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # let peers = ["/ip4/127.0.0.1/udp/1234/quic-v1".parse()?];
/// let client = Client::connect(&peers).await?;
/// let archive = client.archive_get_public(ArchiveAddr::random(&mut rand::thread_rng())).await?;
/// # Ok(())
/// # }
/// ```
pub async fn archive_get_public(&self, addr: ArchiveAddr) -> Result<Archive, GetError> {
let data = self.data_get_public(addr).await?;
Ok(Archive::from_bytes(data)?)
/// Fetch a private archive from the network
pub async fn archive_get(
&self,
addr: PrivateArchiveAccess,
) -> Result<PrivateArchive, GetError> {
let data = self.data_get(addr).await?;
Ok(PrivateArchive::from_bytes(data)?)
}

/// Upload an archive to the network
///
/// # Example
///
/// Create simple archive containing `file.txt` pointing to random XOR name.
///
/// ```no_run
/// # use autonomi::client::{Client, data::DataAddr, archive::{Archive, ArchiveAddr, Metadata}};
/// # use std::path::PathBuf;
/// # #[tokio::main]
/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # let peers = ["/ip4/127.0.0.1/udp/1234/quic-v1".parse()?];
/// # let client = Client::connect(&peers).await?;
/// # let wallet = todo!();
/// let mut archive = Archive::new();
/// archive.add_file(PathBuf::from("file.txt"), DataAddr::random(&mut rand::thread_rng()), Metadata::new_with_size(0));
/// let address = client.archive_put_public(archive, &wallet).await?;
/// # Ok(())
/// # }
/// ```
pub async fn archive_put_public(
/// Upload a private archive to the network
pub async fn archive_put(
&self,
archive: Archive,
wallet: &EvmWallet,
) -> Result<ArchiveAddr, PutError> {
archive: PrivateArchive,
payment_option: PaymentOption,
) -> Result<PrivateArchiveAccess, PutError> {
let bytes = archive
.into_bytes()
.map_err(|e| PutError::Serialization(format!("Failed to serialize archive: {e:?}")))?;
let result = self.data_put_public(bytes, wallet.into()).await;
debug!("Uploaded archive {archive:?} to the network and the address is {result:?}");
result
}

/// Get the cost to upload an archive
pub async fn archive_cost(&self, archive: Archive) -> Result<AttoTokens, CostError> {
let bytes = archive
.into_bytes()
.map_err(|e| CostError::Serialization(format!("Failed to serialize archive: {e:?}")))?;
let result = self.data_cost(bytes).await;
debug!("Calculated the cost to upload archive {archive:?} is {result:?}");
let result = self.data_put(bytes, payment_option).await;
debug!("Uploaded private archive {archive:?} to the network and address is {result:?}");
result
}
}
139 changes: 0 additions & 139 deletions autonomi/src/client/files/archive_private.rs

This file was deleted.

Loading

0 comments on commit dd3a71e

Please sign in to comment.