From c995d16b235f4eae482b62d154223738172d5399 Mon Sep 17 00:00:00 2001 From: Benno Zeeman Date: Tue, 7 Jan 2025 16:46:18 +0100 Subject: [PATCH] feat(ant-cli): report already paid for records --- ant-cli/src/commands/file.rs | 4 ++++ ant-cli/src/utils.rs | 4 ++++ autonomi/src/client/data/mod.rs | 5 +++-- autonomi/src/client/data/public.rs | 5 +++-- autonomi/src/client/files/archive.rs | 7 +++++++ autonomi/src/client/files/archive_public.rs | 7 +++++++ autonomi/src/client/graph.rs | 5 +++-- autonomi/src/client/mod.rs | 4 ++++ autonomi/src/client/payment.rs | 10 ++++++---- autonomi/src/client/pointer.rs | 2 +- autonomi/src/client/registers.rs | 9 +++++---- autonomi/src/client/utils.rs | 6 ++++-- autonomi/src/client/vault.rs | 2 +- 13 files changed, 52 insertions(+), 18 deletions(-) diff --git a/ant-cli/src/commands/file.rs b/ant-cli/src/commands/file.rs index 146133e348..8db5acf5ab 100644 --- a/ant-cli/src/commands/file.rs +++ b/ant-cli/src/commands/file.rs @@ -83,6 +83,10 @@ pub async fn upload(file: &str, public: bool, peers: Vec) -> Result<( println!("At address: {local_addr}"); info!("Successfully uploaded: {file} at address: {local_addr}"); println!("Number of chunks uploaded: {}", summary.record_count); + println!( + "Number of chunks already paid/uploaded: {}", + summary.records_already_paid + ); println!("Total cost: {} AttoTokens", summary.tokens_spent); } info!("Summary for upload of file {file} at {local_addr:?}: {summary:?}"); diff --git a/ant-cli/src/utils.rs b/ant-cli/src/utils.rs index 5f031a3c24..81b1d1e36f 100644 --- a/ant-cli/src/utils.rs +++ b/ant-cli/src/utils.rs @@ -20,6 +20,7 @@ pub fn collect_upload_summary( let stats_thread = tokio::spawn(async move { let mut tokens_spent: Amount = Amount::from(0); let mut record_count = 0; + let mut records_already_paid = 0; loop { tokio::select! { @@ -28,6 +29,7 @@ pub fn collect_upload_summary( Some(ClientEvent::UploadComplete(upload_summary)) => { tokens_spent += upload_summary.tokens_spent; record_count += upload_summary.record_count; + records_already_paid += upload_summary.records_already_paid; } None => break, } @@ -42,6 +44,7 @@ pub fn collect_upload_summary( ClientEvent::UploadComplete(upload_summary) => { tokens_spent += upload_summary.tokens_spent; record_count += upload_summary.record_count; + records_already_paid += upload_summary.records_already_paid; } } } @@ -49,6 +52,7 @@ pub fn collect_upload_summary( UploadSummary { tokens_spent, record_count, + records_already_paid, } }); diff --git a/autonomi/src/client/data/mod.rs b/autonomi/src/client/data/mod.rs index d336c60dfc..5efa9c9807 100644 --- a/autonomi/src/client/data/mod.rs +++ b/autonomi/src/client/data/mod.rs @@ -222,7 +222,7 @@ impl Client { // Pay for all chunks let xor_names: Vec<_> = chunks.iter().map(|chunk| *chunk.name()).collect(); info!("Paying for {} addresses", xor_names.len()); - let receipt = self + let (receipt, skipped_payments) = self .pay_for_content_addrs(xor_names.into_iter(), payment_option) .await .inspect_err(|err| error!("Error paying for data: {err:?}"))?; @@ -244,7 +244,7 @@ impl Client { return Err(last_chunk_fail.1); } - let record_count = chunks.len(); + let record_count = chunks.len() - skipped_payments; // Reporting if let Some(channel) = self.client_event_sender.as_ref() { @@ -255,6 +255,7 @@ impl Client { let summary = UploadSummary { record_count, + records_already_paid: skipped_payments, tokens_spent, }; if let Err(err) = channel.send(ClientEvent::UploadComplete(summary)).await { diff --git a/autonomi/src/client/data/public.rs b/autonomi/src/client/data/public.rs index eff9f99f89..0d82e4f08b 100644 --- a/autonomi/src/client/data/public.rs +++ b/autonomi/src/client/data/public.rs @@ -59,7 +59,7 @@ impl Client { // Pay for all chunks + data map chunk info!("Paying for {} addresses", xor_names.len()); - let receipt = self + let (receipt, skipped_payments) = self .pay_for_content_addrs(xor_names.into_iter(), payment_option) .await .inspect_err(|err| error!("Error paying for data: {err:?}"))?; @@ -87,7 +87,7 @@ impl Client { return Err(last_chunk_fail.1); } - let record_count = chunks.len() + 1; + let record_count = (chunks.len() + 1) - skipped_payments; // Reporting if let Some(channel) = self.client_event_sender.as_ref() { @@ -98,6 +98,7 @@ impl Client { let summary = UploadSummary { record_count, + records_already_paid: skipped_payments, tokens_spent, }; if let Err(err) = channel.send(ClientEvent::UploadComplete(summary)).await { diff --git a/autonomi/src/client/files/archive.rs b/autonomi/src/client/files/archive.rs index 03a82d423a..8aa59f6539 100644 --- a/autonomi/src/client/files/archive.rs +++ b/autonomi/src/client/files/archive.rs @@ -169,6 +169,13 @@ impl Client { let bytes = archive .to_bytes() .map_err(|e| PutError::Serialization(format!("Failed to serialize archive: {e:?}")))?; + + #[cfg(feature = "loud")] + println!( + "Uploading private archive referencing {} files", + archive.map().len() + ); + let result = self.data_put(bytes, payment_option).await; debug!("Uploaded private archive {archive:?} to the network and address is {result:?}"); result diff --git a/autonomi/src/client/files/archive_public.rs b/autonomi/src/client/files/archive_public.rs index 19f1756b8b..47ffec7e1c 100644 --- a/autonomi/src/client/files/archive_public.rs +++ b/autonomi/src/client/files/archive_public.rs @@ -158,6 +158,13 @@ impl Client { let bytes = archive .to_bytes() .map_err(|e| PutError::Serialization(format!("Failed to serialize archive: {e:?}")))?; + + #[cfg(feature = "loud")] + println!( + "Uploading public archive referencing {} files", + archive.map().len() + ); + let result = self.data_put_public(bytes, wallet.into()).await; debug!("Uploaded archive {archive:?} to the network and the address is {result:?}"); result diff --git a/autonomi/src/client/graph.rs b/autonomi/src/client/graph.rs index 71749b3289..07cc900d60 100644 --- a/autonomi/src/client/graph.rs +++ b/autonomi/src/client/graph.rs @@ -68,7 +68,7 @@ impl Client { // pay for the transaction let xor_name = address.xorname(); debug!("Paying for transaction at address: {address:?}"); - let payment_proofs = self + let (payment_proofs, skipped_payments) = self .pay(std::iter::once(*xor_name), wallet) .await .inspect_err(|err| { @@ -121,7 +121,8 @@ impl Client { // send client event if let Some(channel) = self.client_event_sender.as_ref() { let summary = UploadSummary { - record_count: 1, + record_count: 1usize.saturating_sub(skipped_payments), + records_already_paid: skipped_payments, tokens_spent: price.as_atto(), }; if let Err(err) = channel.send(ClientEvent::UploadComplete(summary)).await { diff --git a/autonomi/src/client/mod.rs b/autonomi/src/client/mod.rs index b6ddcfbbb9..750eccfdbb 100644 --- a/autonomi/src/client/mod.rs +++ b/autonomi/src/client/mod.rs @@ -367,6 +367,10 @@ pub enum ClientEvent { /// Summary of an upload operation. #[derive(Debug, Clone)] pub struct UploadSummary { + /// Records that were uploaded to the network pub record_count: usize, + /// Records that were already paid for so were not re-uploaded + pub records_already_paid: usize, + /// Total cost of the upload pub tokens_spent: Amount, } diff --git a/autonomi/src/client/payment.rs b/autonomi/src/client/payment.rs index 29a8f11576..b6dc4c936e 100644 --- a/autonomi/src/client/payment.rs +++ b/autonomi/src/client/payment.rs @@ -5,6 +5,8 @@ use ant_evm::{AttoTokens, EncodedPeerId, EvmWallet, ProofOfPayment}; use std::collections::HashMap; use xor_name::XorName; +use super::utils::AlreadyPaidAddressesCount; + /// Contains the proof of payments for each XOR address and the amount paid pub type Receipt = HashMap; @@ -65,13 +67,13 @@ impl Client { &self, content_addrs: impl Iterator + Clone, payment_option: PaymentOption, - ) -> Result { + ) -> Result<(Receipt, AlreadyPaidAddressesCount), PayError> { match payment_option { PaymentOption::Wallet(wallet) => { - let receipt = self.pay(content_addrs, &wallet).await?; - Ok(receipt) + let (receipt, skipped) = self.pay(content_addrs, &wallet).await?; + Ok((receipt, skipped)) } - PaymentOption::Receipt(receipt) => Ok(receipt), + PaymentOption::Receipt(receipt) => Ok((receipt, 0)), } } } diff --git a/autonomi/src/client/pointer.rs b/autonomi/src/client/pointer.rs index dd759209f5..5e820cf6a2 100644 --- a/autonomi/src/client/pointer.rs +++ b/autonomi/src/client/pointer.rs @@ -60,7 +60,7 @@ impl Client { // pay for the pointer storage let xor_name = *address.xorname(); debug!("Paying for pointer at address: {address:?}"); - let payment_proofs = self + let (payment_proofs, _skipped_payments) = self .pay(std::iter::once(xor_name), wallet) .await .inspect_err(|err| { diff --git a/autonomi/src/client/registers.rs b/autonomi/src/client/registers.rs index dc56e37b45..ad4bf67197 100644 --- a/autonomi/src/client/registers.rs +++ b/autonomi/src/client/registers.rs @@ -316,12 +316,12 @@ impl Client { let reg_xor = address.xorname(); debug!("Paying for register at address: {address}"); - let payment_proofs = self + let (payment_proofs, skipped_payments) = self .pay(std::iter::once(reg_xor), wallet) .await .inspect_err(|err| { - error!("Failed to pay for register at address: {address} : {err}") - })?; + error!("Failed to pay for register at address: {address} : {err}") + })?; let (proof, price) = if let Some((proof, price)) = payment_proofs.get(®_xor) { (proof, price) } else { @@ -370,7 +370,8 @@ impl Client { if let Some(channel) = self.client_event_sender.as_ref() { let summary = UploadSummary { - record_count: 1, + record_count: 1usize.saturating_sub(skipped_payments), + records_already_paid: skipped_payments, tokens_spent: price.as_atto(), }; if let Err(err) = channel.send(ClientEvent::UploadComplete(summary)).await { diff --git a/autonomi/src/client/utils.rs b/autonomi/src/client/utils.rs index ad2aeececb..e86600146d 100644 --- a/autonomi/src/client/utils.rs +++ b/autonomi/src/client/utils.rs @@ -27,6 +27,8 @@ use super::{ }; use crate::self_encryption::DataMapLevel; +pub type AlreadyPaidAddressesCount = usize; + impl Client { /// Fetch and decrypt all chunks in the data map. pub(crate) async fn fetch_from_data_map(&self, data_map: &DataMap) -> Result { @@ -164,7 +166,7 @@ impl Client { &self, content_addrs: impl Iterator + Clone, wallet: &EvmWallet, - ) -> Result { + ) -> Result<(Receipt, AlreadyPaidAddressesCount), PayError> { let number_of_content_addrs = content_addrs.clone().count(); let quotes = self.get_store_quotes(content_addrs).await?; @@ -194,7 +196,7 @@ impl Client { let receipt = receipt_from_store_quotes(quotes); - Ok(receipt) + Ok((receipt, skipped_chunks)) } } diff --git a/autonomi/src/client/vault.rs b/autonomi/src/client/vault.rs index 462e2a4cb0..d9543e8347 100644 --- a/autonomi/src/client/vault.rs +++ b/autonomi/src/client/vault.rs @@ -192,7 +192,7 @@ impl Client { info!("Writing to vault at {scratch_address:?}",); let record = if is_new { - let receipt = self + let (receipt, _skipped_payments) = self .pay_for_content_addrs(std::iter::once(scratch.xorname()), payment_option) .await .inspect_err(|err| {