use std::time::Instant;
use crate::Client;
use crate::chunk::{ChunkAddress, DataMapChunk};
use crate::client::payment::PaymentOption;
use crate::client::quote::CostError;
use crate::client::{GetError, PutError};
use crate::data::DataStream;
use crate::self_encryption::encrypt;
use ant_evm::{Amount, AttoTokens};
use ant_protocol::storage::DataTypes;
use bytes::Bytes;
use xor_name::XorName;
use super::DataAddress;
impl Client {
pub async fn data_get_public(&self, addr: &DataAddress) -> Result<Bytes, GetError> {
info!("Fetching public data from Data Address: {addr:?}");
let datamap_chunk =
DataMapChunk(self.chunk_get(&ChunkAddress::new(*addr.xorname())).await?);
self.data_get(&datamap_chunk).await
}
pub async fn data_stream_public(&self, addr: &DataAddress) -> Result<DataStream, GetError> {
info!("Starting streaming fetch of public data from Data Address: {addr:?}");
let datamap_chunk =
DataMapChunk(self.chunk_get(&ChunkAddress::new(*addr.xorname())).await?);
let stream = self.data_stream(&datamap_chunk).await?;
Ok(stream)
}
pub async fn data_put_public(
&self,
data: Bytes,
payment_option: PaymentOption,
) -> Result<(AttoTokens, DataAddress), PutError> {
let (total_cost, data_map_chunk) =
self.data_put_internal(data, payment_option, true).await?;
let data_address = DataAddress::new(*data_map_chunk.0.address().xorname());
Ok((total_cost, data_address))
}
pub async fn data_cost(&self, data: Bytes) -> Result<AttoTokens, CostError> {
let content_addrs = self.get_content_addrs(data)?;
self.get_cost_estimation(content_addrs).await
}
pub(crate) fn get_content_addrs(
&self,
data: Bytes,
) -> Result<Vec<(XorName, usize)>, CostError> {
let now = Instant::now();
let (data_map_chunk, chunks) = encrypt(data)?;
debug!("Encryption took: {:.2?}", now.elapsed());
let map_xor_name = *data_map_chunk.address().xorname();
let mut content_addrs = vec![(map_xor_name, data_map_chunk.size())];
for chunk in &chunks {
content_addrs.push((*chunk.name(), chunk.size()));
}
info!(
"Calculating cost of storing {} chunks. Datamap chunk at: {map_xor_name:?}",
content_addrs.len()
);
Ok(content_addrs)
}
pub async fn get_cost_estimation(
&self,
content_addrs: Vec<(XorName, usize)>,
) -> Result<AttoTokens, CostError> {
let store_quote = self
.get_store_quotes(DataTypes::Chunk, content_addrs.into_iter())
.await
.inspect_err(|err| error!("Error getting store quotes: {err:?}"))?;
let total_cost = AttoTokens::from_atto(
store_quote
.0
.values()
.map(|quote| quote.price())
.sum::<Amount>(),
);
Ok(total_cost)
}
}