Skip to content

Commit

Permalink
feat!(protocol): gets keys with GetStoreCost
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuef authored and RolandSherwin committed Aug 30, 2023
1 parent f670c09 commit 9a9cb25
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 27 deletions.
7 changes: 3 additions & 4 deletions sn_client/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,11 +402,10 @@ impl Client {
pub async fn get_store_cost_at_address(&self, address: &NetworkAddress) -> Result<Token> {
trace!("Getting store cost at {address:?}");

let cost = self
let costs = self
.network
.get_store_cost_from_network(address.clone())
.await?
.as_nano();
.get_store_costs_from_network(address.clone())
.await?;

trace!("Store cost at address {address:?} is: {cost:?}");

Expand Down
3 changes: 3 additions & 0 deletions sn_networking/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use super::{cmd::SwarmCmd, NetworkEvent};

use libp2p::{
identity::DecodingError,
kad::{self, Record},
request_response::{OutboundFailure, RequestId},
swarm::DialError,
Expand Down Expand Up @@ -64,6 +65,8 @@ pub enum Error {

#[error("Dial Error")]
DialError(#[from] DialError),
#[error("Libp2p Idendity Decode Error")]
LIbp2pDecode(#[from] DecodingError),

#[error("This peer is already being dialed: {0}")]
AlreadyDialingPeer(libp2p::PeerId),
Expand Down
43 changes: 29 additions & 14 deletions sn_networking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use libp2p::core::muxing::StreamMuxerBox;
#[cfg(feature = "local-discovery")]
use libp2p::mdns;
use libp2p::{
identity::Keypair,
identity::{Keypair, PublicKey},
kad::{KBucketKey, Kademlia, KademliaConfig, QueryId, Record, RecordKey},
multiaddr::Protocol,
request_response::{self, Config as RequestResponseConfig, ProtocolSupport, RequestId},
Expand Down Expand Up @@ -644,10 +644,10 @@ impl Network {
.await)
}

pub async fn get_store_cost_from_network(
pub async fn get_store_costs_from_network(
&self,
record_address: NetworkAddress,
) -> Result<Token> {
) -> Result<Vec<(PublicKey, Token)>> {
let (sender, receiver) = oneshot::channel();
debug!("Attempting to get store cost");
// first we need to get CLOSE_GROUP of the dbc_id
Expand All @@ -670,14 +670,20 @@ impl Network {
// loop over responses, generating an avergae fee and storing all responses along side
let mut all_costs = vec![];
for response in responses.into_iter().flatten() {
if let Response::Query(QueryResponse::GetStoreCost(Ok(cost))) = response {
all_costs.push(cost);
if let Response::Query(QueryResponse::GetStoreCost {
store_cost: Ok(cost),
pk_bytes,
}) = response
{
// TODO: handle this error
let pk = PublicKey::try_decode_protobuf(&pk_bytes)?;
all_costs.push((pk, cost));
} else {
println!("other response was {:?}", response);
}
}

get_fee_from_store_cost_quotes(&mut all_costs)
get_fee_from_store_cost_quotes(all_costs)
}

/// Get the Record from the network
Expand Down Expand Up @@ -1007,22 +1013,31 @@ impl Network {
}

/// Given `all_costs` it will return the CLOSE_GROUP majority cost.
fn get_fee_from_store_cost_quotes(all_costs: &mut Vec<Token>) -> Result<Token> {
fn get_fee_from_store_cost_quotes(
mut all_costs: Vec<(PublicKey, Token)>,
) -> Result<Vec<(PublicKey, Token)>> {
// we're zero indexed, so we want the middle index
let target_cost_index = CLOSE_GROUP_SIZE / 2;
let desired_quote_count = (CLOSE_GROUP_SIZE / 2) + 1;

// sort all costs by fee, lowest to highest
all_costs.sort();
all_costs.sort_by(|(_, cost_a), (_, cost_b)| {
cost_a
.partial_cmp(cost_b)
.unwrap_or(std::cmp::Ordering::Equal)
});

let token_fee = *all_costs
.get(target_cost_index)
.ok_or(Error::NotEnoughCostQuotes)?;
// get the first desired_quote_count of all_costs
all_costs.truncate(desired_quote_count);

if all_costs.len() < desired_quote_count {
return Err(Error::NotEnoughCostQuotes);
}

info!(
"Final fee calculated as: {token_fee:?}, from: {:?}",
"Final fees calculated as: {all_costs:?}, from: {:?}",
all_costs
);
Ok(token_fee)
Ok(all_costs)
}

/// Verifies if `Multiaddr` contains IPv4 address that is not global.
Expand Down
10 changes: 8 additions & 2 deletions sn_node/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ impl Node {
local: bool,
root_dir: PathBuf,
) -> Result<RunningNode> {
let reward_main_key = keypair.public();
let (network, mut network_event_receiver, swarm_driver) =
SwarmDriver::new(keypair, addr, local, root_dir)?;
let node_events_channel = NodeEventsChannel::default();
Expand All @@ -91,6 +92,7 @@ impl Node {
network: network.clone(),
events_channel: node_events_channel.clone(),
initial_peers,
reward_main_key,
};

let network_clone = network.clone();
Expand Down Expand Up @@ -296,8 +298,12 @@ impl Node {
let resp: QueryResponse = match query {
Query::GetStoreCost(_address) => {
trace!("Got GetStoreCost");
let result = self.current_storecost().await;
QueryResponse::GetStoreCost(result)
let pk = self.reward_main_key.encode_protobuf();
let store_cost = self.current_storecost().await;
QueryResponse::GetStoreCost {
store_cost,
pk_bytes: pk,
}
}
Query::GetReplicatedData {
requester: _,
Expand Down
3 changes: 2 additions & 1 deletion sn_node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub use self::{
log_markers::Marker,
};

use libp2p::Multiaddr;
use libp2p::{identity::PublicKey, Multiaddr};
use sn_networking::Network;

/// `Node` represents a single node in the distributed network. It handles
Expand All @@ -70,4 +70,5 @@ pub struct Node {
events_channel: NodeEventsChannel,
/// Peers that are dialed at startup of node.
initial_peers: Vec<Multiaddr>,
reward_main_key: PublicKey,
}
8 changes: 6 additions & 2 deletions sn_protocol/src/messages/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ use std::fmt::Debug;
#[allow(clippy::large_enum_variant)]
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, custom_debug::Debug)]
pub enum QueryResponse {
/// The store cost in nanos for storing the next record, and the node's singature over that cost.
GetStoreCost(Result<Token>),
GetStoreCost {
/// The store cost in nanos for storing the next record.
store_cost: Result<Token>,
/// The libp2p protobuf encoded PublicKey to pay this node's store cost to.
pk_bytes: Vec<u8>,
},
// ===== ReplicatedData =====
//
/// Response to [`GetReplicatedData`]
Expand Down
6 changes: 3 additions & 3 deletions sn_transfers/src/wallet/local_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,12 @@ impl LocalWallet {
/// Add given storage payment proofs to the wallet's cache,
/// so they can be used when uploading the paid content.
pub fn add_payment_proofs(&mut self, proofs: PaymentTransactionsMap) {
self.wallet.paymet_transactions.extend(proofs);
self.wallet.payment_transactions.extend(proofs);
}

/// Return the payment proof for the given content address name if cached.
pub fn get_payment_proof(&self, name: &NetworkAddress) -> Option<&Vec<DbcId>> {
self.wallet.paymet_transactions.get(name)
self.wallet.payment_transactions.get(name)
}

pub async fn local_send(
Expand Down Expand Up @@ -248,7 +248,7 @@ impl KeyLessWallet {
spent_dbcs: BTreeMap::new(),
available_dbcs: BTreeMap::new(),
dbcs_created_for_others: vec![],
paymet_transactions: PaymentTransactionsMap::default(),
payment_transactions: PaymentTransactionsMap::default(),
}
}

Expand Down
2 changes: 1 addition & 1 deletion sn_transfers/src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ pub(super) struct KeyLessWallet {
/// transfer history.
dbcs_created_for_others: Vec<Dbc>,
/// Cached proofs of storage transactions made to be used for uploading the paid content.
paymet_transactions: PaymentTransactionsMap,
payment_transactions: PaymentTransactionsMap,
}

/// Return the name of a PublicAddress.
Expand Down

0 comments on commit 9a9cb25

Please sign in to comment.